无法在Select2下拉菜单中选择项目

user70192:

我正在使用Select2(版本3.5.1)的应用程序。用于设置此下拉列表/自动填充字段的HTML如下所示:

<input id="mySelect" class="form-control" type="hidden">

form-control此代码段中类来自Bootstrap。我正在使用以下方法从JavaScript初始化此字段:

function getItemFormat(item) {
  var format = '<div>' + item.ItemName + '</div>';
  return format;
}

$(function() {
  $('#mySelect').select2({
    minimumInputLength: 5,
    placeholder: 'Search for an item',
    allowClear: true,
    ajax: {
      url: '/api/getItems',
      dataType: 'json',
      quietMillis: 250,
      data: function (term, page) {
        return {
          query: term
        };
      },
      results: function (data, page) {
        return { results: data, id: 'ItemId', text: 'ItemText' };
      }
    },
    formatResult: getItemFormat,
    dropdownCssClass: "bigdrop",
    escapeMarkup: function (m) { return m; }
  });
});

加载我的选择字段后,它会成功呈现。一旦我键入至少第五个字符,它将成功从服务器中提取项目并将其列为选项。但是,如果我尝试选择其中之一,则什么也不会发生。下拉弹出窗口保持打开状态。什么都没有放在实际的领域。JavaScript控制台中没有错误。就像我没有点击任何东西一样。

另外,我注意到将鼠标放在某项上或尝试使用箭头键浏览选项列表时,不会突出显示任何内容。

我究竟做错了什么?

吖奇说-何魏奇Archy Will He :

怎么了:

默认情况下,results您要返回的对象ajax.results应该是此结构中的一个数组[{id:1,text:"a"},{id:2,text:"b"}, ...]

  results: function (data, page) {
    var array = data.results; //depends on your JSON
    return { results: array };
  }


Select2.js中,它实际上指出:

* @param options.results a function(remoteData, pageNumber, query) that converts data returned form the remote request to the format expected by Select2.
*      The expected format is an object containing the following keys:
*      results array of objects that will be used as choices
*      more (optional) boolean indicating whether there are more results available
*      Example: {results:[{id:1, text:'Red'},{id:2, text:'Blue'}], more:true}


阅读源代码,我们可以看到ajax.results在AJAX上成功调用:

   success: function (data) {
                        // TODO - replace query.page with query so users have access to term, page, etc.
                        // added query as third paramter to keep backwards compatibility
                        var results = options.results(data, query.page, query);
                        query.callback(results);
                    }


因此ajax.results,实际上,这只是一个功能,您可以[{id:a,text:"a"},{id:b,text:"b"}, ...]在将数据传递给之前将数据格式化为适当的结构(例如query.callback

 callback: this.bind(function (data) {

                    // ignore a response if the select2 has been closed before it was received
                    if (!self.opened()) return;


                    self.opts.populateResults.call(this, results, data.results, {term: term, page: page, context:context});
                    self.postprocessResults(data, false, false);

                    if (data.more===true) {
                        more.detach().appendTo(results).html(self.opts.escapeMarkup(evaluate(self.opts.formatLoadMore, self.opts.element, page+1)));
                        window.setTimeout(function() { self.loadMoreIfNeeded(); }, 10);
                    } else {
                        more.remove();
                    }
                    self.positionDropdown();
                    self.resultsPage = page;
                    self.context = data.context;
                    this.opts.element.trigger({ type: "select2-loaded", items: data });
                })});


query.callback最终要做的是正确设置逻辑,以便在选择其中一项并触发时一切正常.selectChoice

selectChoice: function (choice) {

            var selected = this.container.find(".select2-search-choice-focus");
            if (selected.length && choice && choice[0] == selected[0]) {

            } else {
                if (selected.length) {
                    this.opts.element.trigger("choice-deselected", selected);
                }
                selected.removeClass("select2-search-choice-focus");
                if (choice && choice.length) {
                    this.close();
                    choice.addClass("select2-search-choice-focus");
                    this.opts.element.trigger("choice-selected", choice);
                }
            }
        } 


因此,如果存在某种错误配置(例如results,结构不正确),导致在调用该类之前.select2-search-choice-focus不将其添加到DOM元素中.selectChoice,则会发生以下情况:

下拉弹出窗口保持打开状态。什么都没有放在实际的领域。JavaScript控制台中没有错误。就像我没有点击任何东西一样。


解决方案

有许多解决方案。其中之一当然是在中进行一些数组键操作ajax.results

  results: function (data, page) {
  //data = { results:[{ItemId:1,ItemText:"a"},{ItemId:2,ItemText:"b"}] };
    var array = data.results;
    var i = 0;
    while(i < array.length){
        array[i]["id"] = array[i]['ItemId'];
        array[i]["text"] = array[i]['ItemText'];
        delete array[i]["ItemId"];
        delete array[i]["ItemText"];
    i++;
    }
    return { results: array };
  }

但是您可能会问:为什么数组中的id必须为“ id”,文本必须为“ text”?

[{id:1,text:"a"},{id:2,text:"b"}] 

数组可以改成这种结构吗?

[{ItemId:1,ItemText:"a"},{ItemId:2,ItemText:"b"}]

答案是肯定的。您只需要用自己的函数覆盖idtext函数即可。


这里是原来的功能.selecte2Select2.js

    id: function (e) { return e == undefined ? null : e.id; },
    text: function (e) {
      if (e && this.data && this.data.text) {
        if ($.isFunction(this.data.text)) {
          return this.data.text(e);
        } else {
          return e[this.data.text];
        }
      } else {
        return e.text;
      }
    },


要覆盖它们,只需在要传递给的对象内添加自己的函数.selecte2

$('#mySelect').select2({
id: function (item) { return item.ItemId },
text: function (item) { return item.ItemText }
......
});

更新

发生了什么事:

但是,列表关闭后,所选项目的文本不会出现在字段中。

这意味着.selectChoice已成功执行。现在问题出在.updateSelection在源代码中:

   updateSelection: function (data) {

        var container=this.selection.find(".select2-chosen"), formatted, cssClass;

        this.selection.data("select2-data", data);

        container.empty();
        if (data !== null) {
            formatted=this.opts.formatSelection(data, container, this.opts.escapeMarkup);
        }
        if (formatted !== undefined) {
            container.append(formatted);
        }
        cssClass=this.opts.formatSelectionCssClass(data, container);
        if (cssClass !== undefined) {
            container.addClass(cssClass);
        }

        this.selection.removeClass("select2-default");

        if (this.opts.allowClear && this.getPlaceholder() !== undefined) {
            this.container.addClass("select2-allowclear");
        }
    }


从这里我们可以看到,在将相应的文本字符串放入输入之前,它将调用formatSelection

formatSelection: function (data, container, escapeMarkup) {
            return data ? escapeMarkup(this.text(data)) : undefined;
        },

更新:解决方案

以前,我认为this.text(data)可以通过text: funcion(item){ ... }包含参数来覆盖它,但可悲的是它不能那样工作。

因此,要在字段中正确呈现文本,您应该formatSelection这样做

$('#mySelect').select2({
id: function (item) { return item.ItemId },
formatSelection: function (item) { return item.ItemText }
//......
});

而不是尝试覆盖text(应该具有相同的效果,但是库中尚不支持/实现这种覆盖方式)

$('#mySelect').select2({
id: function (item) { return item.ItemId },
text: function (item) { return item.ItemText }  //this will not work.
//......
});

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

无法从特定的下拉菜单中选择项目(文本)?

Select2下拉菜单,但允许用户使用新值吗?

Select2在选择上打开下拉菜单

禁用模式下的Select2下拉菜单

Select2下拉菜单允许用户输入新的值

Select2:防止Select2下拉菜单集中于点击

如何在select2下拉菜单中换行?

要以逗号分隔的Select2下拉菜单的选定文本。

在yii2的select2下拉菜单中设置默认值

从android应用中的下拉菜单中选择项目后,元素不可见

在选择另一个select2下拉菜单时重置一个select2下拉菜单的元素

在下拉菜单中显示ScriptableObjects,然后在Unity中选择项目

根据第一个值在第二个Select2下拉菜单中显示选项

从select2下拉列表中选择某个选项后触发动作

无法从语义用户界面反应搜索菜单内下拉菜单/ Formik中选择项目

如何捕捉select2下拉菜单的宽度?

为什么select2下拉菜单仅显示在表格的第一行?

从下拉菜单中选择项目

Select2下拉选择框的样式

select2下拉菜单中的fadeIn / fadeOut效果

MVC 5下拉列表,用于选择项目

无法从下拉菜单中选择一个选项,因为我有2个下拉菜单,且具有相同的'<select class =

无法从select2下拉列表中选择结果

使select2下拉菜单仅在键入至少一个字母后才下拉

如何使用从Select2下拉列表中选择的选项来触发jQuery?

Angular 6 更新 *ngFor 数据,从下拉菜单中选择项目

在下拉菜单中选择项目时如何显示内容?

按下选项卡时如何在焦点上打开select2下拉菜单

带硒的select2下拉菜单