Select2 删除所有放第一个标签

Select2 removes all put the first tag

我在 Django 中使用 Select2 建立多对多关系。由于各种验证限制,我发现在将相关对象输入 Select2 标记字段时通过 AJAX 请求创建相关对象最简单。下面是一个最小的例子(和一个 Fiddle)。

HTML:

<select class="js-example-tags form-control" multiple="" tabindex="-1" aria-hidden="true"></select>

有点CSS:

.js-example-tags {
  width: 100%;
}

和 JS:

function register(event) {
  console.log(event);
  if (event.params.data.id == event.params.data.text) {
    $.ajax({
      type: 'POST',
      url: 'https://www.random.org/integers/?num=1&min=0&max=999&col=1&base=10&format=plain&rnd=new',
      success: function(data) {
        $('option[value="' + event.params.data.text + '"').attr('value', data);
      },
      error: function(jqXHR, textStatus, errorThrown) {
        $('option[value="' + event.params.data.id + '"]').remove();
      }
    });
  }
}


$(".js-example-tags").select2({
  tags: true,
  data: [{"text": "Known Author 1", "id": 1}, {"text": "Known Author 2", "id": 2}]
});
$(".js-example-tags").on('select2:select', register);

当用户点击 return:

  1. Select2 应该添加新选项,其中 value = text 作为占位符并且
  2. 触发 select2:select 事件,从而触发 register 函数,
  3. 其 AJAX 调用将(希望)return 新创建的对象 ID,
  4. 用真实值替换之前的选项值。

但显然,不知何故发生了其他事情:第一个标签已正确添加 - 至少从视觉外观来看 - 但是当你添加第二个标签时,它会在按下 return 时消失,并从第三个标签中消失之后,新标签会覆盖第一个标签。

Select2 文档在这一点上很少,因此很可能是使用错误。谢谢!

新解决方案

我找到了[本期评论](https://github.com/select2/select2/issues/3057#issuecomment-77560623 ) 在旧解决方案在某些情况下停止工作后的 Select2 错误跟踪器中。我不知道为什么 selected: true 属性曾经对我有用;也许它只是 似乎 偶然工作。 (New Fiddle.)

function selectOption(select, id) {
  var selectedValues = select.val();
  if (selectedValues == null) {
    selectedValues = new Array();
  }
  selectedValues.push(id);
  select.val(selectedValues).trigger('change');
}

function register(event) {
  if (typeof variable !== event.params &&
      event.params.data.text == event.params.data.id) {
    $.ajax({
      type: 'POST',
      url: 'https://www.random.org/integers/?num=1&min=0&max=999&col=1&base=10&format=plain&rnd=new',
      success: function(data) {
        var select = $(event.target);
        var id = data.replace(/^\s+|\s+$/g, '');
        var text = event.params.data.text;
        select.find('option[data-select2-tag="true"][value="' + text + '"]').remove();
        select.append('<option value="' + id + '">' + text + '</option>');
        selectOption(select, id);
      }
    });
  }
}

var select = $(".js-example-tags");
select.select2({
  tags: true,
  // selectOnClose: true,  // Too much recursion error
  data: [{"text": "Known Author 1", "id": 1}, {"text": "Known Author 2", "id": 2}]
});
select.on('select2:select', register);

额外问题:“是”这个词有什么特别之处,以至于它总是被 Select2 删除?其他典型的停用词不会被删除。


旧解决方案

最后(或到目前为止算作结束)我采用了 Dario 建议的解决方案——在每次输入后完全重新创建 Select2 输入 (Fiddle):

function initSelect2(select) {
  select.find('option[data-select2-tag="true"]').remove();
  select.select2({
    tags: true,
    // selectOnClose: true,  // Too much recursion error
    data: select.data('entries')
  });
}

function register(event) {
  if (typeof variable !== event.params &&
      event.params.data.text == event.params.data.id) {
    var model = $(event.target).data('model');
    $.ajax({
      type: 'POST',
      url: 'https://www.random.org/integers/?num=1&min=0&max=999&col=1&base=10&format=plain&rnd=new',
      success: function(data) {
        var select = $(event.target);
        var entries = select.data('entries');
        entry = {id: data.replace(/^\s+|\s+$/g, ''),
                 text: event.params.data.text,
                 selected: true};
        entries.push(entry);
        select.data('entries', entries);
        initSelect2(select);
        select.parent().find('input.select2-search__field').focus();
      }
    });
  }
}

var select = $(".js-example-tags");
select.data('entries', [{"text": "Known Author 1", "id": 1}, {"text": "Known Author 2", "id": 2}]);
initSelect2(select);
select.on('select2:select', register);

我 运行 遇到的两个问题是:

  1. 该字段失去焦点,需要将其放回 Select2 生成的 input 字段中,并且
  2. 除了新添加的具有正确 ID 的字段外,重新初始化还保留了 data-select2-tag 字段(带有占位符 ID),因此在重新创建 Select2 之前需要清除第一个字段。

这些都在上面的代码中解决了