select2 多组选择。选择父节点,禁用子节点。取消选择父节点,启用子节点

问题描述 投票:0回答:1

我已经用

select2
实现了 2 个自定义函数:

  1. 选择父节点,将父节点添加到选定的节点并禁用子节点。
  2. 取消选择父节点,从选定的节点中删除并启用子节点。

这是有效的,除非按此顺序添加和删除父节点:

  1. 选择父级
  2. 打开新兴选项(可以看到子节点被禁用)
  3. 单击搜索框外部,关闭新兴选项
  4. 取消选择父级
  5. 再次打开新兴框(子节点仍处于禁用状态)

相反,如果步骤2和3没有完成,它会起作用。

  1. 选择父级
  2. 取消选择父级
  3. 打开新兴选项(您可以看到子节点已重新启用)

请参阅一个工作示例:

const tags = [{
    'id': 1,
    'text': 'Parent 1',
    'children': [{
        'id': 'tag11',
        'text': 'Tag 11'
      },
      {
        'id': 'tag12',
        'text': 'Tag 12'
      }, {
        'id': 'parent1',
        'text': 'Parent 1'
      },
    ],
  },
  {
    'id': 2,
    'text': 'Parent 2',
    'children': [{
        'id': 'tag21',
        'text': 'Tag 21'
      },
      {
        'id': 'tag22',
        'text': 'Tag 22'
      },
      {
        'id': 'parent2',
        'text': 'Parent 2'
      },
    ],
  }
];
$(document).ready(function() {

  const selectField = $('#target');
  
  selectField.select2({
    width: '300px',
    templateResult: function(option) {
      if (option.element && (option.element).hasAttribute('hidden')) {
        return null;
      }
      return option.text;
    }
  });

  selectField.on('select2:open', function(e) {
    let allOptionsStart = this.options;
    $('#select2-target-results').on('click', function(event) {
      let allOptions = [];
      $.each(allOptionsStart, (key, option) => {
        allOptions[option.value] = option;
      });

      const data = $(event.target).html();
      const selectedOptionGroup = data.toString().trim();

      let selectedOptionGroupId = '';
      $.each(tags, (key, tag) => {
        if (selectedOptionGroup.toString() === tag.text.toString()) {
          $.each(tag.children, (key, child) => {
            if (selectedOptionGroup.toString() === child.text) {
              selectedOptionGroupId = child.id;
            }
            const jTag = $(allOptions[child.id]);
            if (Object.keys(jTag).length > 0) {
              if (!jTag[0].hidden) {
                jTag[0].disabled = true;
              }
            }
          });
        }
      });
      $('select').select2({
        width: '300px',
        templateResult: function(option) {
          if (option.element && (option.element).hasAttribute('hidden')) {
            return null;
          }
          return option.text;
        }
      });
      event.stopPropagation();

      let options = selectField.val();
      if (options === null || options === '') {
        options = [];
      }
      options.push(selectedOptionGroupId);

      selectField.val(options);
      selectField.trigger('change'); // Notify any JS components that the value changed
      selectField.select2('close');
    });
  });

  selectField.on('select2:unselecting', function(e) {
    let allOptions = [];
    $.each(this.options, (key, option) => {
      allOptions[option.value] = option;
    });
    const unselectedGroupText = e.params.args.data.text;
    $.each(tags, (key, tag) => {
      if (unselectedGroupText === tag.text) {
        $.each(tag.children, (key, childTag) => {
          const jTag = $(allOptions[childTag.id]);
          if (Object.keys(jTag).length > 0) {
            if (!jTag[0].hidden) {
              jTag[0].disabled = false;
            }
          }
        });
      }
    });
  });

});
li.select2-results__option strong.select2-results__group:hover {
  background-color: #ddd;
  cursor: pointer;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js"></script>

<select id="target" data-placeholder="Select an option" multiple='multiple'>
  <optgroup label="Parent 1">
    <option value="tag11">Tag 11</option>
    <option value="tag12">Tag 12</option>
    <option value="parent1" hidden>Parent 1</option>
  </optgroup>
  <optgroup label="Parent 2">
    <option class="tag21">Tag 21</option>
    <option class="tag22">Tag 22</option>
    <option value="parent2" hidden>Parent 2</option>
  </optgroup>
</select>

jsfiddle(以防万一):https://jsfiddle.net/ivantxo/bzu2xmp9/151/

谁能帮我看看出了什么问题吗?

这在两种情况下都应该有效。

谢谢。

javascript jquery jquery-select2-4
1个回答
0
投票

我已经明白这么多了。我希望它会有所帮助。

<!DOCTYPE html>
<html>
<head>
    <title>Select2 Example</title>
    <!-- Include jQuery -->
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>

    <!-- Include Select2 CSS and JS -->
    <link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/js/select2.min.js"></script>

    <style>
        /* Custom CSS to style the parent and child options */
        .parent {
            font-weight: bold;
        }
        .child {
            margin-left: 20px;
            color: #888;
        }
    </style>
</head>
<body>
    <select id="mySelect" multiple style="width: 300px;">
        <optgroup label="Parent 1" class="parent">
            <option value="parent1">Parent 1</option>
            <option value="child1_1" class="child" data-parent="parent1">Child 1.1</option>
            <option value="child1_2" class="child" data-parent="parent1">Child 1.2</option>
        </optgroup>
        <optgroup label="Parent 2" class="parent">
            <option value="parent2">Parent 2</option>
            <option value="child2_1" class="child" data-parent="parent2">Child 2.1</option>
            <option value="child2_2" class="child" data-parent="parent2">Child 2.2</option>
        </optgroup>
    </select>

    <script>
        $(document).ready(function() {
            // Initialize Select2
            $('#mySelect').select2();

            // Store the selected parents
            var selectedParents = [];

            // Listen for changes on the parent options
            $('#mySelect').on('change', function() {
                // Get the selected options
                var selectedOptions = $(this).val();

                // Iterate through selected parents
                $.each(selectedParents, function(index, parent) {
                    // If a parent was deselected, enable its children
                    if (!selectedOptions.includes(parent)) {
                        $('.child[data-parent="' + parent + '"]').prop('disabled', false);
                    }
                });

                // Clear and update selected parents
                selectedParents = [];

                // Iterate through the selected options
                $.each(selectedOptions, function(index, value) {
                    // Check if the selected option is a parent
                    if (value.startsWith('parent')) {
                        // Disable child options associated with this parent
                        $('.child[data-parent="' + value + '"]').prop('disabled', true);
                        // Add selected parent to the list
                        selectedParents.push(value);
                    } else {
                        // Check if the selected option is a child
                        var parentValue = $('.child[value="' + value + '"]').data('parent');
                        // Deselect child if its parent is not selected
                        if (!selectedParents.includes(parentValue)) {
                            $('.child[value="' + value + '"]').prop('selected', false);
                        }
                    }
                });
            });
        });
    </script>
</body>
</html>

© www.soinside.com 2019 - 2024. All rights reserved.