从MVC 4中的数据库填充Select2下拉框

我需要帮助编写jquery / ajax来填充Select2下拉框。

对于那些不知道Select2是什么的人来说,它是一个javascript扩展,为html选择列表下拉框提供Twitter Bootstrap外观和搜索/提前输入function。 有关更多信息,请查看此处的示例: Select2 Github页面


更新 – 解决了!


所以我最终将这一切放在一起,我的问题的解决方案是我缺少格式化结果和列表选择的函数。 下面的代码生成一个function齐全的Select2保管箱,完美地预先输入。

控制器上的Json方法:

public JsonResult FetchItems(string query) { DatabaseContext dbContext = new DatabaseContext(); //init dbContext List itemsList = dbContext.Items.ToList(); //fetch list of items from db table List resultsList = new List; //create empty results list foreach(var item in itemsList) { //if any item contains the query string if (item.ItemName.IndexOf(query, StringComparison.OrdinalIgnoreCase) >= 0) { resultsList.Add(item); //then add item to the results list } } resultsList.Sort(delegate(Item c1, Item c2) { return c1.ItemName.CompareTo(c2.ItemName); }); //sort the results list alphabetically by ItemName var serialisedJson = from result in resultsList //serialise the results list into json select new { name = result.ItemName, //each json object will have id = result.ItemID //these two variables [name, id] }; return Json(serialisedJson , JsonRequestBehavior.AllowGet); //return the serialised results list } 

上面的Json控制器方法返回一个序列化的Json对象列表,其ItemName包含提供的字符串’query’(这个’query’来自Select2下拉框中的搜索框)。

下面的代码是视图中的Javascript(或者如果您愿意,可以使用布局)为Select2下拉框供电。

使用Javascript:

 $("#hiddenHtmlInput").select2({ initSelection: function (element, callback) { var elementText = "@ViewBag.currentItemName"; callback({ "name": elementText }); }, placeholder: "Select an Item", allowClear: true, style: "display: inline-block", minimumInputLength: 2, //you can specify a min. query length to return results ajax:{ cache: false, dataType: "json", type: "GET", url: "@Url.Action("JsonControllerMethod", "ControllerName")", data: function (searchTerm) { return { query: searchTerm }; }, results: function (data) { return {results: data}; } }, formatResult: itemFormatResult, formatSelection: function(item){ return item.name; } escapeMarkup: function (m) { return m; } }); 

然后在视图的主体中,您需要一个隐藏的Input元素, Select2将渲染Dropbox。

HTML:

  

或者将MVC Razor html.hidden元素附加到视图模型,以便将拾取的项目ID发布回服务器。

Html(MVC Razor):

 @Html.HiddenFor(m => m.ItemModel.ItemId, new { id = "hiddenHtmlInput", @class = "bigdrop", style = "width: 30%", placeholder = "Select an Item" }) 

解决了! 最后。

完整的jquery在下面,需要的是两个函数来格式化来自控制器的返回结果。 这是因为dropbox需要将一些html标记包裹在结果中以便能够显示它们。

此外,还需要contractID作为控制器中的属性,因为没有结果显示在下拉列表中,但无法选择它们。

 $("#contractName").select2({ placeholder: "Type to find a Contract", allowClear: true, minimumInputLength: 2, ajax: { cache: false, dataType: "json", type: "GET", url: "@Url.Action("FetchContracts", "Leads")", data: function(searchTerm){ return { query: searchTerm }; }, results: function(data){ return { results: data }; } }, formatResult: contractFormatResult, formatSelection: contractFormatSelection, escapeMarkup: function (m) { return m; } }); function contractFormatResult(contract) { var markup = ""; if (contract.name !== undefined) { markup += "
" + contract.name + "
"; } markup += "
" return markup; } function contractFormatSelection(contract) { return contract.name; }

问题是您从该控制器方法返回List ,但MVC运行时不知道如何将其交给浏览器。 你需要返回一个JsonResult

 public JsonResult FetchContracts() { TelemarketingContext teleContext = new TelemarketingContext(); var contracts = teleContext.Contracts.ToList(); var json = from contract in contracts select new { name = contract.ContractName, id = contract.ContactID, }; return Json(json, JsonRequestBehavior.AllowGet); } 

现在,AJAX:Success函数的data参数将是来自控制器的JSON。 我不熟悉这个插件是如何工作的,但如果需要的话,你应该能够手动遍历data的json。

选择2似乎是附加了jquery的标准选择,所以这应该工作:

模型:

  public class vmDropDown { public IEnumerable DeviceList { get; set; } [Required(ErrorMessage = "Please select at least one item")] public IEnumerable SelectedItems { get; set; } } 

控制器:

  [HttpGet] public ActionResult Assign(int id) { return View(CreateUnassignedModel(id)); } [HttpPost] public ActionResult Assign(vmDeviceAssign model) { if (ModelState.IsValid) { _deviceLogic.Assign(model.GroupId, model.SelectedItems); return View("ConfirmDevice"); } else // Validation error, so redisplay data entry form { return View(CreateUnassignedModel(model.GroupId)); } } private vmDeviceAssign CreateUnassignedModel(int id) { return new vmDeviceAssign { DeviceList = _deviceLogic.GetUnassigned(), SelectedItems = null }; } 

视图:

 
@Html.ListBoxFor(model => model.SelectedItems, new SelectList(Model.DeviceList, "Value", "Text")) @Html.ValidationMessageFor(model => model.SelectedItems)

不能在工作中给出解释,但是如果你留下一个消息,今晚就会接受