laravel5.1で、カテゴリー・サブカテゴリーのような親子セレクトボックスを作る方法
1, 親カテゴリー・サブカテゴリーのテーブルを作る。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
// 親カテゴリー public function up() { Schema::create('product_categories', function (Blueprint $table) { $table->increments('id')->comment('主キー'); $table->string('category_name')->comment('カテゴリー名'); $table->integer('orderby_id')->comment('表示順序 管理画面で並び替えられる'); $table->timestamps(); $table->softDeletes(); }); // スキーマビルダーではテーブル自体のコメントは出来ない?のでSQL文で実行 DB::statement("ALTER TABLE ".DB::getTablePrefix()."product_categories COMMENT '商品カテゴリ'"); } // サブカテゴリー public function up() { Schema::create('product_subcategories', function (Blueprint $table) { $table->increments('id')->comment('主キー'); $table->integer('parent_category_id')->unsigned()->comment('親カテゴリーID 子カテゴリーの場合は親id'); $table->string('subcategory_name')->comment('カテゴリー名 '); $table->integer('orderby_id')->comment('表示順序 管理画面で並び替えられる'); $table->timestamps(); $table->softDeletes(); // 親カテゴリーIDは、必ずproduct_categoriesに存在する事! $table->foreign('parent_category_id')->references('id')->on('product_categories'); }); } |
2, テーブルを操作するためのmodelクラスを、それぞれに生成して、全レコードを返すメソッドを実装する
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
// 配列の形で、全カテゴリーを返す public static function get_category() { $all_category = Product_category::all()->sortby('orderby_id'); $ret_category = array("" => ""); foreach($all_category as $category){ $ret_category += array($category->id => $category->category_name); } return $ret_category; } // 配列の形で、全サブカテゴリーを返す public static function get_subcategory() { $all_subcategory = Product_subcategory::all()->sortby('orderby_id'); $ret_subcategory = array("," => ""); foreach($all_subcategory as $subcategory){ // bladeが二次元配列を表示できないっぽい(print_rなら表示される…。) // しょうがないので、サブカテゴリーIDと親カテゴリーIDを文字列結合してキーとする(表示する時にカンマ分割する) $ret_subcategory += [$subcategory->id .','. $subcategory->parent_category_id => $subcategory->subcategory_name]; } return $ret_subcategory; } |
3, ProductsController::indexにてカテゴリーを取得。Viewに引き渡す
1 2 3 4 5 6 7 8 9 10 11 12 |
use App\Product_category; // 商品カテゴリー use App\Product_subcategory; // 商品サブカテゴリー class ProductsController extends Controller { public function index() { $category = Product_category::get_category(); $subcategory = Product_subcategory::get_subcategory(); return view('product.index')->with(compact('category','subcategory')); } |
4, Viewにて、セレクトボックスを実装する
laravelのbladeでは、二次元配列を扱う事が出来ない?
print_r($value)では表示されるのでviewには渡されているが、$value[0]や$value[‘name’]だとエラーになってしまう!
しょうがないので、サブカテゴリーIDと親カテゴリーIDをカンマ文字列結合して、配列キーとして使った。
また、laravelのFormファサードでカスタムデータ属性を付与する方法が分からなかったので、サブカテゴリーのセレクトボックスは<?php ~ ?>で実装した
※カスタムデータ属性は、HTML5で追加された属性です。「data-任意の文字列=好きな値」でデータを保持でき、jQueryから操作できる!
1 2 3 4 5 6 7 8 9 10 11 12 13 |
{!! Form::label('カテゴリー:') !!} {!! Form::select('category', $category, NULL, ['id' => 'category'] ) !!} <select id="subcategory"> @foreach($subcategory as $index=>$value) <?php // bladeが二次元配列を表示できないっぽい(print_rなら表示される…。) // しょうがないので、サブカテゴリーIDと親カテゴリーIDを文字列カンマ結合してキーとした。 $id = explode(',',$index); echo sprintf("<option value=%d data-parent=%d>%s</option>", $id[0], $id[1], $value); ?> @endforeach </select> |
5, このままだと、カテゴリーとサブカテゴリーが全て表示されてしまうので、jQueryで制御する
参考URL
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
<script src="http://code.jquery.com/jquery-1.11.2.min.js"></script> <script> $(function() { // 親子連動セレクトボックス(親セレクトボックス、子セレクトボックス) function parent_selectbox(ele_name_parent, ele_name_child){ var $children = $(ele_name_child); //子の要素を変数に入れます。 var original = $children.html(); //子のコピーを取っておく //親のselect要素が変更になるとイベントが発生 $(ele_name_parent).change(function() { //親のselect要素が未選択の場合、子を初期化 & disabledにして終了! if ($(this).val() == "") { $children.attr('disabled', 'disabled'); $children.val(""); return; } //選択された親のvalueを取得 var parent_val = $(this).val(); // 子をコピーから、全選択肢を復活させる $children.html(original).find('option').each(function() { // 親の値(data-parent)を取得 var child_val = $(this).data('parent'); // 違う親の値(data-parent)だったら、選択肢を削除する if (parent_val != child_val) { $(this).not(':first-child').remove(); } // 結果、選択された親の子しか残されない }); // 子を有効化して選択できるようにする $children.removeAttr('disabled'); // 編集画面用に、最初に1回だけ選択した状態にする }).trigger('change'); } // カテゴリー・サブカテゴリー連動セレクトボックス parent_selectbox('#category', '#subcategory'); }) </script> |
これで、MySQLのレコードを使った親子セレクトボックスを実装できた!