【问题标题】:How to use select2 with multiple options using Razor and MVC如何使用 Razor 和 MVC 将 select2 与多个选项一起使用
【发布时间】:2019-05-06 18:39:18
【问题描述】:

我正在尝试使用 Select2、Razor 和 MVC 框架创建一个多选列表。我的问题是控制器中接收数组输入的对象始终为空。前端看起来如下:

<form class="form-horizontal" method="post" action="@Url.Action(MVC.Configurazione.Contatori.Edit())">
    <div class="form-group">
        <div class="col-lg-8">
            <select class="form-control attributoSelect2" name="attributiSelezionati" value="@Model.AttributiSelezionati">
                <option value="@Model.AttributiSelezionati" selected>@Model.AttributoDescrizione</option>
            </select>
        </div>
    </div>
</form>

动作方法“Edit”,是从下拉列表中接收所选项目数组的控制器方法。

Javascript 如下:

    $('.attributoSelect2').select2({
        placeholder: "Search attribute",
        multiple: true,
        allowClear: true,
        minimumInputLength: 0,
        ajax: {
            dataType: 'json',
            delay: 150,
            url: "@Url.Action(MVC.Configurazione.Attributi.SearchAttrubutes())",
            data: function (params) {
                return {
                    search: params.term
                };
            },
            processResults: function (data) {
                return {
                    results: data.map(function (item) {
                        return {
                            id: item.Id,
                            text: item.Description
                        };
                    })
                };
            }
        }
    });

最后,C# 控制器有一个对象,该对象期望从视图中检索数据并被定义:

public string[] AttributiSelezionati { get; set; }

而接收数据的HttpPost方法是:

[HttpPost]
public virtual ActionResult Edit(EditViewModel model) { }

谁能告诉我我做错了什么以及我应该改变哪些地方才能找到问题?

【问题讨论】:

  • 您正在使用带有select2 的多项选择,对吗?为什么不在选择元素上使用ListBoxFormultiple 属性?
  • 但我在 Javascript 中使用了“multiple: true”标志,这就是我不在视图中使用它的原因。我不确定如何使用 ListBoxFor,但我目前正在研究一些文档,当我取得进展时会更新你。谢谢。
  • &lt;option&gt; 内容是否包含来自 AJAX 的所有选项值?尝试用匹配的大小写分配name 属性,例如name="AttributiSelezionati"。此外,您还通过value="@Model.AttributiSelezionati" 分配默认值,它具有string[] 数组类型而不是string
  • @Razvan,您想将 Select2 中的字符串数组发送到您的控制器操作方法吗?
  • 是的,我想将所选项目发送到控制器操作方法

标签: javascript c# asp.net asp.net-mvc jquery-select2


【解决方案1】:

你的类名错误不是 attributoSelect2 是 attributesSelect2 ,我也经常犯这个错误。哈哈

 <select class="form-control attributoSelect2" name="attributiSelezionati" value="@Model.AttributiSelezionati">
                <option value="@Model.AttributiSelezionati" selected>@Model.AttributoDescrizione</option>
            </select>

【讨论】:

  • 感谢您的回复,但这并不能解决问题。我的问题是我不明白视图和控制器之间的数据绑定是如何工作的。您是否注意到与我如何将数据发送到服务器有关的明显错误?
【解决方案2】:

没有在服务器上接收数据有多种原因。首先你需要改变你的选择代码如下

@Html.DropDownList("attributiSelezionati", Model.AttributiSelezionati, new { @class = "form-control attributo select2" })

现在进入浏览器的控制台并获取元素的数据以确认您的代码在 HTML 和 JS 中正常工作

之后,您需要在控制器的操作方法中添加属性为

[OverrideAuthorization]
[HttpPost]

【讨论】:

    【解决方案3】:

    您可以尝试我们在一些项目中使用的以下方法,没有任何问题:

    查看:

    @Html.DropDownListFor(m => m.StudentId, Enumerable.Empty<SelectListItem>(), "Select")
    
    $(document).ready(function () {
    
        var student = $("#StudentId");
    
        //for Select2 Options: https://select2.github.io/options.html
        student.select2({
            language: "tr",//don't forget to add language script (select2/js/i18n/tr.js)
            minimumInputLength: 0, //for listing all records > set 0
            maximumInputLength: 20, //only allow terms up to 20 characters long         
            multiple: false,
            placeholder: "Select",
            allowClear: true,
            tags: false, //prevent free text entry
            width: "100%",
    
            ajax: {
                url: '/Grade/StudentLookup',
                dataType: 'json',
                delay: 250,
                data: function (params) {
                    return {
                        query: params.term, //search term
                        page: params.page
                    };
                },
                processResults: function (data, page) {
                    var newData = [];
                    $.each(data, function (index, item) {
                        newData.push({
                                //id part present in data 
                                id: item.Id,     
                                //string to be displayed
                                text: item.Name + " " + item.Surname
                        });
                    });
                    return { results: newData };
                },
                cache: true
            },
            escapeMarkup: function (markup) { return markup; }
        });
    
    
        //You can simply listen to the select2:select event to get the selected item
        student.on('select2:select', onSelect)
    
        function onSelect(evt) {
            console.log($(this).val());
        }
    
            //Event example for close event
            student.on('select2:close', onClose)
    
            function onClose(evt) {
                console.log('Closed…');
            } 
    });
    


    控制器:

    public ActionResult StudentLookup(string query)
    {
        var students = repository.Students.Select(m => new StudentViewModel
        {
            Id = m.Id,
            Name = m.Name,
            Surname = m.Surname
        })
        //if "query" is null, get all records
        .Where(m => string.IsNullOrEmpty(query) || m.Name.StartsWith(query)) 
        .OrderBy(m => m.Name);
        return Json(students, JsonRequestBehavior.AllowGet);
    }
    

    希望这会有所帮助...

    更新:

    下拉选项组:

    <select>
      <optgroup label="Group Name">
        <option>Nested option</option>
      </optgroup>
    </select>
    

    有关更多信息,请查看https://select2.org/options

    【讨论】:

    • 谢谢你的例子。这就是我一直在寻找的,一些模板展示了如何做到这一点。但是,我必须使用一个多项选择下拉列表,其中包含一组(按 Id)分组的值,当我从一组中选择一个时,所有其他项目(来自同一组)都将被禁用。你知道如何获得这个吗?
    • 这是我想要实现的一个例子:jsfiddle.net/bindrid/hpkqxto6
    猜你喜欢
    • 2021-06-07
    • 2014-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-30
    • 2015-12-13
    • 2018-04-22
    • 2016-11-23
    相关资源
    最近更新 更多