2012-06-26 4 views
0

Я пытаюсь расширить dijit.form.FilteringSelect с требованием, чтобы все его экземпляры совпадали с вводом независимо от того, где символы находятся в введенном тексте, а также должны игнорировать пробелы и пунктуации (в основном, периоды и тире).Нечеткие совпадения на dijit.form.ComboBox/dijit.form.FilteringSelect Подкласс

Например, если опция «J.P. Morgan», я хотел бы иметь возможность выбрать эту опцию после ввода «JP» или «P Morgan».

Теперь я знаю, что часть о согласовании в любой точке строки может быть выполнена путем передачи в queryExpr: "*${0}*" при создании экземпляра.

Я не понял, как это сделать, чтобы игнорировать пробелы, периоды и тире. У меня есть пример того, где я здесь, - http://jsfiddle.net/mNYw2/2/. Любая помощь будет оценена по достоинству.

ответ

0

Вещь, которую нужно освоить в этом случае - это запросы на выборку магазина. Она вызовет функцию в прикрепленном хранилище, чтобы вытащить любые соответствующие элементы, поэтому, если у вас есть значение, введенное в поле ввода автозаполнения, оно в конечном итоге закончится до похож на это в коде:

var query = { this.searchAttr: this.get("value") }; // this is not entirely accurate 
    this._fetchHandle = this.store.query(query, options); 
    this._fetchHandle.then( showResultsFunction ); 

Таким образом, при определении выбора, переопределения _setStoreAttr, чтобы внести изменения в API магазин запроса

dojo.declare('CustomFilteringSelect', [FilteringSelect], { 
    constructor: function() { 
     //??? 
    }, 
    _setStoreAttr: function(store) { 
      this.inherited(arguments); // allow for comboboxmixin to modify it 
      // above line eventually calls this._set("store", store); 
      // so now, 'this' has 'store' set allready 
      // override here 
      this.store.query = function(query, options) { 
       // note that some (Memory) stores has no 'fetch' wrapper 
      }; 
    } 
}); 

EDIT: переопределение функции queryEngine как против функции запроса

Взгляните на файл SimpleQueryEngine.js под dojo/store/util. Это, по существу, то, что фильтрует полученные Array по данному Stringзапрос от FilteringSelect. Хорошо, это выглядит следующим образом:

var MyEngine = function(query, options) { 
     // create our matching query function 
     switch(typeof query){ 
       default: 
         throw new Error("Can not query with a " + typeof query); 
       case "object": case "undefined": 
         var queryObject = query; 
         query = function(object){ 
           for(var key in queryObject){ 
             var required = queryObject[key]; 
             if(required && required.test){ 
               if(!required.test(object[key])){ 
                 return false; 
               } 
             }else if(required != object[key]){ 
               return false; 
             } 
           } 
           return true; 
         }; 
         break; 
       case "string": 
    /// HERE is most likely where you can play with the reqexp matcher. 
         // named query 
         if(!this[query]){ 
           throw new Error("No filter function " + query + " was found in store"); 
         } 
         query = this[query]; 
         // fall through 
       case "function": 
         // fall through 
     } 
     function execute(array){ 
       // execute the whole query, first we filter 
       var results = arrayUtil.filter(array, query); 
       // next we sort 
       if(options && options.sort){ 
         results.sort(function(a, b){ 
           for(var sort, i=0; sort = options.sort[i]; i++){ 
             var aValue = a[sort.attribute]; 
             var bValue = b[sort.attribute]; 
             if (aValue != bValue) { 
               return !!sort.descending == aValue > bValue ? -1 : 1; 
             } 
           } 
           return 0; 
         }); 
       } 
       // now we paginate 
       if(options && (options.start || options.count)){ 
         var total = results.length; 
         results = results.slice(options.start || 0, (options.start || 0) + (options.count || Infinity)); 
         results.total = total; 
       } 
       return results; 
     } 
     execute.matches = query; 
     return execute; 
}; 

new Store({ queryEngine: MyEngine }); 

когда execute.matches установлен на нижней части этой функции, что происходит в том, что строка вызывается по каждому пункту. Каждый элемент имеет свойство - Select.searchAttr - которое проверено RegExp следующим образом: new RegExp(query).test(item[searchAttr]); или, может быть, немного проще понять; Пункт [searchAttr] .matches (запрос);

У меня нет среды тестирования, но найти встроенный комментарий выше и начать использовать console.debug ..

Пример:

Stpre.data = [ 
    { id:'WS', name: 'Will F. Smith' }, 
    { id:'RD', name:'Robert O. Dinero' }, 
    { id:'CP', name:'Cle O. Patra' } 
]; 
Select.searchAttr = "name"; 
Select.value = "Robert Din"; // keyup->autocomplete->query 

Select.query станет Select.queryExp.replace("${0]", Select.value), в вашем простом queryExp случае, «Роберт Дин» .. Это позволит получить нечеткое и это будет до вас, чтобы заполнить в регулярном выражении, вот что-то, чтобы начать с

query = query.substr(1,query.length-2); // '*' be gone 
var words = query.split(" "); 
var exp = ""; 
dojo.forEach(words, function(word, idx) { 
    // check if last word 
    var nextWord = words[idx+1] ? words[idx+1] : null; 
    // postfix 'match-all-but-first-letter-of-nextWord' 
    exp += word + (nextWord ? "[^" + nextWord[0] + "]*" : ""); 
}); 
// exp should now be "Robert[^D]*Din"; 
// put back '*' 
query = '*' + exp + '*'; 
+0

Спасибо за ваш ответ. Я вижу, как я могу переопределить метод '' 'query''' в магазине, но я не уверен, что мне нужно делать. Я вижу, что аргумент '' 'query''' имеет то, что было напечатано, но аргумент' '' options''' не имеет ничего полезного. Я также не уверен, что нужно вернуть. Вот где я нахожусь - http://jsfiddle.net/mNYw2/4/. –

+0

В рамках пользовательской функции '' 'query''' я вижу, что' '' this.data''' содержит информацию о необходимых мне параметрах, но я до сих пор не знаю, что вернуть. –

+0

После обработки через источник Dojo по умолчанию метод '' 'query''' возвращает' '' QueryResults (this.queryEngine (query, options) (this.data)); '' ', но я до сих пор не знаю, я знаю, как я могу настроить эти результаты, чтобы просто исключить периоды или пробелы ... –

Смежные вопросы