【问题标题】:How can I hide/show options on the fly with bootstrap-multiselect?如何使用 bootstrap-multiselect 即时隐藏/显示选项?
【发布时间】:2017-12-18 13:25:54
【问题描述】:

我正在使用bootstrap-multiselect 为用户提供两个关键菜单的出色控制器。我的第一个菜单叫做groups,另一个叫做queues。队列中的每个选项都有一个 HTML5 数据属性(即 data-group="X",其中 X 是组值)

当用户从groups 菜单中选择一个选项/组时,我想在queues 菜单中查找并隐藏每个队列/选项,其中data-group 不等于组菜单中的选定组。

确定需要隐藏/显示的队列/项目后,我尝试使用.show() 和.hide() 扩展。然后我尝试使用.addClass('hidden') 和.removeClass('hidden') 方法,但没有什么对我有用。

如何使用bootstrap-multiselect 即时显示/隐藏项目?

这是我的代码

$(function () {
    var queueGroupIds = $('#QueueGroupIds');
    var queueIds = $('#QueueIds');

    queueGroupIds.multiselect({
        nonSelectedText: 'Select group(s)',
        onChange: function (option, checked, select) {
            var groups = queueGroupIds.find('option:selected');

            if (groups.length == 0) {
                //When none of the groups are selected, show all queues!
                queueIds.find('option').each(function (i, q) {
                    $(q).show();
                });
            }

            var queueToDeselect = [];

            //loop over every select option "if any are selected"
            groups.each(function (index, grp) {
                var group = $(grp);

                // loop over every queue option
                queueIds.find('option').each(function (i, q) {
                    var queue = $(q);

                    //id the data-group value == selected group show the item
                    if (queue.data('group') == group.val()) {
                        queue.show();

                        //this prints the value which should be showing
                        console.log('showing', queue.val());
                    } else {
                        queueToDeselect.push(queue.val());
                        queue.hide();

                        //this prints the value which should be hidden
                        console.log('hidding', queue.val());
                    }
                });

            });

            //Delected all hidden queues
            queueIds.multiselect('deselect', queueToDeselect);
            queueIds.multiselect('refresh');
        }
    });

    queueIds.multiselect({
        nonSelectedText: 'Select queue(s)'
    });
});

【问题讨论】:

  • 我怀疑您必须在刷新 queueIds 多选之前实际删除 <option> 元素。
  • 你能提供这个的HTML标记还是小提琴。
  • 查看了 github 存储库中的代码 .... 看起来你必须分叉它才能获得你想要的功能(除非你可以去物理删除 @ 987654334@ 不想要的值)。

标签: javascript jquery twitter-bootstrap multi-select bootstrap-multiselect


【解决方案1】:

已编辑默认未选择: 以下提琴手中显示的示例(为了清楚起见,我将其缩减为基本示例):https://jsfiddle.net/m6uuL53w/3/

无需任何手动混乱的 DOM ADD/REMOVE 操作。多选将继承您放在原始列表中的禁用类,因此您只需在设置禁用值并刷新列表后使用 css 定位它。让多选担心 dom 操作。

示例 HTML:

<select id="one" multiple="multiple">
    <option value="1">One</option>
    <option value="2">Two</option>
    <option value="3">Three</option>
</select>

<select id="two" multiple="multiple">
    <option data-group="1" value="OneA" disabled >One A</option>
    <option data-group="1" value="OneB" disabled>One B</option>
    <option data-group="2" value="TwoA" disabled>Two A</option>
    <option data-group="2" value="TwoB" disabled>Two B</option>
    <option data-group="3" value="ThreeA" disabled >Three A</option>
</select>

jquery:

$(document).ready(function() {
    $('#one').multiselect({
        onChange: function(element, checked) {
        var opts = $('*[data-group="'+ element.val() +'"]');
            if (checked === true) {
                opts.prop('disabled', false).prop('selected', false);
            }
            else if (checked === false) {
                opts.prop('disabled', true).prop('selected', false);
            }
            $("#two").multiselect('refresh');
        }
    });
    $('#two').multiselect();
});

只需一点 CSS:

.multiselect-container > li.disabled { display:none;}

【讨论】:

  • 提琴手没有按预期工作。当我从第一个菜单中选择 One 时,我希望只有 One* 留在第二个菜单上。但这并没有发生。
  • @MikeA 更新了示例,因此默认情况下在第二个下拉列表中未选择任何内容。只需要添加列表的禁用属性初始设置,然后一切都按预期进行,为疏忽道歉。
  • 感谢您的回答。我不想默认禁用所有。我稍微改变了你的提琴手来做我正在寻找的东西,如果你看到更好/更好的写法,请告诉我......这是更新后的提琴手jsfiddle.net/m6uuL53w/7
  • @MikeA 我明天肯定会抽出一些时间来检查一下,当我最初研究你的问题时,我发现很多人都有这个确切的要求,但没有真正的答案,所以很酷能够解决这个问题。
【解决方案2】:

https://jsfiddle.net/ta1wvs3j/1/

    //Because we alter the DOM, we need to save an instance of the original list
    //There are many ways to do this, I chose an easy one
    var globalClone = $('#queues option');

    //Init the queues
    $('#queues').multiselect({
      nonSelectedText: 'Select queue(s)',
      onChange: function (option, checked, select) {
      }
    });
    //Init the groups
    $('#groups').multiselect({
        nonSelectedText: 'Select group(s)',
        onChange: function (option, checked, select) {
            //Store the list of selections in an array
            var selections = $('#groups').val();
            //Reset the queue to it's starting list so we can loop
            $('#queues').html(globalClone);
            //Look at each option
            $('#queues option').each(function(){
                //"includes" may not be widly suppoerted but there are other ways to see if a value is in an array
                //Check to see if the data-group value is in the selections array, if it's not
                if( selections.includes(String($(this).data('group'))) == false ){
                    //Remove the option from the DOM
                    $(this).remove();
                 }
             });
             //Rebuild, per the multiselect docs basically reinit the select. Nice we don't have to destroy and recreate. 
             $('#queues').multiselect('rebuild');
          }
      });

这不是我完全保留生产代码的方式,但它向您展示了它是如何工作的。

基本上,循环、检查、更改 DOM 和重建多选。我想这就是你想要的。

【讨论】:

  • 为 Mike 编写解决方案的道具!您可能需要复制/克隆要删除的项目,以免用户重新选择其他组之一时它们不可用。
  • 不确定你的意思,我可以勾选 1,取消勾选 1 并再次勾选 1,选项会按预期显示隐藏显示。就像我说的,虽然,还没有完全准备好生产,但应该向他展示他想要做什么的基础吗?你的意思是把第 1 行改成$('#queues option').clone()?
  • 糟糕,我现在看到了顶部的那个位。之前错过了,只看到了 .remove() 调用。对不起!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-21
  • 1970-01-01
  • 1970-01-01
  • 2011-10-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多