この場合に習得すべきことは、ストア フェッチ クエリ文字列です。一致するアイテムを引き出すために、接続されたストアの関数が呼び出されるため、自動入力入力フィールドに値が入力されている場合、最終的にはこのようになります。コードで:
var query = { this.searchAttr: this.get("value") }; // this is not entirely accurate
this._fetchHandle = this.store.query(query, options);
this._fetchHandle.then( showResultsFunction );
そのため、select を定義するときは、_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 関数をオーバーライドします
dojo/store/util の下にあるファイル SimpleQueryEngine.js を見てください。これは基本的に、からの特定のクエリで受信した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]);
ます。item[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 の場合は ' Robert Din ' になります。これはあいまいになり、正規表現を入力するのはあなた次第です。
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 + '*';