jQuery 从 MVC 4 中的数据库填充 Select2 下拉框
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14853643/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Fill Select2 dropdown box from database in MVC 4
提问by Whiplash450
I need help writing the jquery/ajax to fill a Select2dropdown box.
我需要帮助编写 jquery/ajax 来填充Select2下拉框。
For those who don't know what Select2is, it is a javascript extension to provide Twitter Bootstrap looks and search / type-ahead functionality to an html select list dropdown box. For more information look at the examples here: Select2 Github page
对于那些不知道Select2是什么的人,它是一个 javascript 扩展,用于为 html 选择列表下拉框提供 Twitter Bootstrap 外观和搜索/提前输入功能。有关更多信息,请查看此处的示例:Select2 Github 页面
UPDATED - Solved!更新 - 解决了!
So I finally put this all together, and the solution to my problems was that I was missing functions to format the results and the list selection. The code below produces a functioning Select2dropbox with type-ahead perfectly.
所以我终于把这一切放在一起,我的问题的解决方案是我缺少格式化结果和列表选择的函数。下面的代码生成了一个功能齐全的Select2 下拉框,并且可以完美地提前输入。
Json Method on Controller:
控制器上的 Json 方法:
public JsonResult FetchItems(string query)
{
DatabaseContext dbContext = new DatabaseContext(); //init dbContext
List<Item> itemsList = dbContext.Items.ToList(); //fetch list of items from db table
List<Item> resultsList = new List<Item>; //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
}
The Json controller method above returns a list of serialised Json objects, whose ItemName contains the string 'query' provided (this 'query' comes from the search box in the Select2drop box).
上面的 Json 控制器方法返回一个序列化的 Json 对象列表,其 ItemName 包含提供的字符串 'query'(这个 'query' 来自Select2下拉框中的搜索框)。
The code below is the Javascript in the view(or layout if you prefer) to power the Select2drop box.
下面的代码是视图(或布局,如果您愿意)中的 Javascript,用于驱动Select2下拉框。
Javascript:
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; }
});
Then in the body of the view you need a hidden Input element, which Select2will render the dropbox to.
然后在视图的主体中,您需要一个隐藏的 Input 元素,Select2会将 Dropbox 渲染到该元素。
Html:
网址:
<input id="hiddenHtmlInput" type="hidden" class="bigdrop" style="width: 30%" value=""/>
Or attach a MVC Razor html.hidden element to your view model to enable you to post the picked item Id back to the server.
或者将 MVC Razor html.hidden 元素附加到您的视图模型,以使您能够将选择的项目 Id 发布回服务器。
Html (MVC Razor):
Html(MVC 剃刀):
@Html.HiddenFor(m => m.ItemModel.ItemId, new { id = "hiddenHtmlInput", @class = "bigdrop", style = "width: 30%", placeholder = "Select an Item" })
采纳答案by Whiplash450
Solved! Finally.
解决了!最后。
The full jquery is below, what was needed were two functions to format the returned results from the controller. This is because the dropbox needs some html markup to be wrapped around the results in order to be able to display them.
完整的 jquery 如下,需要两个函数来格式化控制器返回的结果。这是因为 Dropbox 需要一些 html 标记来包裹结果,以便能够显示它们。
Also contractID was needed as an attribute in the controller as without it results were shown in the dropdown, but they could not be selected.
还需要 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 = "<table class='contract-result'><tr>";
if (contract.name !== undefined) {
markup += "<div class='contract-name'>" + contract.name + "</div>";
}
markup += "</td></tr></table>"
return markup;
}
function contractFormatSelection(contract) {
return contract.name;
}
回答by Graham
The problem is that you are returning a List<Contract>
from that controller method, but the MVC runtime doesn't know how to hand that off to the browser. You need to return a JsonResult
instead:
问题是您正在List<Contract>
从该控制器方法返回 a ,但 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);
}
Now, the data
param of the AJAX : Success function will be the JSON from the controller. I'm not familiar with how this plugin works, but you should be able to loop through the json in data
manually if you need to.
现在,data
AJAX : Success 函数的参数将是来自控制器的 JSON。我不熟悉这个插件的工作原理,但是data
如果需要,您应该能够手动循环 json 。
回答by DavidB
Select 2 seems to be a standard select with jquery attached so this should work:
Select 2 似乎是附加了 jquery 的标准选择,所以这应该可以工作:
Model:
模型:
public class vmDropDown
{
public IEnumerable<SelectListItem> DeviceList { get; set; }
[Required(ErrorMessage = "Please select at least one item")]
public IEnumerable<int> SelectedItems { get; set; }
}
Controller:
控制器:
[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
};
}
View:
看法:
<div class="editor-field">
@Html.ListBoxFor(model => model.SelectedItems, new SelectList(Model.DeviceList, "Value", "Text"))
@Html.ValidationMessageFor(model => model.SelectedItems)
</div>
Cant give explanation as am at work but if you leave a message ill pick it up tonight
不能在工作时给出解释,但如果你留下信息,今晚我会捡起来