views:

70

answers:

3

Hi,

I am new to ASP.NET MVC, particularly ajax operations. I have a form with a jquery dialog for adding items to a drop-down list. This posts to the controller action.

If nothing (ie void method) is returned from the Controller Action the page returns having updated the database, but obviously there no chnage to the form. What would be the best practice in updating the drop down list with the added id/value and selecting the item. I think my options are:

1) Construct and return the html manually that makes up the new <select> tag [this would be easy enough and work, but seems like I am missing something]

2) Use some kind of "helper" to construct the new html [This seems to make sense]

3) Only return the id/value and add this to the list and select the item [This seems like an overkill considering the item needs to be placed in the correct order etc]

4) Use some kind of Partial View [Does this mean creating additional forms within ascx controls? not sure how this would effect submitting the main form its on? Also unless this is reusable by passing in parameters(not sure how thats done) maybe 2 is the option?]

UPDATE:

Having looked around a bit, it seems that generating html withing the controller is not a good idea. I have seen other posts that render partialviews to strings which I guess is what I need and separates concerns (since the html bits are in the ascx). Any comments on whether that is good practice.

+1  A: 

look at the ContentResult you can specify the mime type of what you return (text/html) You could alternatively make a control that take a IEnumerable of whatever you put in the selectlist, and build it using the view engine. That way you keep the formatting of the html (in this case a list of options) into a view, and not in your code.

<%@ Control Language="C#"Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<Article>>"%>

<%foreach (var article in Model){%>
    <option><%:article.Title %></option>
<%} %>

I think I would go for that second one

Stephane
+1  A: 

From what I understood, the jQuery dialog contains a form that, when submitted, will post to an action which updates the database with some information. You want to get the newly added database information and update the same form that was used to trigger the database update.

If that is the case, then I think the best clean and logical option is to return JSON serialization of the items to be put in the drop down right after you update the database. Then, using jQuery, you would clear the drop down and append option tags into it.

You can also write a new, seperate action that returns the JSON serialization of the database objects you need. You would have jQuery call another post to this action as a callback to your first ajax post (the one used to update the database).

Here is a quick snippet

public ActionResult UpdateDatabase(string something)
{
     /// update the database
     IEnumerable<Items> items = getItemsFromDatabase(); // or w/e
     var vals = items.Select(x=> new { value = x.ID, text = x.Name }); // something similar

      return Json(vals);
} 

Personally, I would write a separate function that returns JSON. This ensure separation of concerns, and gives me a function I can use in many different places.

Baddie
returning JSON is a much better option indeed :)
Stephane
A: 

Returning a JsonResult with all the items is the most versatile and least-bandwidth intensive solution as long as you are happy to iterate through the list in jQuery and update your drop-down list.

Using a partial view is nice for HTML that you can .load(...) directly into your select, but less versatile.

I would go with the JsonResult.

In your Controller:

public JsonResult UpdateItem(string sItem)
{
    // 1. Insert new item into database if not exist...
    // {update code here}

    // 2. retrieve items from database:
    IEnumerable<Item> Items = GetItems();

    // 3. return enumerable list in JSON format:
    return new JsonResult{ Data = new {Items = Items, Result = "OK" }};
}

On client-side:

Iterate through Items array and add the items to your list.

FreshCode
@Baddie you beat me to it :).
FreshCode