我需要帮助编写jquery / ajax来填充Select2下拉框。
对于那些不知道Select2是什么的人,它是一个javascript扩展,为html选择列表下拉框提供Twitter Bootstrap外观和搜索/提前输入功能。有关详细信息,请查看此处的示例:Select2 Github page
<小时/> 更新 - 已解决!
所以我最终将这些全部放在一起,我的问题的解决方案是我缺少格式化结果和列表选择的函数。下面的代码会生成一个功能正常的Select2保管箱,其前提是完美的。
控制器上的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
}
上面的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:
<input id="hiddenHtmlInput" type="hidden" class="bigdrop" style="width: 30%" value=""/>
或者将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" })
答案 0 :(得分:2)
解决!最后。
下面是完整的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 = "<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;
}
答案 1 :(得分:1)
问题是您从该控制器方法返回List<Contract>
,但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 :(得分:1)
选择2似乎是附加了jquery的标准选择,所以这应该有效:
型号:
public class vmDropDown
{
public IEnumerable<SelectListItem> DeviceList { get; set; }
[Required(ErrorMessage = "Please select at least one item")]
public IEnumerable<int> 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
};
}
查看:
<div class="editor-field">
@Html.ListBoxFor(model => model.SelectedItems, new SelectList(Model.DeviceList, "Value", "Text"))
@Html.ValidationMessageFor(model => model.SelectedItems)
</div>
不能在工作中给出解释,但是如果你留下一条消息,今晚就会把它拿起来