【问题标题】:ExtJs: Search / Filter within a ComboBoxExtJs:在组合框中搜索/过滤
【发布时间】:2011-04-01 09:00:49
【问题描述】:

我在 ExtJs 2.3 中有以下问题/问题:

我想在组合框中进行搜索。 我给你举个例子:

Ext.comboData.names = [['Peter', 'Paul', 'Amanda']];

var store = new Ext.data.SimpleStore({
     fields: ['name'],
     data: Ext.comboData.names
});


var combo = new Ext.form.ComboBox({
     name: '...',
     id: '...',
     store: store,
     displayField: 'name',
     typeAhead: true,
     mode: 'local',
     forceSelection: false,
     triggerAction: 'all',
     emptyText: '-',
     selectOnFocus: true,
     applyTo: '...',
     hiddenName: '...', 
     valueField: 'name'
     enableKeyEvents: true,
     lastQuery: '',
     listeners: {
         'keyup': function() {
               this.store.filter('name', this.getRawValue(), true, false);
         }
     }
});

当我输入“a”时,“下拉菜单”中应该只有“Paul”和“Amanda”。所以换句话说,我正在寻找一种解决方案,不仅可以通过条目的第一个字母过滤数据,还可以使用正则表达式(?)之类的东西(比如在 SQL ... LIKE '%a%' 中) ...我还需要我的组合框的“onKeyDown”事件类型,以便过滤我添加的每个字母的结果。 我怎样才能做到这一点?有什么想法吗?

提前很多坦克:)

谢尔迪

PS:不幸的是,我必须使用我当前版本的 ExtJs (2.3),所以如果在以后的版本中有解决我的问题的方法,我将不得不寻找其他方法......

【问题讨论】:

    标签: extjs combobox filter


    【解决方案1】:

    anyMatch: true 就是您所需要的。 (就像在 SQL ... LIKE '%a%' 中一样)你可以通过简单地添加这个来完成。

    示例:

    Ext.create('Ext.form.ComboBox', {
      name: 'name',
      anyMatch: true,
      allowBlank: true,
      editable : true,
      typeAhead: true,
      transform: 'stateSelect',
      forceSelection: true,
      queryMode: 'local',
      displayField: 'name',
      valueField: 'id',
      selectOnFocus: true,
      triggerAction: 'all',
      store: {
        fields: ['id', 'name'],
        proxy: {
          type: 'ajax',
          url: '/user'
        },
        autoLoad: true,
        autoSync: true
      }
    })
    

    【讨论】:

    【解决方案2】:

    我知道这是一个老问题,但这里的最佳答案建议覆盖 doQuery。应避免覆盖私有方法,尤其是在您要升级时。相反,只需添加一个beforequery 侦听器以防止doQuery 清除过滤器。

    listeners: {
         'keyup': function() {
               this.store.filter('name', this.getRawValue(), true, false);
         },
         'beforequery': function(queryEvent) {
               queryEvent.combo.onLoad();
               // prevent doQuery from firing and clearing out my filter.
               return false; 
         }
     }
    

    【讨论】:

    • 谢谢!非常简洁的解决方案。但我必须在“beforequery”监听器中添加 queryEvent.combo.expand() 以使其正常工作。
    • 使用这段代码时,一旦我开始输入搜索内容,我最终将失去使用箭头键导航组合框的能力。
    【解决方案3】:

    ExtJS ComboBox 有一个 keydown 事件(以及 keyupkeypress),您可以将其用于此目的。

    ExtJS SimpleStore 也有一个 filter 方法,应该适合您的目的。您可以像这样使用它(查找包含“a”字符的值):

    store.filter('name', 'a', true, true)
    

    第一个参数是记录字段,第二个是要查找的字符串/正则表达式,第三个参数表示过滤器应该匹配字段的任何部分(而不仅仅是值的开头),最后一个值决定大小写-灵敏度。当然,如果您愿意,可以将其关闭。

    所有这些都适用于 ExtJS 2.3.0。希望这能让你开始。

    【讨论】:

    • 嘿,非常感谢您的回答! :) 我没有为我的组合框添加一个监听器(见上文),但我的问题是,当我输入一些字母时,商店仍然没有被过滤:( 我的代码还有什么问题吗?
    • 我不确定getRawValue() 是否是在活动期间获取用户输入的正确方法。我建议您使用 Firebug 调试事件(设置断点),以查看您传递给过滤器的值。还要检查作为参数传入的EventObject e
    • 我同意汤米的观点。萤火虫规则。那是我的MO当我开始调查这些问题时。为了好玩,试着在你的事件中传递一些额外的参数,看看你也可以访问什么。有时您可以找到金块。
    【解决方案4】:

    这可以通过覆盖组合框的 doQuery 方法来完成。

    【讨论】:

      【解决方案5】:

      只需删除该列表并覆盖 doQuery 方法,如下所示

      if(combo!=null){
          combo.doQuery = function(q, forceAll){
        q = Ext.isEmpty(q) ? '' : q;
        var qe = {
            query: q,
            forceAll: forceAll,
            combo: this,
            cancel:false
        };
        if(this.fireEvent('beforequery', qe)===false || qe.cancel){
            return false;
        }
        q = qe.query;
        forceAll = qe.forceAll;
        if(forceAll === true || (q.length >= this.minChars)){
            if(this.lastQuery !== q){
                this.lastQuery = q;
                if(this.mode == 'local'){
                    this.selectedIndex = -1;
                    if(forceAll){
                        this.store.clearFilter();
                    }else{
                        this.store.filter(this.displayField, q, true,false); // supply the anyMatch option
                        }
                        this.onLoad();
                    }else{
                        this.store.baseParams[this.queryParam] = q;
                        this.store.load({
                            params: this.getParams(q)
                        });
                        this.expand();
                    }
                }else{
                    this.selectedIndex = -1;
                    this.onLoad();
                }
            }
        };
      }
      

      【讨论】:

        【解决方案6】:

        我在 ExtJs4 中也有类似的要求 检查以下链接中的调整...它对我来说非常有效。

        http://atechiediary.blogspot.in/2013/06/first-page-extjs-containslike-search-in.html

        【讨论】:

          【解决方案7】:

          我以前遇到过类似的事情。我查看了doQeury function,它似乎是在使用显示名称进行过滤,而没有在过滤器函数中设置anyMatch 参数。在这种情况下,没有简单的解决方案,只能覆盖 doQuery 或创建新的用户扩展。幸好可以找到here

          我认为这可能适用于 Ext 2.3,因为我们最近升级了,我似乎丢失了我的文档链接。但这就是我的想法。

          【讨论】:

            【解决方案8】:

            您也可以使用这种方法: 为组合框提供侦听器并捕获此事件:

             change: function() {
                                    //debugger
                                    var store = this.getStore();
                                    store.clearFilter();
                                    store.filter({
                                        property: 'deviceName',//your property
                                        anyMatch: true,
                                        value   : this.getValue()
                                    });
                                }
            

            【讨论】:

              【解决方案9】:

              您可以使用 keyup 事件。我没有让它与 this.getValue() 一起工作。不得不使用 this.getRawValue()

              keyup: {fn:function() {
                                      var store1 = ContractStore;//store object
                                      store1.clearFilter();
                                      store1.filter({
                                      property: 'modificationnumber',//your displayField
                                      anyMatch: true,
                                      value   : this.getRawValue(),
                                      exactMatch: false,
                                      caseSensitive: false
                                  });
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2012-11-16
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2018-03-14
                • 1970-01-01
                相关资源
                最近更新 更多