遥かへのスピードランナー

シリコンバレーでAndroidアプリの開発してます。コンピュータービジョン・3D・アルゴリズム界隈にもたまに出現します。

ExtJSでインクリメンタルサーチを実装する

最近ExtJSをいろいろといじって遊んでいるのですが、GridPanelにインクリメンタルサーチを実装したくなったので早速実装してみました。

世の中の一般的なインクリメンタルサーチの実装方法は、setTimeoutで定期的に検索用のテキストフィールドを監視して、入力値に変更があればその値で検索を行うという仕組みになっているようなのですが、ExtJSのライブラリ内にはこの監視処理まで実装されていません。

incsearch.js - インクリメンタルサーチライブラリのようなライブラリも公開されているのですが、これだとUIのパターンが限定されてしまうので、今回のようにUIにExtJSを使いたい場合にはうまく対応できません。

そこでこのライブラリを改造して、もっとシンプルかつ汎用的に使えるようにしてみました。

動作デモとライブラリの使い方は以下のような感じ。ExtJSのGridPanelと組み合わせて使うサンプルです。

[incremental_search_sample.html]

<html>
<head>
	<script type="text/javascript" src="ext-2.2/adapter/ext/ext-base.js"></script>
	<script type="text/javascript" src="ext-2.2/ext-all.js"></script>
	<script type="text/javascript" src="ext-2.2/source/locale/ext-lang-ja.js"></script>
	<script type="text/javascript" src="incremental_search.js"></script>
	<script type="text/javascript" src="incremental_search_sample.js"></script>
	<link rel="stylesheet" type="text/css" href="ext-2.2/resources/css/ext-all.css">
</head>
<body>
<div id="grid-sample" />
</body>
</html>

[incremental_search_sample.js]
ライブラリを使えば、Ext.data.Store.filter関数で曖昧検索絞り込みが簡単にできるので、実装はいたってシンプルです。

Ext.onReady(function() {
    var ds = new Ext.data.SimpleStore({
        fields: [
            { name: 'a' },
            { name: 'b' }
        ],
        data:[ 
            [ 'hoge', 1 ],
            [ 'moge', 2 ],
            [ 'fuga', 3 ] 
        ]
    });
    var cm = new Ext.grid.ColumnModel([
        { header: "title", width: 200, dataIndex: 'a' },
        { header: "number", width: 100, sortable: true, dataIndex: 'b' }
    ]);
	var tf = new Ext.form.TextField({id : 'tf-cmp'});
	var grid = new Ext.grid.GridPanel({
				id : 'grid-cmp',
				store : ds,
				cm : cm,
 				renderTo : 'grid-sample',
				height : 380,
				width : 500,
				stripeRows : true,
				title : 'incremental search sample',
				viewConfig : {
					forceFit : true
				},
				tbar : [tf],
			});

	var getInputFunc = function() {
		return Ext.getCmp('tf-cmp').getValue();
	}
	var searchFunc = function(input){
		ds.filter('a', input, true, false);
	};
	var is = new IncrementalSearch(getInputFunc, searchFunc);
	is.checkLoop();
});

検索入力値を取得する関数:getInputFuncと、検索を行う関数:searchFuncを変えてやれば、大抵のケースには対応できると思います。ちなみにjqueryとかScript.aculo.usとかは僕はほとんど使ったことがないんですが、もっと簡単にできるのかも知れないです。

何かいい情報があったら是非コメント欄とかで教えてください^^