Выберите2 изменения предметов динамически

У меня есть два выбора, которые связаны между собой: каждое значение первого выбора определяет, какие элементы будут отображаться во втором выборе.

Значения второго выбора сохраняются в двумерном массиве:

[ [{"id":1,"text":"a"}, {"id":2,"text":"b"},...],
  [{"id":"1a","text":"aa"},{"id":"1b","text":"ba"},...],
  ...
]

Первое значение выбора определяет индекс, который будет использоваться для заполнения второго выбора. Поэтому в первом событии 'change' я должен иметь возможность изменять элементы, которые содержит select-two.

Чтение документации. Я думаю, что мне нужно использовать опцию "data"... но не уверен, как в примере загружаются данные массива при инициализации, и, похоже, он не работает, если я пытаюсь сделать то же самое после инициализации.

HTML

Attribute:
<select name="attribute" id="attribute">
    <option value="0">Color</option>
    <option value="1">Size</option>
</select>

Value:
<select name="value" id="value"></select>

<script>
   var data = [ [{"id":1,"text":"black"}, {"id":2,"text":"blue"},...],
                [{"id":"1","text":"9"},{"id":"1","text":"10"},...],
              ];
   $('#attribute').select2().bind('change', function(){
      // Here I need to change `#value` items.
      $('#value').select2('data',data[$(this).val()]);  // This does not work
   );

   $('#value').select2();
</script>

8 ответов

Решение

Я сделал для вас пример, показывающий, как это можно сделать.

Обратите внимание на js, но я также изменил #value на элемент input

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

и что я запускаю change событие для получения начальных значений

$('#attribute').select2().on('change', function() {
    $('#value').select2({data:data[$(this).val()]});
}).trigger('change');

Пример кода

Редактировать:

В текущей версии select2 атрибут class передается из скрытого ввода в корневой элемент, созданный select2, даже select2-offscreen Класс, который позиционирует элемент далеко за пределы страницы.

Чтобы решить эту проблему, все, что нужно, это добавить removeClass('select2-offscreen') перед применением select2 второй раз для того же элемента.

$('#attribute').select2().on('change', function() {
    $('#value').removeClass('select2-offscreen').select2({data:data[$(this).val()]});
}).trigger('change');

Я добавил новый пример кода для решения этой проблемы.

Я успешно использую следующее для динамического обновления параметров:

$control.select2('destroy').empty().select2({data: [{id: 1, text: 'new text'}]});

Попробуйте использовать свойство триггера для этого:

$('select').select2().trigger('change');

Я исправляю отсутствие библиотеки примера здесь:

<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/3.5.2/select2.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/3.5.2/select2.js">

http://jsfiddle.net/bbAU9/328/

Для v4 это известная проблема, которая не будет решена в 4.0, но есть обходной путь. Проверьте https://github.com/select2/select2/issues/2830

В моем проекте я использую следующий код:

$('#attribute').select2();
$('#attribute').bind('change', function(){
    var $options = $();
    for (var i in data) {
        $options = $options.add(
            $('<option>').attr('value', data[i].id).html(data[i].text)
        );
    }
    $('#value').html($options).trigger('change');
});

Попробуйте закомментировать часть select2. Остальная часть кода все еще будет работать.

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

$('#attribute').select2({
    data: data
});

$("#attribute").select2().val(1).trigger('change');

если вы ищете код, который изменяет другие данные раскрывающегося списка, извлекая данные со стороны сервера (Api). Вы должны попробовать это.

      $('#attribute').on('change', function (e) {
        $.post("../api", { id: e.val }).done(resp => {
            $("#value").select2('destroy').empty();
            resp.map(o => $("#value").append("<option value=\"" + o.Value + "\">" + o.Text + "</option>"));
            $("#value").select2();
        });
    });
Другие вопросы по тегам