Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC partial page update

I have an MVC project where I have a form with fields a user can enter and save. On that same page I have a table which shows a brief listing of information that the user just saved. The problem I am having is trying to update only the table after a save and not an entire page refresh.

Is this possible in jquery or MVC? If so does anyone have an example.

Here is what the action in the controller looks like:

public ActionResult RefreshList()
    {
        string _employeeID = Request.QueryString["empIDSearch"];
        this.ViewData["coursehistorylist"] = _service.ListCoursesByEmpID(_employeeID);
        return View("CourseHistoryList");
    }

The function in the view: (and this is where I'm confused on how to update only the table)

$.ajax({
        url: "/Home/RefreshList",
        type: "POST",
        success: function(result) {
            alert("got here");
        },
        error: function(xhr, ajaxOptions, thrownError) {
            alert(xhr.status + " " + thrownError + " " + ajaxOptions);
        }
    });

Grabbing the ViewData from the controller:

<% foreach (var item in
  (IEnumerable<EdMVC.Models.tblEdCourse>)ViewData["coursehistorylist"])
 {
%> 

Thanks.

like image 278
GB. Avatar asked Dec 28 '22 21:12

GB.


2 Answers

Note: When I wrote this MVC was only at version 1, though mostly relevant now there are certain parts of this post which are not applicable to later versions of MVC.

This is a more in depth version of NickLarsen's answer, unfortunately I ran out of space in the comments so added it as an answer.

This should probably be a "GET" request, as you are not sending any data to the server in this request. jQuery will actually work this out for itself when you use the $.ajax request so you can leave it out as I have done below. When explicitly needing a "POST" action, be sure to make that distinction.

In the ajax call that you are making here, the result variable is the string returned from the server and can be viewed and applied as such. If you wish you can also turn this into a jQuery object and filter against it, but that is out of the scope of this question.

Your $.ajax code would need to be updated to the following:

$.ajax({
        url: '/Home/RefreshList',
        success: function(result) {
            alert('Received: ' + result);
            $('#myDivId').html(result);//This is the line you need
        },
        error: function(xhr, ajaxOptions, thrownError) {
            alert(xhr.status + " " + thrownError + " " + ajaxOptions);
        }
    });

The above code will insert the result into an element with the id "myDivId" if the server responds correctly.

That div would need to have the following id attribute, but content of the div and other attributes are irrelevant.

<div id="myDivId"></div>

The above examples will function completely by themselves, as long as the controller action your url is pointing to returns a value.

On a Completely Different Note...

The following is completely to make your life with MVC easier, even though it isn't really relevant to the question it wont fit in a comment and deserves to be mentioned.

To cut down on namespace declaration, add the namespace to your web.config file, under the <pages><namespaces> node, add the following: <add namespace="EdMVC.Models"/> You should also do this with any other namespaces which you need to access regularly, as this will allow you to access their objects easily from the view.

Also, in this case you should probably be sending the data to the view via the view's "model" value if at all possible, rather than the ViewData dictionary which you always need to cast back if used.

To do this change your return from:

this.ViewData["coursehistorylist"] = _service.ListCoursesByEmpID(_employeeID);
return View("CourseHistoryList");

to:

return View("CourseHistoryList", _service.ListCoursesByEmpID(_employeeID)) 

From here you need to create a strongly typed view, to do this replace the inherits attribute at the top of your view to:

Inherits="System.Web.Mvc.ViewPage<IEnumerable<tblEdCourse>>") 

With these steps taken you can now access it as a strongly typed object like so:

foreach(tblEdCourse item in Model) 
{ 
}

Or if it's a single object, simply <%= Model.Id %>

This should allow you to cut down on your casting and save you heaps of time in the long run, if any of the above doesn't make sense or is difficult to understand let me know and I will re-word it.

like image 68
Jay Avatar answered Dec 31 '22 12:12

Jay


The only step you are missing is to replace the existing table with the new data that is returned in the success function.

For a little more information, you should wrap the call to the partial view in the action view with a div that has an id. Then call the .html(newData) function on that div in your success method.

like image 45
Nick Larsen Avatar answered Dec 31 '22 10:12

Nick Larsen