Select2: добавить и выбрать ручные значения при использовании источника данных ajax

Я хочу добиться следующего сценария с select2(4.0.0) и jquery(2.1.4):

  • У меня есть поле выбора, которое берет данные из внешнего источника (конечная точка на сервере приложений Java)
  • Пользователь может выбрать одно из возвращаемых значений или придумать собственное значение
  • Теперь, когда пользователь отправляет форму и проверка на стороне сервера завершается неудачей, я хотел бы отобразить форму со всеми значениями, предоставленными ранее пользователем, поэтому в поле выбора должно быть значение, отправленное на сервер.

Чтобы достичь этого

  • Я использую Ajax от выбора для запроса данных с сервера
  • Я использую createTag, чтобы позволить пользователю создавать свои собственные значения
  • Я хотел использовать initSelection, чтобы предварительно заполнить selectbox значением, ранее добавленным пользователем.

Мой код выглядит так:

$("select[name='serie']").select2({
    ajax: {
        url: "http://javaendpoit/serie/filter",
        dataType: 'json',
        delay: 250,
        data: function (params) {
          return {
            name: params.term,
            page: params.page
          };
        },
        processResults: function (data, page) {
          return {
            results: $.map(data, function (item) {
              return {
                text: item.name,
                name: item.name,
                id: item.name
              }
            })
          };
        },
        cache: true
      },
      escapeMarkup: function (markup) { return markup; },
      minimumInputLength: 2,
      templateResult: formatRepo,
      templateSelection: formatRepoSelection,
      tags: true,
      createTag: function (tag) {
        return {
          id: tag.term,
          text: tag.term,
          name: tag.term,
          isNew : true
        };
      },
      /* below part is rendered by jsp so that it has the value from previous form submission; if it is initial form render the below part is not included */
      initSelection : function (element, callback) {
            callback({id:"Name",name:"Name","text":"Name"});
      }   
    });

 function formatRepo (serie) {
        if (serie.loading) return serie.text;
        var markup = '<div class="clearfix">' +
        '<div clas="col-sm-10">' +
        '<div class="clearfix">' +
        '<div class="col-xs-12">' + serie.name + '</div>' +
        '</div>';
        markup += '</div></div>';
        return markup;
  }

  function formatRepoSelection (serie) {
    return serie.name;
  }

Это работает просто отлично. Это означает, что после отправки я вижу значение Имя в поле выбора и это выбранное значение. Тем не менее, если я попытаюсь отправить эту форму еще раз, значение отсутствует в запросе.

Как предложено в числе тем здесь, я добавил следующую строку (см. Последнюю строку).

  /* [...] */
  initSelection : function (element, callback) {
        callback({id:"Name",name:"Name","text":"Name"});
  }   
}).select2("val","Name");

Но после добавления этого значения имя даже не отображается в поле select2.

Я пытался исправить это в течение нескольких часов, но почему-то не могу найти правильное решение. Могу поспорить, что мне не хватает некоторых базовых вещей. Пожалуйста, помогите!

--- [РЕДАКТИРОВАТЬ]

После добавления данных я могу видеть значение Name даже при установке значения с помощью val, тем не менее, если я повторно отправляю форму, это значение все еще отсутствует в запросе.

.select2('data',{id:"Name",name:"Name","text":"Name"})
.select2('val', "Name")

--- [РЕДАКТИРОВАТЬ 2]

В html я использую select для создания этого элемента.

<select class="form-control" name="serie"></select>

2 ответа

Решение

Благодаря Кевину я смог разгадать загадку. Так что в конечном итоге я отказался от использования initSelection. Вместо этого я просто заполнил тег выбора параметрами, которые следует выбрать.

<select class="form-control" id="author" name="author" multiple="multiple">
  <option value="name" selected="selected">name</option>
</select>

Удален initSelection из определения select2

$("select[name='author']").select2({
    ajax: {
        url: "http://javaendpoit/serie/filter",
        dataType: 'json',
        delay: 250,
        data: function (params) {
            return {
                name: params.term,
                page: params.page
            };
        },
        processResults: function (data, page) {
            return {
                results: $.map(data, function (item) {
                    return {
                        text: item.name,
                        name: item.name,
                        id: item.name
                    }
                })
            };
        },
        cache: true
    },
    escapeMarkup: function (markup) {
        return markup;
    },
    minimumInputLength: 1,
    templateResult: formatRepo,
    templateSelection: formatRepoSelection,
    tags: true,
    createTag: function (tag) {
        return {
            id: tag.term,
            text: tag.term,
            name: tag.term,
            isNew: true
        };
    }
});

И изменил formatRepoSelection для работы со значениями без атрибута name.

function formatRepoSelection(serie) {
    if (serie.name === undefined) {
        return serie.text;
    } else {
        return serie.name;
    }
}

Я думаю, что я не мог использовать атрибут имени в formatRepo и мог удалить предложение if для formatRepoSelection. Но это только незначительное исправление.

Мне удается сделать это с Select2 версии 4.0.2, как это:

$("select[name='serie']").data('select2')
    .dataAdapter.select({
        id:"Name",
        name:"Name",
        "text":"Name"
    });
Другие вопросы по тегам