AngularJSでは、filterを利用すれば簡単にデータの絞り込み機能が実装できる。
<tbody ng-repeat="item in items | filter:searchText">
<tr>
<td>{{item.taskName}}</td>
<td>{{item.priority}}</td>
</tr>
</tbody>
KnockoutJSでは同様の機能は存在しないようなので、独自で実装をしてみた。
ViewModelの定義
- 検索キーワード項目として、filterTextを定義
- 一覧表示データとして、itemsを定義
- 絞り込み処理結果として、filteredItemsを定義
function TestappViewModel(){
var self = this;
self.filterText = ko.observable('');
self.items = ko.observableArray([
{taskName:"AAAAA",priority:"Low"},
{taskName:"BBB",priority:"High"},
{taskName:"CCC",priority:"High"}
]);
self.filteredItems = ko.computed(function() {
var filter = self.filterText().toLowerCase();
if (!filter) {
return self.items();
} else {
return ko.utils.arrayFilter(self.items(), function(item) {
return item.taskName.toLowerCase().indexOf(filter)!== -1;
});
}
}, self);
}
ko.applyBindings(new TestappViewModel());
filteredItemsでは、ko.utils.arrayFilterを使用して、条件に一致する配列のみに絞り込んでいる。
1. filterTextが未入力なら、itemsの配列をそのまま返す。
2. taskNameに、filterTextの値が含まれていれる配列を返す。
taskNameだけではなく、すべての項目を対象とする場合は、ko.utils.arrayFilter内を以下のように記載する。
return ko.utils.arrayFilter(self.items(), function(item) {
for (var i in item) {
if(item[i].toLowerCase().indexOf(filter)!== -1){
return true;
}
}
return false;
});
HTML
- 検索キーワード入力欄に、keydownイベントを付与。
- 一覧表示部には、絞り込み処理結果であるfilteredItemsをbind
Search Keyword: <input data-bind="value: filterText, valueUpdate: 'afterkeydown'" />
<tbody data-bind="foreach: filteredItems">
<tr>
<td data-bind="text: taskName"></td>
<td data-bind="text: priority"></td>
</tr>
</tbody>