ExtJs: поиск / фильтрация внутри ComboBox - PullRequest
4 голосов
/ 01 апреля 2011

У меня следующая проблема / вопрос в 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);
         }
     }
});

Когда я набираю «а», в «выпадающем списке» должны быть только «Пол» и «Аманда». Другими словами, я ищу решение для фильтрации данных не только по первой букве записей, но, возможно, с помощью чего-то вроде регулярного выражения (?) (Как в SQL ... LIKE '% a%') ... Мне также понадобится тип события "onKeyDown" для моего комбинированного списка, чтобы отфильтровать результаты по каждой добавляемой букве. Как я могу это сделать? Есть идеи?

Танки много заранее:)

Schildi

PS: К сожалению, мне приходится использовать мою текущую версию ExtJs (2.3), поэтому, если есть решение моей проблемы только в более поздних версиях, мне придется искать другой путь ...

Ответы [ 8 ]

8 голосов
/ 06 января 2012

Я знаю, что это старый вопрос, но лучшие ответы здесь рекомендуют переопределить 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; 
     }
 }
6 голосов
/ 02 августа 2016

anyMatch: true - это все, что вам нужно. (как в SQL ... как '% 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 голосов
/ 01 апреля 2011

ExtJS ComboBox имеет событие keydownkeyup, и keypress), которое вы можете использовать для этой цели.

ExtJS SimpleStore также имеет метод filter, который должен соответствовать вашим целям. Вы можете использовать его следующим образом (чтобы найти значения, содержащие символ «а»):

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

Первый параметр - это поле записи, второй - строка / регулярное выражение для поиска, третий параметр означает, что фильтр должен соответствовать любой части поля (а не только началу значения), а последнее значение определяет регистр чувствительность. Вы можете выключить его, если хотите.

Все это относится к ExtJS 2.3.0. Надеюсь, это поможет вам.

1 голос
/ 08 июня 2013

У меня было похожее требование в ExtJs4. Проверьте настройки в приведенной ниже ссылке ... У меня это отлично сработало.

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

1 голос
/ 28 сентября 2011

просто удалите этот список и переопределите метод 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();
          }
      }
  };
}
1 голос
/ 29 июня 2011

Это можно сделать путем переопределения метода combQox doQuery.

0 голосов
/ 16 февраля 2018

Вы также можете использовать этот подход: предоставить слушателю комбобокс и перехватить это событие:

 change: function() {
                        //debugger
                        var store = this.getStore();
                        store.clearFilter();
                        store.filter({
                            property: 'deviceName',//your property
                            anyMatch: true,
                            value   : this.getValue()
                        });
                    }
0 голосов
/ 15 апреля 2011

Я наткнулся на нечто подобное раньше. Я посмотрел на функцию doQeury , и она, казалось бы, фильтрует по отображаемому имени, не задав параметр anyMatch в функции фильтра. В таких случаях нет простого решения, кроме как переопределить doQuery или создать новое расширение пользователя. К счастью, можно найти здесь

Я думаю, что это может относиться к Ext 2.3, так как мы недавно обновились, я, похоже, потерял ссылки на документацию. Но я бы так и поступил.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...