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

时间:2022-11-27 20:04:55

I need help writing the jquery/ajax to fill a Select2 dropdown box.

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

For those who don't know what Select2 is, 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 Select2 dropbox 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 Select2 drop box).

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

The code below is the Javascript in the view(or layout if you prefer) to power the Select2 drop 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 Select2 will render the dropbox to.

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

Html:

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 Razor):

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

3 个解决方案

#1


2  

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;
}

#2


1  

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 ,但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.

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

#3


0  

Select 2 seems to be a standard select with jquery attached so this should work:

选择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

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

#1


2  

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;
}

#2


1  

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 ,但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.

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

#3


0  

Select 2 seems to be a standard select with jquery attached so this should work:

选择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

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