2017の24日目の記事です。昨日は@yuzoiwasakiさんの「後からアソシエーションを制御する方法いろいろ」でした。みなさん、突然ですがフォームをグリグリ動かしたくないですか?CakePHPで簡単にフォームをグリグリ動かしたくないですか??今回はそんな思いから、CakePHP3にjquery-uiのSortableフォームを導入した記録を残しておきます。jquery-uiの導入jquery-uiのSortableについてはこちらにサンプルがあります。実装に必要なJSファイルはCDNでも提供されているので今回はそちらを利用しましょう。$this->Html->script('https://code.jquery.com/jquery-2.2.4.min.js');$this->Html->script('https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js');ViewかTemplateあたりで読み込んでおきましょう。999999});あとはこんな感じでHTMLとJSを書けばフロント側は完成です。ここからCSSを整える必要はありますが、とりあえずグリグリ動かせるフォームが出来上がります。AdminLTEを導入していると、このコードだけでもそこそこ綺麗な可動式フォームができるようです。システムを組み込むそれでは実際にjquery-uiのSortableを使用したフォームにシステムを組み込んでみましょう。ここでは仮にブログシステムのようなものを想定し、記事を管理するPostモデルとそれに対して一対多で紐づくCategoryモデル、そして多対多で紐づくTagモデルを作成しておきます。作成したテーブルの略図を載せておきますね。表示順bakeコマンドで勝手にいろいろ作ってもらうため、テーブル名やカラム名はできる限りCakePHPの命名規則に沿ったものを作るといいと思います。そのほかSortableフォームを作成する際のポイントですが、表示順を保持しておくためのカラムを用意しておくことでしょうか。一対多であればbelongsTo側のテーブルに用意しますが、多対多の場合は中間テーブルに保持しないといけません。一対多のSortableフォームまずは一対多で紐づくPostsとCategoriesのフォームを実装してみましょう。?>Templateに記述するのはこんな感じです。addでもeditでも使いまわせるように、$postで渡されたEntityにcategoriesが紐づいていた場合はそれをフォームとして表示させておき、それぞれに削除ボタンと、新しくカテゴリを追加できるボタンを設置します。ポイントは下記の通り。一対多のリレーションを登録するフォームであれば基本的に$this->Form->control('..');のようにすることで登録ができますが、Sortableフォームでグリグリ好き勝手に動かされちゃうと順番の管理が面倒なので、順番のところを空欄にしておいて勝手に入るようにしておきます。上記で順番を指定しないようにしてしまったため、editしたときなどに自動でvalue値を取ってこれなくなります。ダサいですが手動で引っ張ってきましょう。フォーム追加ボタンのJSとフォーム削除ボタンのJSはそれぞれこのようになります。{$(this).parent().remove();});Controller次はControllerでの処理を見ていきましょう。基本的にはbakeコマンドで生成されるadd()の処理を流用しますが、少しだけ処理を加えます。{...追加した処理でやっていることとしては、空欄で追加されたカテゴリの削除と表示順制御カラムorder_numの追加ぐらいです。ModelあとはModelの設定もちょこちょこ変更します。PostsTableのinitialize()を見ていきます。'replace',これがないとフォームを編集するたびにカテゴリがどんどん増えていきます。NULL制約を付けていないと、フォームを編集するたびに既存のレコードは削除されずにpost_idがNULLになってレコード自体は残り続けます。これもなんだか気持ち悪いので気を付けましょう。これで、グリグリ動かせるカテゴリ追加フォームができたかと思います!次はこのままタグ追加フォームに行ってみましょう!!多対多のSortableフォームここでPostsとTagsの関係はbelongsToMany、つまり多対多を想定しています。CategoriesのようにPostsを追加・編集する際に都度レコードを作成していく形式ではなく、すでに作成されたTagsのレコードの中からセレクトボックスなりで選び取っていく形です。カテゴリと同様にこちらも自由に追加、削除ができるフォームを作成していきましょう。?>まずは、Templateです。だいたいは先ほどのCategoriesフォームを踏襲していますが、ところどころ変えています。表示順を挿入する関係で、多対多リレーションに便利なtags._idsは使っていません。Controller次にControllerの処理はこんな感じです。$j]];この処理です。カテゴリと同様に表示順を登録しますが、タグの場合は中間テーブルposts_tagsに登録しなければなりません。その場合、_joinDataというキーを使用すると、登録した中間テーブルのレコードに対してデータを挿入することができます。参考:cakePHP3でbelongsToManyModelModelの設定もしてやります。PostsTableのinitialize()内で、下記のリレーション設定を定義してあげてください。'asc'],]);(ここでのsort設定は特に何も考えずに書いてもposts_tagsテーブルのデータを見てくれるようです。)いかがでしたでしょうか??これにてSortableなカテゴリ追加/タグ追加フォームができたかと思います。2017最終日、@chinpei215さんの担当です!ここまでお読みいただきありがとうございました!よい聖夜をお過ごしください。Analyticsで自社メディアを解析してみた株式会社リスペクトという、仙台・東京に拠点を持つ会社のシステム部門のブログです。プログラミングやシステム運用のノウハウなどを公開していきます。