Html.DropDownListFor confusion

廉价感情. 提交于 2019-12-02 15:40:41

问题


Can someone please help me understand how the Html.DropDownListFor works? I have a model which is as follows

public class TestModel
{
    public IList<SelectListItem> ProductNames { get; set; }
    public string Product { get; set; }
}

The call to DropDownListFor which looks like

@Html.DropDownListFor(model => model.ProductNames,  Model.ProductNames, "Select a Product", new {@class="selectproductname" })

With this set up I find that the drop down list gets populated correctly however after submitting the form I can't seem to get the selected item. Also from what I've read the call to Html.DropDownListFor should actually look like

@Html.DropDownListFor(model => model.Product,  Model.ProductNames, "Select a Product", new {@class="selectproductname" })

In fact other parts of the code look like that as well but when I do this the drop down list is not being populated. Am I missing something here?

A couple of side notes: 1) The population of this drop down occurs after selection of a value from another drop down so I make an AJAX call by calling getJSON to get data from the database 2) The application is an MVC application

Would appreciate any help offered. Let me know if you need any other information to help answer this question

Edit: Here are some more details

This is the action method in the controller used to retrieve the data for the drop down

[AcceptVerbs(HttpVerbs.Get)]
    public JsonResult LoadProductsBySupplier(string parentId)
    {
        var ctgy = this._categoryService.GetAllCategoriesByParentCategoryId(Convert.ToInt32(parentId));
        List<int> ctgyIds = new List<int>();

        foreach (Category c in ctgy)
        {
            ctgyIds.Add(c.Id);
        }

        var prods = this._productService.SearchProducts(categoryIds: ctgyIds, storeId: _storeContext.CurrentStore.Id, orderBy: ProductSortingEnum.NameAsc);

        products = prods.Select(m => new SelectListItem()
        {
            Value = m.Id.ToString(),
            Text = m.Name.Substring(m.Name.IndexOf(' ') + 1)
        });

        var p = products.ToList();
        p.Insert(0, new SelectListItem() { Value = "0", Text = "Select A Product" });
        products = p.AsEnumerable();
        //model.ProductNames = products.ToList();


        return Json(products, JsonRequestBehavior.AllowGet);
    }

And this is the JQuery call to the action in the controller

$("#Supplier").change(function () {
        var pID = $(this).val();            
        $.getJSON("CoaLookup/LoadProductsBySupplier", { parentId: pID },
                function (data) {
                    var select = $("#ProductNames");
                    select.empty();
                    if (pID != "0") {
                        $.each(data, function (index, itemData) {
                            select.append($('<option/>', {
                                value: itemData.Value,
                                text: itemData.Text
                            }));
                        });
                    }
                });
    });

It's this $.each loop that doesn't get entered into when I use model => model.Product even though data is returned in the variable data


回答1:


The second usage is correct, however when you use

@Html.DropDownListFor(model => model.Product, .....

you are generating a <select> with the attribute id="Product" so you need to change your script to refer to the element with this ID

....
$.getJSON("CoaLookup/LoadProductsBySupplier", { parentId: pID }, function (data) {
  var select = $("#Product"); // change this selector
  select.empty();
  ....

Edit

As a side not, you do not necessarily need to create a SelectList in your controller method and you code could be simplified to

[AcceptVerbs(HttpVerbs.Get)]
public JsonResult LoadProductsBySupplier(int parentId)
{
  List<int> ctgyIds = _categoryService.GetAllCategoriesByParentCategoryId(parentId).Select(c => c.ID).ToList();
  var products= _productService.SearchProducts(categoryIds: ctgyIds, storeId: _storeContext.CurrentStore.Id, orderBy: ProductSortingEnum.NameAsc).AsEnumerable().Select(p => new
  {
    ID = p.ID,
    Text = p.Name.Substring(m.Name.IndexOf(' ') + 1)
  });
  return Json(products, JsonRequestBehavior.AllowGet);
}

and the script

$("#Supplier").change(function () {
  var pID = $(this).val();
  var select = $("#Product").empty().append($('<option/>').text('Select A Product'));
  if (pID == '0') { return; } // this should really be testing for null or undefined but thats an issue with your first select          
  $.getJSON('@Url.Action("LoadProductsBySupplier", "CoaLookup")', { parentId: $(this).val() }, function (data) {
    $.each(data, function (index, item) {
      select.append($('<option/>').val(item.ID).text(item.Text);
    });
  });
});

Note also in the script the if clause before $.getJSON - there is not much point calling the server then deciding to ignore the return value




回答2:


To get the selected value in Edit page try using:

@Html.DropDownList("name", new SelectList(ViewBag.Product, "Id","Name", item.Id))

in this the item.Id is the selected value, and ViewBag.Product you have to fill it from your products using linq for example in the Controller.



来源:https://stackoverflow.com/questions/26556718/html-dropdownlistfor-confusion

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!