【jQueryプラグイン】Flexigridまとめ

web

こんにちは、なかだ(@newNakata)です。

この度jQueryプラグインのflexigridを触る機会がありました。
ただこのプラグイン、作成日もさることながらリファレンスが少ない。
(リファレンスは当初から少なかった様です)
という事で、色々触ってみたので早速ログに残していきたいと思います。

flexigridとは

一言で言うとテーブルをグリット表示してくれるものです。
概要は以下の通り。

  • htmlのtableタグを整形
  • テーブル、テーブル内のカラムの伸縮、移動
  • テーブル内カラムの表示、非表示
  • ajaxによる表示データの非同期読み込み
  • 項目のソート
  • フィルタ
  • 追加、削除などボタンの追加

プラグインのダウンロードなど

Google Code
flexigrid-1.1.zipをダウンロード。
これがベース?だと思います。
これを使う場合の注意としてjQueryのバージョンがあります。
jQuery1.9以上で動作させたい(現在ではほとんどの場合がこれに該当すると思いますが)場合は解凍して得られるflexigrid.jsまたはflexigrid.pack.jsを開き
$.browser → $.support
に全置換してください。
該当の$.browserはjQuery1.3で非推奨となり、jQuery1.9で削除されました。
リファレンス > jQuery API Documentation

paulopmx/Flexigrid: Lightweight but rich data grid … – GitHub
google codeのproject informationに作者が載っていたので情報を求めて検索するとヒットしました。
git cloneまたはzipをダウンロードしてください。
こちらはgoogle codeにあるソースよりもカスタマイズされています。
jQuery1.9以上(確認は3.3.1で行いました)でも動作し、オプションも追加されている様です。

本稿はこちらのバージョンで進めます。

基本的な使い方

解凍したFlexigrid-masterフォルダは以下の通りです。
※使用するファイルのみ表示

Flexigrid-master
 ├ css/
 │ └ flexigrid.css
 │ └ image/
 └ js/
   └ flexigrid.js

js、cssフォルダを手元の開発環境に応じて配置してください。
jsについてはflexigrid.jsとflexigrid.pack.jsはありますが、内部は一緒ですので好きな方を配置してください。
css内にあるimageフォルダはflexigridのボタンなどを使用しなければ必要ありません。

<script>
$(document).ready(function(){
  $('#grid').flexigrid();
});
</script>

<table id="grid">
<thead>
  <tr><th>カラム1</th><th>カラム2</th></tr>
</thead>
<tbody>
  <tr><td>レコード1-1</td><td>レコード2-1</td></tr>
  <tr><td>レコード1-2</td><td>レコード2-2</td></tr>
  <tr><td>レコード1-3</td><td>レコード2-3</td></tr>
</tbody>
</table>

テーブルタグのIDに対してflexigridを呼び、グリットが表示されれば設置は完了です。

オプション、パラメーター一覧

heightテーブルの縦幅。
初期値は200。
実数またはautoを指定可能で、autoを指定するとテーブル縦幅のリサイズは無効となる。
widthテーブルの横幅。
初期値はauto。
実数またはautoを指定可能で、autoを指定するとテーブル横幅のリサイズは無効となる。
striped行に対してストライプ表示を利用するかどうか。
初期値はtrue(する)。
trueまたはfalse(しない)で指定する。
novstripe列の区切り線を表示するかどうか。
初期値はfalse(表示する)。
true(非表示)にして行を選択すると区切り線が青くなる。
minwidth各列の最小横幅。
初期値は30。
minheightテーブルの最小縦幅。
初期値は80。
resizableテーブルのリサイズを可能にするかどうか。
初期値はtrue(可能)。
heightおよびwidthがautoでない場合、テーブルの右端、下部にリサイズ用アイコンが表示される。
urlAjaxで通信する際のURL。
初期値はfalse。
methodリクエスト形式。
初期値はPOST。
dataType読み込みデータタイプ。
初期値はxml。
xmlまたはjsonを指定可能。
errormsgデータ取得時エラーが発生した時の文言。
初期値は’Connection Error’。
usepagerページネーションを使用するかどうか。
初期値はfalse(使用しない)。
falseまたはtrue(使用する)を指定可能。
trueを指定した場合、テーブル下部に表示される。
nowrap各カラム幅に応じて折り返すかどうか。
初期値はtrue(折り返さない)。
trueまたはfalse(折り返す)を指定できる。
page現在表示しているページ数。
初期値は1。
リクエストパラメーターで上書きされる。
10ページ中1ページ目表示の状態で5(ページ)を指定してリクエストするとpage=5で送信される。
total格納されているデータの総行数。
初期値は1。
useRpテーブル下部に表示される、1ページに表示する行数を変更できるセレクトボックスを表示するかどうか。
初期値はtrue(表示する)。
trueまたはfalse(表示しない)を指定できる。
rp1ページに表示する行数。
初期値は15。
rpOptionsuseRpを有効にした際に表示されるセレクトボックスの値(配列)。
初期値は'[10, 15, 20, 30, 50]’。
titleテーブルのタイトル(キャプション)をテーブル上部に表示する。
初期値はfalse(表示しない)。
falseまたは文字列で指定する。
idPropertydata-idを付与する時のアトリビュート名。
初期値はid。
pagestat現在表示しているページの説明文フォーマット。
初期値は’Displaying {from} to {to} of {total} items’。
以下の通りしていできる。
開始行:'{form}’
終了行:'{to}’
総行数:'{total}’
例)'{total}’ + ‘件中’ + ‘{from}’ + ‘件から’ + ‘{to}’ + ‘件目を表示’
pagetextusepagerを使用している場合、テーブル下部に表示される現在表示されているページ数(入力項目)の前(左)に表示される文言。
初期値は’Page’。
outofusepagerを使用している場合、テーブル下部に表示される現在表示されているページ数(入力項目)の後(右)に表示される文言。
初期値は’of’。
findtext初期値は’Find’。
paramsリクエスト時、追加でパラメーターを渡したい時に指定する。
初期値は[]。
配列オブジェクトで指定する。
name:キー名
value:値

例)
params:[
 {name:’id’, value:’example’},
 {name:’password’, value:’12345′}
]
procmsg通信中時フッターに表示されるメッセージ。
初期値は’Processing, please wait …’。
query検索文字列。
設定していなくてもリクエストパラメーターで値は渡る。
初期値は”(空)。
qtype検索対象のテーブルの列名。
設定していなくてもリクエストパラメーターで値は渡る。
初期値は”(空)。
nomsg取得データがゼロ行の時表示するメッセージ。
初期値は’No items’。
minColToggle非表示にする場合の最小列数。
初期値は1。
showToggleBtnテーブル列の表示非表示セレクトボックスを表示するかどうか。
初期値はtrue(表示する)。
trueまはたfalse(非表示)で指定する。
hideOnSubmit初期値はtrue。
autoloadHTML読み込み時、自動的に読み込みを開始するかどうか。
初期値はtrue(開始する)。
trueもしくはfalse(開始しない)で指定する。
blockOpacity初期値は0.5。
preProcessレスポンスデータを受信した直後に呼ばれる。
初期値はfalse。
addTitleToCellセルの内容が切り捨てられている場合、タイトル属性をdivに追加する。
初期値はfalse。
dblClickResizeダブルクリックで列のサイズを自動変更させる。
初期値はfalse(させない)。
falseまたはtrue(させる)。で指定する。
onDragColcolMoveがtrueの時、テーブルのカラム名をドラッグ&ドロップした時に呼ばれる。
初期値はfalse。
falseまたはfunctionで指定する。
onToggleColshowToggleBtnがtrueの時、セレクトボックスのチェックを押下した時に呼ばれる。
ページ読み込み時にも呼ばれる。
初期値はfalse。
falseまたはfunctionで指定する。
onChangeSort項目のソート(クリック)が行われた時に呼ばれる。
初期値はfalse。
falseまたはfunctionで指定する。
onDoubleClickデータ行部分でダブルクリックが行われた時に呼ばれる。
初期値はfalse。
falseまたはfunctionで指定する。
onSuccess処理が成功した時に呼ばれる。
初期値はfalse。
falseまたはfunctionで指定する。
onError処理が失敗した時に呼ばれる。
初期値はfalse。
falseまたはfunctionで指定する。
onSubmitデータの送受信が行われる直前に呼ばれる。
初期値はfalse。
falseまたはfunctionで指定する。
colResizeテーブルの列幅をドラッグ&ドロップで変更できるかどうか。
できる場合は列の境界線付近にカーソルを持っていくとポインターが変わる。
初期値はtrue(できる)。
trueまたはfalse(できない)で指定する。
colMove列の表示順をドラッグ&ドロップでテーブル内を移動させれるかどうか。
初期値はtrue(できる)。
trueまたはfalse(できない)を指定する。
singleSelect複数行選択を可能にするかどうか。
初期値はfalse(複数選択可)。
falseまたはture(複数選択不可)を指定する。
showTableToggleBtnテーブルの表示非表示ボタンを表示するかどうか。
titleが設定(文字が設定)されている場合にのみ、タイトル表示部分の右端に表示される。
初期値はfalse(表示しない)。
falseまたはtrue(表示する)で指定する。
sortnameソートする列。
設定していなくてもリクエストパラメーターで値は渡る。
初期値は”(空)。
colModelの設定でソートを可にした場合、name(テーブルのカラム名)が渡る。
sortorder昇順ソートまたは降順ソート。
設定していなくてもリクエストパラメーターで値は渡る。
初期値は”(空)。
‘asc’または’desc’で指定する。
初期設定を指定していない場合、空→asc→descと渡る為、ソートを使用する場合は事前に初期値を指定した方がよい。
flexReloadテーブル情報をリロードします。

例)
$(‘~’).flexReload();
flexToggleCol列の表示非表示を切り替えます。
column id:カラム番号
visible:true[表示] / false[非表示]

例)
$(‘~’).flexToggleCol(0,false);
$(‘~’).flexigrid({}).flexToggleCol(0,false).flexTogglecol(1,true);
searchitems検索機能を使いたい時に指定する。
指定するとテーブル下部一番左に虫メガネアイコンが表示され、そこを押下するとテキストボックス、検索対象カラム選択セレクトボックスが表示される。
リクエスト時、テキストボックスの値はキー名queryにセットされ、セレクトボックスの値はqtypeにセットされる。
配列オブジェクトで指定する。
display:検索対象のカラム名(セレクトボックスに表示される表示名)
name:リクエスト時に送信される検索対象カラム名
isdefault:初期選択状態にするかどうか

例)
searchitems:[
 {display:’カラム1′, name:’col1′},
 {display:’カラム2′, name:’col2′, isdefault:true},
]
buttonsボタンを表示したい時に指定する。
指定するとテーブルの上部(text設定のタブとテーブルthの間)に表示される。
配列オブジェクトで指定する。
name:ボタン表示文字
bclass:ボタンに付与するクラス(css)名
bimage:ボタンの背景画像URL
onpress:ボタン押下時の処理関数名
separator:trueで指定し、表示したい場合はこれのみ

例)
buttons:[
 {name:’add’,bclass:’add’, onpress:add_function},
 {separator:true}, 
 {name:’del’, bclass:’del’ onpress:del_fuction}
]
colModel行を動的に表示したい時、表示する列について定義する。
配列オブジェクトで指定する。
display:テーブルに表示する表示名
name:リクエスト時に使用する列名
width:列幅
sortable:列のソート可否(true:可 / false:不可)
align:文字の表示位置(left:左寄せ / center:中央 / right:右寄せ)
hide:非表示設定(true:非表示 / false:表示)

例)
colModel:[
 {display:’カラム1′,name:’col1′,width:200,sortable:true,align:’left’},
 {display:’カラム2′,name:’col2′,width:200,sortable:false,align:’center’}
]

使用例(動的読み込みなど)

使用例(動的読み込みなど)

デモ環境など無いのですが上の画像のように表示されるコンテンツを置いておきますので、宜しければお使いください。
動的ファイルはPHPとなります。

ファイルはお使いの環境に合わせて設置してください。
flexigridのライセンスは詳しく調べていませんので含んでいません。
expフォルダの中に適宜設置してください。

ここでは上記コンテンツを元に説明していきます。

最初に

本サンプルは1ページ10件(最大30件)を表示させ、ページネーションによってデータが切り替わります。
テーブルのリサイズ、ボタン、検索など、内部パラメーターを確認することを目的としている箇所は完全には動作していません。
初期設定(例えばmethodがPOSTなど)から変更する必要が無いものは記載していません。
PHP側も挙動確認以外のエスケープなどは入っていません。

flexigridをダウンロードした時に一緒に同梱されているdemoフォルダも参考になると思いますので一緒に確認すると理解が進むと思います。

html側

基本的な使い方で記載したhtmlのテーブル情報を空にしたものをベースに拡張した形になります。

26行目 rp:10,
27行目 rpOptions:[10,20,30],
30行目 pagetext:'ページ',
31行目 outof:'ページ中',
32行目 params:[],

rp設定で基本10件に設定。
rpOptionsで表示件数を選べるセレクトボックス(画像左下)を設置。
セレクトボックスを変更すると自動で表示を切り替えてくれます。
pagetext、outofは下記ページネーション文言を参考にしてください。
paramsは空にしています。
後述するphp側の基本パラメーターの確認ができた後で、例えば

params:[
 {name:'id', value:'nakadalog'},
 {name:'password', value:'12345'}
]

を追加しリクエストするとパラメーターが追加される為、違いがわかりやすいかと思います。

39行目 buttons:[
40行目   {name:'編集', bclass:'edit', onpress:edit_function},
41行目   {separator:true},
42行目   {name:'削除', bclass:'del', onpress:del_function},
43行目   {separator:true}
44行目  ],

63行目 // buttons edit onpress
64行目 function edit_function(){
65行目     alert('edit_function');
66行目     $('#grid').flexReload();
67行目 }

69行目 // buttons del onpress
70行目 function del_function(){
71行目     alert('del_function');
72行目     $('#grid').flexReload();
73行目 }

編集、削除ボタンの設置です。
40、42行目が実際のボタンの指定です。
bclassは不要であれば空白で構いません。
onpressはボタンを押下した時に実行されるjs関数名になります。
記載した関数が無い場合はエラーになるので注意が必要です。
編集ボタンの処理関数が63行目から、削除が69行目になります。
本サンプルではアラートが表示され、その後にテーブルがリロードされます。
(実際は画面がチラつくだけですが・・・)

45行目 searchitems:[
46行目  {display:'カラム1', name:'col1'},
47行目  {display:'カラム2', name:'col2', isdefault:true}
48行目 ],

検索項目の設置です。
テーブル左下に虫メガネアイコンが表示され、押下すると入力項目と検索対象列セレクトボックスが表示されます。
検索の実行は入力項目がフォーカスされている状態でエンター(キーコード13)を押下する事で実行します。
実行時、リクエストパラメーターとして入力項目はキー名query、セレクトボックスはキー名qtypeでリクエストされます。

50行目 url:'./index.php',
51行目 dataType:'json',
52行目 colModel:[
53行目  {display:'連番', name:'no', width:20, sortable:true, align:'center'},
54行目  {display:'カラム1', name:'col1', width:150, sortable:true, align:'left'},
55行目  {display:'カラム2', name:'col2', width:200, sortable:true, align:'left'},
56行目  {display:'カラム3', name:'col3', width:300, sortable:false, align:'left', hide:true},
57行目  {display:'カラム4', name:'col4', width:50, sortable:false, align:'center'}
585行目 ],

50行目はajaxのリクエスト先URLです。
ダウンロードしたexpフォルダにindex.htmlと一緒に同梱されています。
51行目はそのままですが、この度のデータのやり取りはjson形式で行います。

52行目以降は動的読み込み時の列設定です。
53、54、55行目はsortable設定がある為、テーブル表示時の列名を押下するとソート処理が走ります(サンプルではソート処理自体は未実装)。
ソート処理実行時、リクエストパラメーターとして押下した列名の上記nameで指定した文字列がキー名sortname、昇順降順はキー名sortorderでリクエストされます。
flexigridの設定にあえてsortorderを記述していません。
よってソート処理実行時は1回目sortorderは空→2回目asc→3回目desc→4回目ascと変わっていきます。
56行目と57行目はsortableにfalseを設定している為、列名を押下しても何も動作しません。

表は5列ありますが、56行目は最後にhideが指定ある為、テーブルには表示されません。

実際の行の説明はこの後のPHP側で記載します。

PHP側

2行目 //var_dump($_POST);

リクエストパラメーター確認的な意味で残しています。

 4行目 // 基本的なpostパラメーター
 5行目 $page = $_POST['page'];
 6行目 $rp = $_POST['rp'];
 7行目 $sortname = $_POST['sortname'];
 8行目 $sortorder = $_POST['sortorder'];
 9行目 $query = $_POST['query'];
10行目 $qtype = $_POST['qtype'];

基本的なpostパラメーターを記載していますが、この6のリクエストパラメーターは必ず送信されます。

5行目のpageパラメーターの初期値は1です。
usepager設定でページネーションを非表示(使わない)にしても必ず1が渡ります。
ページネーション部の戻る(左三角)、進む(右三角)、ページ入力項目の入力によりパラメーターが変化します。
ただし、レスポンスデータのtotal値とrpで算出される範囲以外は指定できません。
つまり、本サンプルは1~3以外は指定できません。
1ページ目表示の状態で戻るを押下しても動作せず、進むを押下すると次ページへ遷移、入力項目に100と入力すると3ページ目が自動で表示されます。
うん。便利。
6行目のrpパラメーターの初期値は15です。
この度はhtml側で10を指定しているので10が渡ってきます。
7、8行目は列名のソートパラメーターです。
9、10行目は検索項目パラメーターです。

12行目 // データ作成ループ範囲
13行目 $startRec = $rp * ($page - 1);
14行目 $endRec = ($rp * $page) - 1;

3ページ分のデータを作成する為の記述です。
ここはSQLなどでのデータ取得処理に置き換わる箇所かと思います。
本サンプルでは検索やソートのリクエストパラメーターは使っていませんが、SQLの場合はlike検索やlimit offsetなどに使用されるかと思います。

16行目 $res = [];

18行目 // レスポンスデータ(テーブル)
19行目 $res['page'] = $page;
20行目 $res['total'] = 30;

22行目 // レスポンスデータ(レコード)
23行目 $res['rows'] = [];

24行目 for($i = $startRec; $i <= $endRec; $i++){
25行目     $no = $i + 1;
26行目     $res['rows'][] = [
27行目         'cell' => [
28行目             $no,
29行目             sprintf('col1データ%d', $no),
30行目             sprintf('col2データ%d', $no),
31行目             sprintf('col3データ%d', $no),
32行目             sprintf('<input type="checkbox" name="rec%s">',$no),
33行目         ]
34行目     ];
35行目 }

レスポンスデータを取得した後、上記の書式に整形します。
html側のcolModelに対して上記書式でレスポンスデータを返すと自動でテーブルに情報をセットしてくれます。
配列のキー名である、page、total、rowsは必須です。
上記各項目ごとに分けているレスポンスデータの書式を1つの配列にした場合は以下の様になります。

$res = array(
    'page' => ページ数,
    'total' => 総行数,
    'rows' => array(
        array('cell' => array(1行目のデータ~)),
        array('cell' => array(2行目のデータ~)),
        array('cell' => array(3行目のデータ~)),
    )
);

19行目のpageはレスポンス後に表示するページ数です。
基本的にはリクエストデータをそのままセットすれば大丈夫かと思います。
20行目は最大レコード数です。
基本的なpostパラメーターでも記載しましたが、ページネーションの動作に必要です。
23行目のrowsの中に実際に表示させたい配列をセットします。
27行目~35行目が実際のデータをセットしている箇所です。
htmlでセットした列名(数)と同じ数のデータをcell配列の中に入れます。

32行目にHTMLのタグが入っています。
flexigridはhtmlをセットするとそのまま表示してくれます。
これにより上記inputや画像を表示できますが、動的にHTMLを生成する場合はエスケープ処理も実装すべきです。

60行目 header("Content-Type:application/json");
61行目 echo json_encode($res);
62行目 exit;

html側でdataTypeをjsonにしている為、json形式で返却します。

ちょっとしたカスタマイズ

ページネーション文言

ページネーションを表示した時に
pagetext
outof
で文言を変更しても表現しきれません。
これはjsで生成されるHTMLの配置が日本語の表現になっていない為です。
flexigrid.jsの1267行目でセットされるhtmlタグを変更すると対応できます。
ちなみに、英字表現のまま逆にしているので、outofの方にpagetextの内容を持って来る形になっています。

var html = ' <div class="pGroup"> <div class="pFirst pButton"><span></span></div><div class="pPrev pButton"><span></span></div> </div> <div class="btnseparator"></div> <div class="pGroup"><span class="pcontrol">' + p.pagetext + ' <input type="text" size="4" value="1" /> ' + p.outof + ' <span> 1 </span></span></div> <div class="btnseparator"></div> <div class="pGroup"> <div class="pNext pButton"><span></span></div><div class="pLast pButton"><span></span></div> </div> <div class="btnseparator"></div> <div class="pGroup"> <div class="pReload pButton"><span></span></div> </div> <div class="btnseparator"></div> <div class="pGroup"><span class="pPageStat"></span></div>';
↓
var html = ' <div class="pGroup"> <div class="pFirst pButton"><span></span></div><div class="pPrev pButton"><span></span></div> </div> <div class="btnseparator"></div> <div class="pGroup"><span class="pcontrol"><span> 1 </span> ' + p.outof + ' <input type="text" size="4" value="1" />' + p.pagetext + '</span></div> <div class="btnseparator"></div> <div class="pGroup"> <div class="pNext pButton"><span></span></div><div class="pLast pButton"><span></span></div> </div> <div class="btnseparator"></div> <div class="pGroup"> <div class="pReload pButton"><span></span></div> </div> <div class="btnseparator"></div> <div class="pGroup"><span class="pPageStat"></span></div>';

検索表示時のクリアボタン

検索を使用する時、クリアボタンも表示すると参考サイトに記載されていましたが、クリアボタンは表示されませんでした(demoも)。
確認したところ、クリアボタンを押すと検索文言の削除および検索の実行がされる処理は残されていました。
そこで、クリアボタンを表示したい場合はflexigrid.jsの1339行目でセットされるhtmlに追記すると対応できます。

" <select name='qtype'>" + sopt + "</select></div>");
↓
" <select name='qtype'>" + sopt + "</select> <input type='button' value='Clear' /></div>");

ボタンアイコンの表示

ボタンを表示すると表示文言の左隣に20pxの幅が空きます。
bclassの指定でaddとdelはデフォルトで実装されており、何もしなくともアイコンが表示していた様です。
ですが使用するファイル群にはCSSも画像もない為、削除されたようです。
ただ同梱しているdemoフォルダにはCSSの記述と画像があります。
ボタンにアイコンを表示したい場合はimagesの中にアイコン画像を設置した後、各環境に合わせて以下のCSSを追記すると表示されます。

.flexigrid div.fbutton .add {
	background: url(images/add.png) no-repeat center left;
}
.flexigrid div.fbutton .delete {
    background: url(images/close.png) no-repeat center left;
}

ボタン表示時の左padding

ボタン左隣りの20pxの空きが不要になる場合があります。
このpaddingはjsでコンテンツ作成時に指定されている為そのままでは削除できません。
このpaddingを設定させたくない場合はflexigrid.jsの990~992行目および995行目をコメントアウトする事で対応できます。

if (btn.bclass) $('span', btnDiv).addClass(btn.bclass).css({
	paddingLeft: 20
});
if (btn.bimage) // if bimage defined, use its string as an image url for this buttons style (RS)
	$('span',btnDiv).css( 'background', 'url('+btn.bimage+') no-repeat center left' );
	$('span',btnDiv).css( 'paddingLeft', 20 );
↓
//if (btn.bclass) $('span', btnDiv).addClass(btn.bclass).css({
//	paddingLeft: 20
//});
if (btn.bimage) // if bimage defined, use its string as an image url for this buttons style (RS)
	$('span',btnDiv).css( 'background', 'url('+btn.bimage+') no-repeat center left' );
//	$('span',btnDiv).css( 'paddingLeft', 20 );

参考サイト