开发者

ExtJs: Search / Filter within a ComboBox

I've the following problem / question in ExtJs 2.3:

I'd like to do a search within a combobox. I'll give you an example:

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);
         }
     }
});

When I would type in an 'a', there only should be 'Paul' and 'Amanda' in the "dropdown". So in other words I'm looking for a solution to filter the data not only by the entries' first letter, but maybe by using something like a regular expression (?) (like in SQL ... LI开发者_运维知识库KE '%a%')...I also would need type of "onKeyDown"-event for my comboBox in order to filter the results on every single letter I add. How can I do that? Any ideas?

Tanks a lot in advance :)

Schildi

PS: Unfortunately I have to use my current version of ExtJs (2.3), so if there's a solution for my problem just in later versions, I would have to look for an other way...


anyMatch: true is all you need. (like in SQL ... LIKE '%a%') as you asked can be done by simply add this.

Example:

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
  }
})


I know this is an old question, but the best answers here recommend overriding doQuery. Overriding private methods should be avoided especially if you are ever going to upgrade. Instead, just add a beforequery listener to prevent doQuery from clearing the filter.

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; 
     }
 }


ExtJS ComboBox has a keydown event (and keyup, and keypress) that you can use for this purpose.

ExtJS SimpleStore also has a filter method that should suit your purpose. You can use it like this (to find values that contain an 'a' character):

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

First parameter is the record field, second is the string/regexpt to look for, third parameter means that filter should match any part of field (instead of just the beginning of the value), and the last value determines the case-sensitivity. You can turn it off, of course, if you like.

All of this applies to ExtJS 2.3.0. Hopefully this will get you started.


This can be done by overriding the doQuery method of combobox.


just remove that lister and override the doQuery method as follows

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();
          }
      }
  };
}


I had a similar requirement in ExtJs4 Check the tweaks in the below link... It worked for me perfectly.

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


I cam across something similar before. I looked into the doQeury function and it would seem to be filtering using the display name, without having set anyMatch parameter in the filter function. In such cases, there are no easy solution but to override doQuery or a create a new user extension. Fortunately, one can be found here

I think this may apply to Ext 2.3 since we recently upgraded, I would seem to have lost my documentation links. But that is how I would go about it.


You can use this approach also: provide a listener to combobox and catch this event:

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


You may use the keyup event. I did not get it working with this.getValue(). had to use 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
                    });
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜