tags:

views:

261

answers:

3

Hello,

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.

A: 

You can do this in web forms which it sounds like you are using by simply using an update panel.

However...

MVC is an ideal approach because it removes the tight coupling between the presentation layer of an web app and the actual code handling the user interaction. However if you are invested in a webforms solution, implementing jquery can still be done...

JQuery is a JavaScript library that lets you "query" the DOM of web pages to access different elements in that page. It also has handy functionality for doing asynchronous requests to the server.

In web forms you can build a webservice to save the user input and return a the new table row to do the partial update. You'll also need to learn about how to return JSON from the webservice to make it easy to handle in the JavaScript.

Below are some helpful Links:

Returning JSON from a .NET Web Service: http://blog.davebouwman.com/index.php/2008/09/posting-data-to-aspnet-json-services-with-dojo/

Consuming a .NET Web Service with JQuery: http://encosia.com/2008/03/27/using-jquery-to-consume-aspnet-json-web-services/

Achilles
I'm actually doing all this in MVC and not web forms. I should have been clearer in my original post. The form I'm referring to is just a collection of labels and text boxes the user can fill out and save.
GB
+2  A: 

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.

NickLarsen
Sorry, I'm pretty new to this. How would I do that with jquery?
GB
`var myTable = $('myDivId');` gets you a jquery handle to the div, then you call `myTable.html(newData);`.
NickLarsen
Thanks for the quick response, and how would I 'wrap the call to the partial view in the action view with a div that has an id'?
GB
Can you include the view code as well (not the partial view, but the action view) and I will be able to help you.
NickLarsen
+1 For this answer, also slight typo in your comment (should be $('#myDivId'); as it's filtering on id)
Jay
Ohh you're right @Jay, good catch.
NickLarsen
+2  A: 

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 a 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.

Jay