jQuery UI Sortableで並び替えたフォームのデータをどう処理すればいいか
製品対資材の連携マスタメンテナンスを作成する際に、ドラッグアンドドロップで操作できたほうがいいと思い、jQuery UI Sortableを導入した。
このjQuery UI SortableはWordPressでテーマを作成する際に、バックエンド画面で幾度となく使用したことがあるのでもはや使い慣れたものではある。
・・・が、今回はゼロベースの開発ということでWordPressのようにゆるーく設定するべきものではないので、POSTで受け渡すフォームのデータの処理をどういう形式で行うかっていうプログラムが関係ないところの部分で何回かコードを書き直したので、その記録としてケースパターンを記事に残しておこうと思う。
jQuery UI Sortableで並び替えたフォームのデータを処理するためには、分けると2パターンがあり、例えば以下のようなHTMLで構成できる。
<!-- 1つ目のパターン --> <ul id="sortdata"> <li><input name="items[item_id][]" value="1" type="text" /> <input name="items[item_inzu][]" value="10" type="text" /></li> <li><input name="items[item_id][]" value="2" type="text" /> <input name="items[item_inzu][]" value="20" type="text" /></li> <li><input name="items[item_id][]" value="3" type="text" /> <input name="items[item_inzu][]" value="30" type="text" /></li> </ul> <!-- 2つ目のパターン --> <ul id="sortdata"> <li><input name="items[0][item_id]" value="1" type="text" /> <input name="items[0][item_inzu]" value="10" type="text" /></li> <li><input name="items[1][item_id]" value="2" type="text" /> <input name="items[1][item_inzu]" value="20" type="text" /></li> <li><input name="items[2][item_id]" value="3" type="text" /> <input name="items[2][item_inzu]" value="30" type="text" /></li> </ul>
1つ目のパターンにおいては、$_POSTに入ってくるitemsの配列の番号を自動割り振りにしてSortableを通常呼び出しすることで、PHPでありのままに処理していく。
2つ目のパターンにおいては、行数を厳密に指定してSortableの更新タイミングと同時に行番を変更する処理を走らせ、その後で更に送信された$_POSTに入ってくるitemsのデータをPHPで処理していくものとなる。
手軽にSortableのデータを処理したい場合、1つ目のパターンが有用である。
細かい処理とかはとりあえず書きたくなくて、非常にざっくり動けばいいという書き方。
コードにするとこんな感じ。
// // jQuery UI Sortable // $( '#sortdata' ).sortable(); // // PHP // /* $_POSTのarrayの構成 : 'items' => array( 'item_id' => array( '1', '2', '3' ), 'item_inzu' => array( '10', '20', '30' ), ) */ if ( isset( $_POST['items'] ) && is_array( $_POST['items'] ) ) { $items = $_POST['items']; foreach ( $items as $colkey => $colval ) { // $colkeyはitem_id→item_inzu foreach ( $items[$colkey] as $rowkey => $rowval ) { // $rowkeyは0→1→2 // データ処理 } } }
これの何が良いかと言うと各コードの数が少ないということで時間的には多大なメリットがあることと、ネットとかでも調べやすいということ。
Sortableのイベントは色々あるが、そこの調べを省略してその時間をそっくりそのままPHPのコーディング時間に割り当てられるので、どちらかといえば少ないコストで数出すタイプのWebサイト制作向け。
ただし、これがより多くの多列構成になる場合は、フロントエンドで視覚的に見たときとバックエンドでの処理が一致しないという齟齬が生じる。
なにより送信データの状態を見るためにvar_dump()で配列を表示を行う際に、データが多いと追いきれなくなる。
後々手を入れることを考えて、データの形や動きをわかりやすくする場合、少しだけ手の混んだ書き方をする必要がある。これが2つ目のパターン。
コードにすると以下のような形となる。
// // jQuery UI Sortable // var sortdata = $('#sortdata'); sortdata.sortable(); // jQuery UI Sortableの行更新イベント sortdata.on( 'sortupdate', function( e, ui ) { updateSortRows( $(this), e, ui ); }); // 行更新が発生した際に呼び出す関数 function updateSortRows( row, e, ui ) { row.each( function( sortcnt ) { var chgelems = row.find( '[name^="items"]' ); chgelems.each( function( nodecnt ) { var chgname = $(this).attr( 'name' ); // 行番を置換 chgname = chgname.replace( /^items\[.+?\](.+?)$/g, 'items[' + sortcnt + ']\1' ); $(this).attr( 'name', chgname ); }); }); } // // PHP // /* $_POSTのarrayの構成 : 'items' => array( 0 => array( 'item_id' => '1', 'item_inzu' => '10' ), 1 => array( 'item_id' => '2', 'item_inzu' => '20' ), 2 => array( 'item_id' => '3', 'item_inzu' => '30' ) ) */ if ( isset( $_POST['items'] ) && is_array( $_POST['items'] ) ) { $items = $_POST['items']; foreach ( $items as $rowkey => $rowval ) { // $rowkeyは0→1→2 foreach ( $items[$colkey] as $colkey => $colval ) { // $colkeyはitem_id→item_inzu // データ処理 } } }
最大のメリットはフロントエンドの動きとバックエンドのデータの形と動きが完全に一致することで、var_dump()で出したときに視覚的な一致があること。
バグつぶしをする際などにデータが追いやすく、デバッグメッセージの可読性が非常に高まる。
PHPベースで膨大なコード量が必要な際に、デバッグやテストに当たって堅実な書き方・出し方をすることに越したことはないので、ある程度工数と時間を持って作れるシステム向け。
無論、行番を厳密に指定することでデータ処理の際に1つ目のパターンで必要のなかった形式チェックをより多く入れる必要があるので結構面倒くさいというのはある。
最初は細かい処理とかをあまり書きたくなかったもので1つ目のパターンにしていたけど・・・
var_dump()で出したときに「ああこりゃわかりづれぇわ」と思ったんだ(´・ω・`)
やっているのはWeb制作ではなくてシステム開発。
機能や処理が多岐に渡ってくる都合上、var_dump()で出したときのデータの追い方がよりナチュラルに行える方法のほうが良かったし、自分は結局2つ目のパターンを選んだ。
今回はjQuery UI Sortableをベースにしているが、パターンの考え方そのものは例えば単純な行の上下変更などにも有効であると思う。
そういえば、いつの間にか年末も過ぎ、年始も過ぎ去っているんだよな。
年末年始とテレビをながら見しながら仕事していたら、気づけばゴローさんもガキ使も紅白もゆく年くる年も終わり、年が明けていた。
2019年→2020年のフィニッシュとスタートはいつ終わっていつ始まったのかがあやふやだったけど・・・本年もよろしくお願いいたします!