ExtJS入門20 グリッドにフィルタリング機能を追加する
引き続きGridPanel関連のサンプルの紹介です。
今回はグリッドに表示されている一覧から特定のデータをフィルタリングして表示する方法をご紹介します。
グリッドのデータはストアによって管理されています。グリッドの一覧からフィルタリングして特定の情報だけを表示したい場合は、大きく二つの方法があります。
一つはstoreクラスのfilterメソッドを使ってフィルタリングを行う方法。もう一つはstoreがロードしているデータをフィルタリングされたデータに更新する、つまりサーバーサイドでフィルタリングを行ってstoreを更新する方法があります。
今回はこの2つの機能を同時に持ったグリッドパネルのサンプルになります。
グリッドパネルについてはこちらもご覧下さい。
- ExtJSで楽しくRIA業務アプリ開発 ExJS入門17 グリッド・パネル 基本編
- ExtJSで楽しくRIA業務アプリ開発 ExtJS入門18 グリッド レンダラーを使ってデザインを変える
- ExtJS入門19 グリッドにページング機能を追加する
リファレンスはこちらから
ExtJS -3.0 日本語APIドキュメント – Ext.data.Storeクラス
http://extdocs.xenophy.com/?class=Ext.data.Store
PHP:
<?php
$limit = $_POST['limit'];
$start = $_POST['start'];
$name = $_POST['name'];
//全データ
$data = array(
array(
'id'=>1,
'rank'=>1,
'name'=>'IE',
'percentage'=>62.69
),
array(
'id'=>2,
'rank'=>2,
'name'=>'Firefox',
'percentage'=>24.61
),
array(
'id'=>3,
'rank'=>3,
'name'=>'Chrome',
'percentage'=>4.63
),
array(
'id'=>4,
'rank'=>4,
'name'=>'Safari',
'percentage'=>4.46
),
array(
'id'=>5,
'rank'=>5,
'name'=>'Opera',
'percentage'=>2.40
),
array(
'id'=>6,
'rank'=>6,
'name'=>'Opera Mini',
'percentage'=>0.53
)
);
if ($name) {
$newData = array();
foreach($data as $val){
if(stristr($val['name'],$name)) {
$newData[] = $val;
}
}
$data = $newData;
}
if ($limit && $start + $limit <= count($data)) {
//ページング用
$rows = array_slice($data,$start,$limit);
}else {
//ページングしない
$rows = $data;
}
$res = array(
'success' => true,
'total' => 6,
'rows' => $rows
);
header("Content-Type: text/javascript; charset=utf-8");
echo json_encode($res);
die();
HTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>ExtJS名古屋勉強会 Grid Filter and Sort</title>
<!--Ext JS CSS-->
<link rel="stylesheet" href="../js/ext/resources/css/ext-all.css" type="text/css" />
<!--Ext JS-->
<script type="text/javascript" src="../js/ext/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="../js/ext/ext-all.js"></script>
<script type="text/javascript" src="grid-filter.js"></script>
</head>
<body>
<div style="width:500px;margin:0 auto;padding:15px;background-color:#D3E1F1;font-size:small;">
<p style="font-weight:bold;padding:3px;margin-bottom:10px;">
Gridデータのフィルタリングを行います。
</p>
フィルタリングにはローカルのstore内で行うものと、サーバーサイドで行いstoreをリロードする方法の2種類があります。
<div id="grid"></div>
<br/>
Java Script:<a href="grid-filter.js">grid-filter.js</a><br/>
PHP(JSONデータ):<a href="data.php">data.php</a><br />
</div>
</body>
</html>
Java Script:
//フィルターグリッド
Ext.onReady(function()
{
//1.データを用意
//今回はPHPでdata.phpでJSONを返しています。
//2.データストアを用意
var store = new Ext.data.JsonStore({
url:'data.php',
root:'rows', //実際のデータ位置(プロパティ名)
totalProperty:'total', //全件数を返すプロパティ名を指定
fields:[
{name:'id'},
{name:'rank'},
{name:'name'},
{name:'percentage',type:'float'}
],
autoLoad:true //描写後に自動的に初回のリクエストをかける
});
//3.カラムモデルを用意
var column = new Ext.grid.ColumnModel([
{
id:'rank',
header:'順位',
dataIndex:'rank',
width:50
},
{
id:'name',
header:'ブラウザ名',
dataIndex:'name',
width:100
},
{
id:'percentage',
header:'シェア',
dataIndex:'percentage',
width:80
},
{
id:'id',
header:'ID',
dataIndex:'id',
width:20
}
]);
//4.フィルター用
var tbar = [
'ローカル:',
{
xtype:'textfield',
emptyText:'ブラウザ名を入力',
listeners:{
valid:function(field){
var cond = field.getValue();
store.filter('name',cond,true);
}
}
},
'リモート:',
{
xtype:'textfield',
emptyText:'ブラウザ名を入力',
listeners:{
valid:function(field){
var cond = field.getValue();
store.load({
params:{
name:cond
}
});
}
}
}
];
//5.グリッドパネルの作成
new Ext.grid.GridPanel({
renderTo:'grid',
id:'my-grid',
autoExpandColumn:'name',
title:'フィルター付きグリッドパネル',
height:210,
width:400,
cm:column,
store:store,
tbar:tbar
});
});
実行結果:
リモートフィルタリング:
サーバーサイドのPHPは前回のものから若干変更があります。サーバーサイドでのフィルターを実行するために、元データを変更する処理が追加されています。
リモート(サーバーサイド)でのフィルタリングは、storeの内容を入れ替えて行います。
storeのloadメソッドを使ってstoreの内容をリロードします。loadメソッドの引数にはオブジェクトを渡します。この引数オブジェクトのparamsプロパティに設定されたオブジェクトがstoreの内容を再リクエストする際にPOST値として設定されます。
今回の場合はブラウザ名でフィルタリングを行うため、paramsに設定するオブジェクトのnameプロパティに条件を設定しています。
store.load({
//pramsプロパティに設定したオブジェクトがリクエスト時にPOST値に設定される
params:{
name:'条件'
}
});
このリクエストに基づきサーバーサイドでフィルタリングを行い、結果を返すことでストアの内容はフィルタリングされたデータに切り替わります。
注意点としては、storeにはフィルタリング後のデータしかストアされていない点です。後述するローカルのフィルタリングと違い、フィルター条件が変更されるたびにstoreを更新するためのリクエストが必要になります。、
ローカルフィルタリング:
ローカルでのフィルタリングはグリッドのstoreにストア済みのデータの中からグリッドに表示する項目をフィルタリングする方法です。storeのfilterメソッドを使うことで、特定のデータのみをグリッドに表示させます。第1引数にnameを指定し,第2引数に条件を設定します。第3引数以降はオプションになり、マッチング条件を設定できます。詳しくはAPIリファレンスのfilterメソッドの項目をご覧下さい。
今回はnameフィールドのブラウザ名が一部でもマッチする場合を設定してます。
store.filter( 'name', //対象のフィールド cond, //検索条件。フォームより入力 true //先頭以外にもマッチさせる );
今回は紹介していませんが、より複雑な条件でフィルタリングを行う場合はfilterByメソッドを使います。filterByメソッドではカスタムのフィルタリング関数を記述してフィルタリングを実行できます。
storeのfilterメソッドが実行されると、条件にマッチしたrecordのみがGridに再設定されます。
ローカルで行うフィルタリングでは、毎回リクエストを行わないため比較的すばやいフィルタリングが実行できます。ただし、あくまでstore内のデータだけに対してのフィルターになります。ページングなどを使っている場合に全件中からフィルタリングを行いたい場合はこの方法ではなく、リモートでフィルタリングを行う必要があります。
FireFoxのFirebugなどでリクエストの実行状況を見ながらサンプルを試すと、動作の状況がよくわかるかと思います。リモートの方は入力があるたびにリクエストが実行されていますが、ローカルのときはリクエストが実行されません。
またこのフィルタリング機能はstoreの機能ですので、グリッド以外にもstoreを使っている場所で様々な場所で使うことができるので、色々な場所で試してみるとよいかと思います。




[...] ExtJS入門20 グリッドにフィルタリング機能を追加する [...]
ExJS入門23 グリッドへの項目の追加と削除 | ExtJSで楽しくRIA業務アプリ開発
20 4 月 10 at 12:28 PM
[...] ExtJS入門20 グリッドにフィルタリング機能を追加する [...]
ExJS入門30 Twitter Search APIを使ったグリッドパネル | ExtJSで楽しくRIA業務アプリ開発
7 5 月 10 at 11:50 AM
[...] ExtJS入門20 グリッドにフィルタリング機能を追加する [...]
ExJS入門31 GridViewでグリッドの各行の背景色を変更する | ExtJSで楽しくRIA業務アプリ開発
10 5 月 10 at 12:05 PM