使用 ajax 选择 2 个默认选项

Select2 default options with 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 选项为空,仅显示提示 "Please enter 1 or more characters"。

目前还不清楚是否可行,谢谢。

UPDselect2 removes default options when using ajax

有关

Select-2 在使用 ajax 适配器时删除选项。

UPD2github问题https://github.com/select2/select2/issues/3828

如果您想要一个始终可见的 <optgroup>,无论客户端搜索什么,并且在其下方,在另一个 <optgroup> 中,您想要查看搜索结果,试试这个输出:

在您处理客户端输入的搜索查询的服务器端脚本中,您应该 return a json_encoded array 包含您想要显示的项目在 select 框中。而不是这个,尝试做这样的事情:

** 根据您在问题评论中的要求修改代码**

$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

我正在使用一个类似的代码,它在我这边运行得很好,但在它运行之前可能还需要设置一些其他的东西(我几个月前写的代码,我记得我很难弄清楚这一点),如果这种方法不起作用,请通知我,我会查看我的代码,看看我是如何做到的。

在这种情况下可能的(不幸的是,我认为唯一的)解决方案是编写自定义适配器。 像这样:

$.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

此适配器首先分析查询词。如果 term 长于 minimumInputValue,AjaxAdapter 将被启动。否则,defaultResults 将传递给回调。

要使用此适配器,只需将其传递给 select2 选项:

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

我没有使用 requireJS 或 AMD,如果你使用,请使用它来要求适配器。