Select2 параметры по умолчанию с ajax

у меня есть следующая структура html

<select class="change_item_dropdown_ajax form-control" id="item_id" name="item_id" onchange="updateData(this, this.value, 16)" >
<optgroup label="System Data">
  <option value="17">Test</option>
  <option selected="selected" value="18">System</option>
</optgroup>
</select>

в JavaScript

 $(".change_item_dropdown_ajax").select2({
        ajax: {
            url: "get_user_items",
            dataType: 'json',
            delay: 250,
            theme: "classic",
            data: function (params) {
                return {
                    q: { name_contains: params.term } // search term
                };
            },
            processResults: function (data) {
                return {
                    results: data
                };
            },
            cache: true
        },
        allowClear: true,
        placeholder: '--- Please select item ---',
        minimumInputLength: 1
    });

Я хочу, чтобы клиент мог видеть некоторые системные параметры по умолчанию с элементами <optgroup label="System Data">, но также добавить возможность поиска ajax запросов по своим собственным элементам.

однако после привязки select2 он не показывает <optgroup label="System Data">...</optgroup>,

параметры select2 пусты, и он отображает только подсказку "пожалуйста, введите 1 или более символов".

это даже не ясно, если это можно сделать, спасибо.

UPD Связано с select2 удаляет параметры по умолчанию при использовании ajax

Select-2 удаляет параметры при использовании адаптера ajax.

UPD2 выпуск github https://github.com/select2/select2/issues/3828

2 ответов


если вы хотите иметь <optgroup> который всегда виден, независимо от того, что ищет клиент, и ниже этого, в другом <optgroup>, вы хотите увидеть результаты поиска, попробуйте это:

в скрипте на стороне сервера, где вы обрабатываете поисковый запрос, введенный клиентом, вы должны вернуть json_encoded array С элементами, которые вы хотите отобразить в поле выбора. Вместо этого, попробуйте сделать что-то вроде этого:

** ИЗМЕНЕННЫЙ КОД НА ВАШ ЗАПРОС В КОММЕНТАРИИ К ВОПРОСУ**

$q=$_REQUEST['q']; //the query string passed, note, that if you have minimumInputLength set, until that inputLength is reached, this part of the code won't run, so if you require the minimumInputLength, you should play with the templateResult option of select2
if (empty($q)) {
   $results=array();
   $result[0]=array(); //an optgroup to display when no query was sent
   $result[0]['text']='System Data';
   $result[0]['children']=array();
   // populate your first optgroup here, using the format which you are sending to select2.
} else {    
   $result[0]=array(); //an optgroup for results for the users searches
   $result[0]['text']='User results';
   $result[0]['children']=array();
   //populate the children array with the search related results
}

// json_encode the $result array, and return it

Я использую simmilar-код, который работает безупречно на моей стороне, но возможно, что некоторые другие вещи должны быть настроены, прежде чем он будет работать(я написал код несколько месяцев назад, и я помню, что мне было довольно трудно понять это), если этот подход не работает, сообщите мне, и я посмотрю в свой код, чтобы увидеть, как я это сделал.


возможное (и, к сожалению, я думаю, единственное) решение в этом случае-написать пользовательский адаптер. Что-то вроде этого:--3-->

$.fn.select2.amd.define('select2/data/extended-ajax',['./ajax','../utils','jquery'], function(AjaxAdapter, Utils, $){

  function ExtendedAjaxAdapter ($element,options) {
    //we need explicitly process minimumInputLength value 
    //to decide should we use AjaxAdapter or return defaultResults,
    //so it is impossible to use MinimumLength decorator here
    this.minimumInputLength = options.get('minimumInputLength');
    this.defaultResults     = options.get('defaultResults');

    ExtendedAjaxAdapter.__super__.constructor.call(this,$element,options);
  }

  Utils.Extend(ExtendedAjaxAdapter,AjaxAdapter);

  //override original query function to support default results
  var originQuery = AjaxAdapter.prototype.query;

  ExtendedAjaxAdapter.prototype.query = function (params, callback) {
    var defaultResults = (typeof this.defaultResults == 'function') ? this.defaultResults.call(this) : this.defaultResults;
    if (defaultResults && defaultResults.length && (!params.term || params.term.length < this.minimumInputLength)){
      var processedResults = this.processResults(defaultResults,params.term);
      callback(processedResults);
    }
    else {
      originQuery.call(this, params, callback);
    }
  };

  return ExtendedAjaxAdapter;
});

https://gist.github.com/govorov/3ee75f54170735153349b0a430581195

этот адаптер сначала анализирует термин запроса. AjaxAdapter будет запущен, если срок больше, чем minimumInputValue. В противном случае defaultResults будет передан обратному вызову.

чтобы использовать этот адаптер, просто передайте это select2 опции:

dataAdapter: $.fn.select2.amd.require('select2/data/extended-ajax')

я не использую requireJS или AMD, если вы это делаете, используйте его для требования адаптера.