Bootstrap多选框:如何在流程中更新选项列表

14
我使用Bootstrap的多选功能,我想通过ajax更新选项。
初始化我的多选框的填充可以这样做:
<select name="model" class="multiselect" multiple="multiple">
                <? foreach ($sel_models as $mod) { ?>
                    <option value="<?= $mod ?>" <?= ($mod == $params['model']) ? 'selected' : '' ?>><?= $mod ?></option>
                <? } ?>    
</select>  

然后在事件发生时,我想通过以下 ajax 更新我的选项列表。

我尝试使用 rebuild 方法,但它在创建后无法触发下拉列表。

 $.ajax({
        type: 'post',
        url: "helper/ajax_search.php",
        data: {models: decodeURIComponent(brands)},
        dataType: 'json',
        success: function(data) {
            $('select.multiselect').empty();
            $('select.multiselect').append(
                    $('<option></option>')
                    .text('alle')
                    .val('alle')
                    );

            $.each(data, function(index, html) {
                $('select.multiselect').append(
                        $('<option></option>')
                        .text(html.name)
                        .val(html.name)
                        );
            });

            $('.multiselect').multiselect('rebuild')
        },
        error: function(error) {
            console.log("Error:");
            console.log(error);
        }
    });

使用Firebug我可以看到列表已经生成,但在选择时不会显示。


如果您刚刚通过ajax更改了选择框选项,则需要调用$('.multiselect').multiselect('rebuild')。它将重新构建带有选择框中选定值的多选框。 - RN Kushwaha
4个回答

31
在文档中我可以读到:
.multiselect('setOptions', options) 用于在初始化multiselect之后更改配置。这可能与.multiselect('rebuild')结合使用很有用。
也许您无法按照最初的方式更改小部件数据。正确的方法是使用setOptions方法。
否则:按照您的方式,也许您应该考虑销毁您的小部件.multiselect('destroy'),然后重新创建它。
评论后更新:
在文档中:(您已链接)
提供构建选择选项的数据的方式如下:
var data = [
    {label: "ACNP", value: "ACNP"},
    {label: "test", value: "test"}
];
$("#multiselect").multiselect('dataprovider', data);

所以 : 当您从ajax调用中获取数据时,您需要创建一个对象数组(它是您想要拥有的select选项),格式如下:

var data = 
[
    {label: 'option1Label', value: 'option1Value'},
    {label: 'option2Label', value: 'option2Value'},
    ...
]

当你创建对象数组后,只需调用该方法。
$("#multiselect").multiselect('dataprovider', data);

数据是您的对象数组。

希望我表达清楚 :/


谢谢您的反馈!我刚刚阅读了它,但说实话,我不知道该如何使用它。 - fefe
如果我使用数据提供程序,如何传递其他条件,例如按钮宽度、最大高度等? - harishannam
你知道如何在这个数组中包含一个 section 吗? - Thakhani Tharage
我使用jQuery添加了选项,然后使用.multiselect('rebuild'),它起作用了。 - Saurabh Solanki

11
作为multiselect('dataprovider',data)的替代方案,您可以使用jquery append按照您在问题中所做的方式构建列表。 您需要进行的唯一更改是延迟重建,直到ajax请求完成。
var buildDrivers = $.getJSON('resources/orders/drivers.json', function(data) { 
   $.each(data, function(i, driver) {
      $('#toolbar select[name="drivers"]').append('<option>'+driver+'</option>');
   });
});
buildDrivers.complete(function() {
    $('.multiselect').multiselect('rebuild');
});

请参阅http://api.jquery.com/jquery.getjson/获取文档。


0
我已经添加了筛选并从服务器端获取选项后更新选项的功能。这个解决方案依赖于注入新选项、销毁选择并重新初始化它的概念。
我考虑到了以下几点:
  1. 考虑现有的选定选项,必须保留。
  2. 删除重复的选项(可能是由于已经选择的选项与来自服务器的新选项之间的冲突)。
  3. 在更新后保持选项托盘打开状态。
  4. 重新分配搜索文本框中的先前文本并将其聚焦。
只需在“刷新”函数后添加“updateOptions”作为一个函数,并加上两个辅助函数,如下所示:
updateOptions: function (options) {
        var select = this.$select;
        options += this.getSelectedOptionsString();
        var selectedIds = select.val(),
            btnGroup = select.next('.btn-group'),
            searchInput = btnGroup.find('.multiselect-search'),
            inputVal = searchInput.val();

        options = this.removeOptionsDuplications(options);
        if (!options) {
            options = '<option disabled></option>';
        }

        // 1) Replacing the options with new & already selected options
        select.html(options);

        // 2) Destroyng the select
        select.multiselect('destroy');

        // 3) Reselecting the previously selected values
        if (selectedIds) {
            select.val(selectedIds);
        }

        // 4) Initialize the select again after destroying it
        select.multiselect(this.options);

        btnGroup = select.next('.btn-group');
        searchInput = btnGroup.find('.multiselect-search');

        // 5) Keep the tray options open
        btnGroup.addClass('open');

        // 6) Setting the search input again & focusing it
        searchInput.val(inputVal);
        searchInput.focus();
    },
    getSelectedOptionsString: function () { // Helper
        var result = '',
            select = this.$select,
            options = select.find('option:selected');

        if (options && options.length) {
            $.each(options, function (index, value) {
                if (value) {
                    result += value.outerHTML;
                }
            });
        }

        return result;
    },
    removeOptionsDuplications: function (options) { // Helper
        var result = '',
            ids = new Object();

        if (options && options.length) {
            options = $(options);
            $.each(options, function (index, value) {
                var option = $(value),
                    optionId = option.attr('value');

                if (optionId) {
                    if (!ids[optionId]) {
                        result += option[0].outerHTML;
                        ids[optionId] = true;
                    }
                }
            });
        }
        return result;
    },

演示:

状态:

“选项 1”

$('#select').multiselect('updateOptions', '<option value="2">Option 2</option>');

状态:

“选项2”

“选项1”


0

我认为这是一种更简单的方法,可以使用ajax或任何其他监听器在现有的Bootstrap MultiSelect上动态添加选项。

以下是一个简化的示例,用于添加选项:

function addOptionToMultiSelect(multiselectSelector, value, selected) {
    var data = [];
    $(multiselectSelector + ' option').each(function(){
        var value = $(this)[0].value;
        var selected = $(this)[0].selected;
        data.push({label: value, value: value, selected: selected});
    });

    // Add the new item
    data.push({label: value, value: value, selected: selected});

    $(multiselectSelector).multiselect('dataprovider', data);
}

为了简化起见,我假设选项中的标签和值是相同的。请注意,已选择的选项是通过从现有选项中读取selected属性来处理的。您可以通过跟踪禁用和其他属性使其更加复杂。

示例:

addOptionToMultiSelect('#multiselect-example', 'new-option', true);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接