如何在 jQuery select2 远程 select 框中设置默认 selected 值的顺序?

How to set ordering for default selected value in jQuery select2 remote select box?

我自定义了 select2 插件来显示默认的 selected 值。我在会话创建和编辑页面中应用了 select2 远程 select 框。当我创建一个会话并从下拉列表中 select 多个发言者时,它显示为 selected.

创建页面:

但是,当我为该会话编辑另一个字段时,selected 扬声器没有按插入的顺序显示

编辑页面:

这是我的 jQuery 代码片段:

$(".jsRemoteSelectBox").each(function (index, element) {
        if ($(element).data("isprocessed") != "1" && $(element).attr("isprocessed") != 1) {
            $(element).data("isprocessed", "1");
            $(element).attr("isprocessed", "1");
            select2SelectedResult = [];
            if ($(element).data("defaultvalue") != undefined) {
                select2SelectedResult = $(element).data("defaultvalue");
            }
            oOptionHtml = [];
            var oTargetControl = $(element).data('targetcontrol');
            $(element).select2({
                dropdownAutoWidth: true,
                allowClear: ($(element).data('allowclear') == "True" ? true : false),
                closeOnSelect: ($(element).data('iscloseonselect') == "True" ? true : false),
                width: '100%',
                placeholder: ($(element).data('placeholder') != undefined ? $(element).data('placeholder') : "Type to search"),
                ajax:
                {
                    url: $(element).data('url'),
                    type: "POST",
                    dataType: 'json',
                    data: function (params) {
                        return {
                            search: params.term,
                            pageResult: ($(element).data('pageresult') != undefined ? $(element).data('pageresult') : 10),
                            page: params.page,
                            notIn: (oTargetControl != undefined ? ($.isArray($("#" + oTargetControl).val()) ? $("#" + oTargetControl).val().join(",") : $("#" + oTargetControl).val()) : ($(element).data('fixedvalue') != undefined ? $(element).data('fixedvalue') : ""))
                        };
                    },
                    processResults: function (data, params) {
                        params.page = params.page || 1;

                        return {
                            results: data.items,
                            pagination: {
                                more: (params.page * ($(element).data('pageresult') != undefined ? $(element).data('pageresult') : 10)) < data.total_count
                            }
                        };
                    },
                    cache: true
                },
                escapeMarkup: function (markup) { return markup; },
                minimumInputLength: ($(element).data('minlength') != undefined ? $(element).data('minlength') : 3),
                //templateResult: formatResult,
                templateResult: function (optionResult) {
                    if (optionResult.loading) return optionResult.text;
                    oOptionHtml = [];
                    oOptionHtml.push("<div class='select2-result-repository clearfix'>");
                    if ($(element).data("isimagedisplay") == "True") {
                        oOptionHtml.push("<div class='select2-result-repository__avatar'>");
                        oOptionHtml.push("<img src='" + optionResult.imageurl + "' />");
                        oOptionHtml.push("</div>");
                    }
                    oOptionHtml.push("<div class='select2-result-repository__meta'>");
                    oOptionHtml.push("<div class='select2-result-repository__title'>");
                    oOptionHtml.push(optionResult.full_name);
                    oOptionHtml.push("</div>");
                    oOptionHtml.push("</div>");
                    if ($(element).data("isdescriptiondisplay") == "True") {
                        oOptionHtml.push("<div class='select2-result-repository__description'>");
                        oOptionHtml.push(optionResult.description);
                        oOptionHtml.push("</div>");
                    }
                    oOptionHtml.push("</div>");

                    return oOptionHtml.join(" ");
                },
                templateSelection: formatResultSelection,
                data: select2SelectedResult
            });
            if (select2SelectedResult.length > 0) {
                $(element).val(select2SelectedResult.select('x.id'));
                $(element).trigger('change');
            }
        }
    });

创建页面上生成的 Html 代码是:

<div class="row">
    <div class="col-md-12 form-group">
        <label>Select Speaker</label>

        <select class="jsRemoteSelectBox form-control select2-hidden-accessible" data-allowclear="True" data-iscloseonselect="True" data-isdescriptiondisplay="False" data-isimagedisplay="True" data-minlength="3" data-pageresult="10" data-placeholder="Type to search speaker" data-targetcontrol="jsClientID" data-url="/Speakers/SearchSpeakers" id="SpeakerIDs" multiple="" name="SpeakerIDs" isprocessed="1" data-select2-id="SpeakerIDs" tabindex="-1" aria-hidden="true">
        </select>
        <span class="select2 select2-container select2-container--default select2-container--focus" dir="ltr" data-select2-id="6" style="width: 100%;">
            <span class="selection">
                <span class="select2-selection select2-selection--multiple" role="combobox" aria-haspopup="true" aria-expanded="false" tabindex="-1" aria-disabled="false">
                    <ul class="select2-selection__rendered">
                        <li class="select2-search select2-search--inline">
                            <input class="select2-search__field" type="search" tabindex="0" autocomplete="off" autocorrect="off" autocapitalize="none" spellcheck="false" role="searchbox" aria-autocomplete="list" placeholder="Type to search speaker" style="width: 1238px;">
                        </li>
                    </ul>
                </span>
            </span>
            <span class="dropdown-wrapper" aria-hidden="true"></span>
        </span>
        <div>
            <small>Usage: Enter at least three characters to get speakers name suggestions. Select a value to continue adding more speakers.</small>
        </div>

        <span class="field-validation-valid red" data-valmsg-for="SpeakerIDs" data-valmsg-replace="true"></span>
    </div>
</div>

编辑页面上生成的 Html 代码是:

<div class="row">
    <div class="col-md-12 form-group">
        <label>Select Speaker</label>

        <select class="jsRemoteSelectBox form-control select2-hidden-accessible" data-allowclear="True" data-defaultvalue="[{&quot;id&quot;:&quot;2&quot;,&quot;text&quot;:&quot;Angela  Xavier (Senior Exclusive Head)&quot;,&quot;ImageUrl&quot;:&quot;cf0fab51-84af-43b6-9c4b-7e96227f4e95_images.jpg&quot;,&quot;SessionID&quot;:1056},{&quot;id&quot;:&quot;1&quot;,&quot;text&quot;:&quot;Jon Patel ()&quot;,&quot;ImageUrl&quot;:&quot;7844b969-e793-4af3-899c-0d28bc97da18_download_(2).png&quot;,&quot;SessionID&quot;:1056},{&quot;id&quot;:&quot;3&quot;,&quot;text&quot;:&quot;Haresh Yadav ()&quot;,&quot;ImageUrl&quot;:&quot;28937477-3e2d-4166-aad8-758ffe6ad17b_Beacon_logo_FINAL_white_&amp;_green.jpg&quot;,&quot;SessionID&quot;:1056}]" data-iscloseonselect="True" data-isdescriptiondisplay="False" data-isimagedisplay="True" data-minlength="3" data-pageresult="10" data-placeholder="Type to search speaker" data-targetcontrol="jsClientID" data-url="/Speakers/SearchSpeakers" id="SpeakerIDs" multiple="" name="SpeakerIDs" isprocessed="1" data-select2-id="SpeakerIDs" tabindex="-1" aria-hidden="true">
            <option value="2" data-select2-id="17">Angela  Xavier (Senior Exclusive Head)</option>
            <option value="1" data-select2-id="18">Jon Patel ()</option>
            <option value="3" data-select2-id="19">Haresh Yadav ()</option>
        </select>
        <span class="select2 select2-container select2-container--default select2-container--focus" dir="ltr" data-select2-id="16" style="width: 100%;">
            <span class="selection">
                <span class="select2-selection select2-selection--multiple" role="combobox" aria-haspopup="true" aria-expanded="false" tabindex="-1" aria-disabled="false">
                    <ul class="select2-selection__rendered">
                        <span class="select2-selection__clear" title="Remove all items" data-select2-id="23">×</span>
                        <li class="select2-selection__choice" title="Angela  Xavier (Senior Exclusive Head)" data-select2-id="20">
                            <span class="select2-selection__choice__remove" role="presentation">×</span>Angela  Xavier (Senior Exclusive Head)
                        </li>
                        <li class="select2-selection__choice" title="Jon Patel ()" data-select2-id="21">
                            <span class="select2-selection__choice__remove" role="presentation">×</span>Jon Patel ()
                        </li>
                        <li class="select2-selection__choice" title="Haresh Yadav ()" data-select2-id="22">
                            <span class="select2-selection__choice__remove" role="presentation">×</span>Haresh Yadav ()
                        </li>
                        <li class="select2-search select2-search--inline">
                            <input class="select2-search__field" type="search" tabindex="0" autocomplete="off" autocorrect="off" autocapitalize="none" spellcheck="false" role="searchbox" aria-autocomplete="list" placeholder="" style="width: 0.75em;">
                        </li>
                    </ul>
                </span>
            </span>
            <span class="dropdown-wrapper" aria-hidden="true"></span>
        </span>
        <div>
            <small>Usage: Enter at least three characters to get speakers name suggestions. Select a value to continue adding more speakers.</small>
        </div>

        <span class="field-validation-valid red" data-valmsg-for="SpeakerIDs" data-valmsg-replace="true"></span>
    </div>
</div>

请帮我解决这个问题。

这不是一个更简单的解决方案,这里有一个显示您想要的示例(select selecting 上的事件,unselect unselecting 上的事件):

$('#example').select2();

$('#example').on("select2:selecting select2:unselecting", function (evt) {
    var _id = evt.params.args.data._resultId.match(/select2-(\w+)-result/)[1];
    var ul = $(`ul#select2-${_id}-container`)
    var tmpord = ul.children('li').map((idx, elm) => CSS.escape(elm.title)).get()
    tmpord.push(CSS.escape(evt.params.args.data.text))
    ul.data('tmpord', tmpord)
}).on("select2:select select2:unselect", function (evt) {
    var _id = evt.params.data._resultId.match(/select2-(\w+)-result/)[1];
    var ul = $(`ul#select2-${_id}-container`);
    ;(ul.data('tmpord')||[]).forEach(tp => {
        var li = ul.children(`li[title="${tp}"]:contains("${tp}")`)
        li.detach().appendTo(ul)
    })
});
<html>
  <body>
    <link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>

<select id="example" multiple="multiple" style="width: 300px">
    <option value="Apple">Apple</option>
    <option value="Bat">Bat</option>
    <option value="Cat">Cat</option>
    <option value="Dog">Dog</option>
    <option value="Elephant">Elephant</option>
    <option value="View/Exposure">View/Exposure</option>
    <option value="View / Exposure">View / Exposure</option>
    <option value="Dummy - Data">Dummy - Data</option>
    <option value="Dummy-Data">Dummy-Data</option>
    <option value="Dummy:Data">Dummy:Data</option>
    <option value="Dummy(Data)">Dummy(Data)</option>    
</select>

  </body>
</html>

它正在使用内部未记录的 _resultId 属性 这是一个 hack,不能保证这个 属性 会一直存在

使用来自 json 或数组的数据的解决方案:

    var sampleArray = [
    {id: 0, text: 'enhancement'},
    {id: 1, text: 'bug'},
    {id: 2, text: 'duplicate'},
    {id: 3, text: 'invalid'},
    {id: 4, text: 'wontfix'}];

    $("#e10").select2({
      data: sampleArray
    });
    
        $('#e10').on("select2:selecting select2:unselecting", function(evt) {
      var _id = evt.params.args.data._resultId.match(/select2-(\w+)-result/)[1];
      var ul = $(`ul#select2-${_id}-container`)
      var tmpord = ul.children('li').map((idx, elm) => CSS.escape(elm.title)).get()
      tmpord.push(CSS.escape(evt.params.args.data.text))
      ul.data('tmpord', tmpord)
    }).on("select2:select select2:unselect", function(evt) {
      var _id = evt.params.data._resultId.match(/select2-(\w+)-result/)[1];
      var ul = $(`ul#select2-${_id}-container`);;
      (ul.data('tmpord') || []).forEach(tp => {
        var li = ul.children(`li[title="${tp}"]:contains("${tp}")`)
        li.detach().appendTo(ul)
      })
    });
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>

<input type="hidden" id="e10" multiple="multiple" style="width:300px" />

据我了解,您需要在模型中添加一个 Sequence 字段。

你的模型应该是这样的。

public string id { get; set; } // id for drop-down value
public string text { get; set; } // text for drop-down text visible in select control
public int? Sequence { get; set; } // this is the new filed you have to manage when you select multiple option in drop-down and store in db level.

之后需要更改您的 select2 partial helper

if (Model.DefaultSelectedValue != null && Model.DefaultSelectedValue.Count > 0)
{
        HtmlAttributes.Add("data-defaultValue", JsonConvert.SerializeObject(Model.DefaultSelectedValue.OrderBy(x=>x.Sequence),
        Formatting.Indented));
}

注意:我也构建了相同的 select2 helper,但与您不同,如果我在编辑时 select 的值类似于 2,5,1,4,我在插入时也遇到了问题值显示 1,2,4,5.

如果您仍然遇到问题,请告诉我,以便我们联系。