【问题标题】:Select2: Hide certain options dynamicallySelect2:动态隐藏某些选项
【发布时间】:2014-09-23 17:28:12
【问题描述】:

基本上,我正在寻找的是能够从选定项目的下拉列表中隐藏选项。因此,从技术上讲,它们仍然是选项,但由于它们是隐藏的,因此您将无法单击它们。

我查看了文档并找到了与禁用相关的内容,不幸的是我非常希望能够隐藏项目。有人对如何实现这一点有建议吗?

是否有可能做一些事情,比如让 select 在原始 <option> 元素和该元素的 select2 副本之间进行一些特定的映射,那也可以。例如,假设“如果原始<option> 具有此类或具有此类属性,则选择下拉列表中的结果项将采用这种方式构造”。

【问题讨论】:

标签: hide jquery-select2


【解决方案1】:

将以下 CSS 规则添加到页面会解决您的问题吗?

.select2-container--default .select2-results__option[aria-disabled=true] {
    display: none;
}

基本上它会隐藏一个禁用选项,而不是用灰色背景显示它。

在您的选项列表中也使用disabled 而不是display:'none'

JS Bin

【讨论】:

  • 添加了编辑,在 IE9 中测试有效,在 IE8 中无法测试 - 你能告诉我它是否在 IE8 中有效吗?
  • 非常适合我。不过不需要支持非浏览器。
  • 我不得不使用 [aria-seleted=true] 而不是 [aria-disabled=true]
  • 你的答案可能是这个问题最相关和最精确的解决方案。搜索了一个多小时,只有在启用多项选择的 select2 上这对我有用。
  • 您可能应该考虑更新您的答案。您的回答似乎简短而准确,但 class="select2-container--default" 在最新版本的 select2 中对我来说似乎不存在。
【解决方案2】:

我刚刚投入了 3 个小时,为我找到了一个非常干净和简单的解决方案,可以在 select2 容器中动态显示/隐藏选项。

首先,我使用此选项创建 select2:

$( selector ).select2({
  templateResult: resultState
});

然后我提供resultState 回调函数,它将所有类从原始<option> 复制到select2-option。这允许我们根据我们分配给原始选项的类来显示/隐藏 select2 中的选项。

function resultState(data, container) {
    if(data.element) {
        $(container).addClass($(data.element).attr("class"));
    }
    return data.text;
}

在我的 css 中我声明了这一行:

.select2-container .select2-results__option.optInvisible {
    display: none;
}

现在我可以通过将 optInvisible 类添加到 <option> 来轻松显示或隐藏 select2 容器中的任何选项:

<select>
  <option class="optInvisible">Choose one</option>
  <option value="1">1</option>
</select>

或者您也可以使用addClass("optInvisible")removeClass("optInvisible") 动态更新它。

愿这对任何人都有帮助;) 问候

【讨论】:

  • 嗨。你向谁添加或删除类“optInvisibel”到选项标签?谢谢
  • 嗨,Tom,您将类 'optInvisible' 分配给原始
  • 不错的解决方案,v.clean,ty
  • 另一个选项是直接通过样式显示/隐藏选项。 $(容器).hide().
【解决方案3】:

如果你想实现,或许可以修改select2.js代码,

首先我隐藏了第二个选项,原来你用的时候它不起作用

select2 插件,

<select id="test" style="width:100px">
  <option></option>
  <option value='1'>1</option>
  <option value='2' style="display:none">2</option>
</select>

其次,我将修改 select2.js 代码:第 926 行

我在这里添加额外的条件语句&amp;&amp; element.css('display') != 'none'

 process = function (element, collection) {
     var group;
     if (element.is("option") && element.css('display') != 'none') {
         if (query.matcher(term, element.text(), element)) {
              collection.push(self.optionToData(element));
              }
     } else if (element.is("optgroup")) {
              group = self.optionToData(element);
              element.children().each(function (i, elm) { 
                       process(elm, group.children); 
                   });
              if (group.children.length > 0) {
                       collection.push(group);
              }
      }
     };

JSBINhttp://jsbin.com/qusimi/1/edit

【讨论】:

    【解决方案4】:
    $('.selector').remove(); 
    

    然后根据它在select2中出现的位置附加选项:

    然后作为第一个选项出现:

    $('.selector')
    .prepend('<option value="option-value" class="option-value">Option Label</option>');
    

    然后作为最后一个选项出现:

    $('.selector')
    .append('<option value="option-value" class="option-value">Option Label</option>');
    

    出现在任何选项之后:

    $('<option value="option-value" class="option-class">Option Label</option>')
    .insertAfter($('.selector option:first-child'));
    

    或者

    $('<option value="option-value" class="option-value">Option Label</option>')
    .insertAfter($('.selector > .option-class'));
    

    我们可以使用jquery 禁用/启用该选项,而不是隐藏。

    $('.selector').prop('disabled', 'disabled');
    
    $('.selector')
    .prop('disabled', !$('.selector').prop('disabled'));
    

    【讨论】:

      【解决方案5】:

      我也有类似的要求。隐藏是首选,但其中许多答案对于多个浏览器都不确定或过于复杂。更改 select2 代码也是不可能的。

      我的解决方案是将每个选择的选项副本作为数组存储在内存中。当我想“隐藏”一个选项时,我会使用 jQuery remove()。当我想“取消隐藏”时,我会将其重新添加到该选择的选项中。

      如果您可能隐藏了当前可能被选中的选项,请记住在选择上调用 .trigger("change")。

      【讨论】:

        【解决方案6】:

        这是@peter-schilling 对答案的更新,因为the Select2 templating API 似乎在他发布之后发生了变化。

        我需要动态显示和隐藏 Select2 所针对的 select 中的选项,因此我像这样初始化 Select2:

        $("#myDropdown").select2({
            ...
            templateResult: function (state) {
                let $opt = $(state.element);
                if ($opt.hasClass("d-none")) {
                    return null;
                }
                return state.text;
            }
        });
        

        这里我使用了d-none utility class from Bootstrap,但您可以轻松地使用您自己的 CSS 类(或&lt;option&gt; 元素上的任何其他属性,就此而言)来标识应隐藏的选项。

        由于我是在我的基础 &lt;select&gt; 元素的 &lt;option&gt;s 上动态设置此类,因此我必须每次都重新初始化 Select2,我就是这样做的:

        $("#myDropdown").select2("destroy");
        $("#myDropdown").select2(select2Options);
        

        (我将我的 Select2 配置选项作为名为 select2Options 的全局变量存储在 Javascript 对象中,然后在初始化 Select2 的任何地方都像这样使用它们,因为我希望行为在整个应用程序中保持一致。 )

        【讨论】:

          【解决方案7】:

          这是接受答案的小变化,实际上我必须修改接受的答案才能使其正常工作,我必须更改类名,这可能是因为 Select2 库的版本不同

          .select2-results__options .select2-results__option[aria-disabled=true] {
             display: none;
          }
          

          【讨论】:

          • @KazimZaidi 尝试投票最多的答案,如果它不适合您,请尝试其他答案
          【解决方案8】:

          此代码有效。使用 Select2 4.0.6 版本测试

              <select class='select2'>
                  <option>WillShow</option>
                  <option willHide='true'>WillHide</option>
              </select>
          
              <style>
                  li[aria-disabled='true'] {
                      display: none;
                  }
              </style>
          
              <script type="text/javascript">
                  $(".select2").select2();
                  $(".select2 option[willHide='true']").prop("disabled", true);
              </script>
          

          【讨论】:

            【解决方案9】:

            我刚刚对他的答案 6 做了一个变体,并通过隐藏属性更改了类,所以这样每个具有隐藏属性的选项也将隐藏在 select2 容器中,如下所示,选项 1 将被隐藏:

            <select class='mySelect'> My Select 2
            <option hidden>1</option>
            <option >2</option>
            <option >3</option>
            </select>
            
            $('.mySelect').select2({templateResult: hideSelect2Option});
            
            function hideSelect2Option(data, container) {
                if(data.element) {
                    $(container).addClass($(data.element).attr("class"));
                    $(container).attr('hidden',$(data.element).attr("hidden"));
                }
                return data.text;
            }
            
               
            

            【讨论】:

              【解决方案10】:

              如果有人想要使用 jquery 数据标签的另一个选项,这对我来说很合适:

              $('.select2 option').each(function(){
                      if ($(this).data('condition') != 'true' ) {
                        $(this).wrap('<div></div>')
                      } else {
                        $(this).unwrap('div')
                      }
              })
              

              【讨论】:

                【解决方案11】:

                我遇到了一种情况,需要从角色列表中单击“角色”按钮,然后打开一个模式,在该模式中我必须选择任何其他角色,从中将权限复制到当前单击的角色(laravel 8项目,最新的 jQuery)。通过数据属性发送当前单击的角色以添加到模态隐藏输入,我使用 jQuery 构建选择,不添加当前角色选项(根本不显示),然后调用 select2 进行初始化。

                按钮:

                <i class="fas fa-download cursor-pointer" data-copy-permissions="10" 
                data-toggle="modal" data-target="#copy_permissions"></i>
                

                模态表单元素:

                <input type="hidden" name="current_role_id" value="">
                <select name="copy_role_id" id="copy_role_id" style="width: 100%"></select>
                

                DOM 操作(我也有选择 optgroups,但与讨论无关):

                $("[data-copy-permissions]").on('click touch', function() {
                        let current_role_id = $(this).data('copy-permissions');
                        $('input[name="current_role_id"]').val(current_role_id);
                        let roles_select = $('select[name="copy_role_id"]').html("");
                        let option = "";
                
                        @foreach ($rolesTree as $section)
                            option = '<optgroup label="{{ $section['section']->label }}">';
                                @foreach ($section['subroles'] as $subrole)
                                    if(current_role_id != '{{ $subrole->id }}') {
                                        option += '<option value="{{ $subrole->id }}">{{ ucfirst($subrole->name) }}</option>';
                                    }
                                @endforeach
                            option += '</optgroup>';
                            roles_select.append(option);
                        @endforeach
                
                        roles_select.select2();
                    });
                

                【讨论】:

                  猜你喜欢
                  • 2018-06-13
                  • 1970-01-01
                  • 2017-02-08
                  • 1970-01-01
                  • 2023-01-10
                  • 2019-02-10
                  • 2020-03-09
                  • 2017-06-02
                  • 1970-01-01
                  相关资源
                  最近更新 更多