使用ajax选择2个默认选项

时间:2015-10-12 12:07:25

标签: jquery-select2 jquery-select2-4

我有下一个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选项为空,只显示提示&#34;请输入1个或多个字符&#34;。

甚至不清楚是否有可能做到,谢谢。

UPD select2 removes default options when using ajax

相关

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

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

2 个答案:

答案 0 :(得分:2)

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

$.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,如果你这样做,请使用它来要求适配器。

答案 1 :(得分:1)

如果您想要一个始终可见的<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代码,它在我身边发挥作用,但有可能在它工作之前必须设置其他一些东西(几个月前我写了代码,我记得我有如果这种方法不起作用,请通知我,我将查看我的代码,看看我是如何做到的。