Laravelでプルダウンを書いているけど、optionをたくさん書く方法しかわからない….もっと簡単に修正に強い書き方はないかな….
こんな疑問を解決します。
プルダウンを書いていて、もっと実務で使える方法ないかな…って思いますよね。
いつまでも初心者のようなコードを書いていても成長はありません。
今回は、optionをたくさん書かずに、foreachを使ってプルダウンをスマートに書く方法を現役エンジニアが解説します。
- スマートにプルダウンを書く方法がわかる
- クソコードから脱却できる
休日で空いた時間の暇つぶしを探せるアプリを公開しています。
開発環境
Docker 20.10.7
PHP 7.4.22
Laravel 8.53.1
mySQL 5.7
データベースのツール phpmyadmin
dockerで動作確認をしておりますが、基本的にMAMP環境とかでも動くと思います。
また、Laravelのバージョンが8なので6系を使っていたら多少記述が違ってくると思います。
ex.ルーティングの書き方やApp\Book→App\Models\Bookなど
想定するもの
本を管理するアプリを想定しており、「カテゴリーのプルダウンを作成してほしい」という依頼がきたとします。
プルダウンは以下を想定
その場合、初心者でありがちなのがoptionタグをひたすら書いてしまうこと。これだと順番が入れ替わったりしたときに修正が大変です。
なので、optionタグをひたすら書くというクソコードから脱却してforeachなどを使ってみましょう。
初心者が書きがちなプルダウンのコード例
<!-- カテゴリープルダウン -->
<div class="form-group">
<label for="category-id">{{ __('カテゴリー') }}<span class="badge badge-danger ml-2">{{ __('必須') }}</span></label>
<select class="form-control" id="category-id" name="category_id">
<option value="1">PHP</option>
<option value="2">Ruby</option>
<option value="3">Laravel</option>
<option value="4">Java</option>
<option value="5">jQuery</option>
</select>
</div>
こんな感じでoptionを増やしがちです。
サンプルコードのように5個ぐらいならこれでも問題ないのですが、データが1000個とかになったら1000こoption描かなくちゃいけないし、数字が変わったらメンテナンスも大変です。
なので、実務では絶対NGなクソコードになります。
ちなみにclass名にform-controllとかbadge-dangerとかありますが、これはbootstrapを導入したときに以下のように認識してくれます。
実務で使えるプルダウン
事前準備としてカテゴリーテーブルを作成する必要があります。
var/www/html/tests_app# php artisan make:migration create_categories_table --create=categories
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateCategoriesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->id('category_id');
$table->string('category_name', 255);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('categories');
}
}
$table->id(‘category_id’);ですがlaravel7以降から導入された記述方法です。laravel6系の場合は、$table->bigIncrements(‘category_id’);としてください。
あとはマイグレートを実行して、カテゴリーテーブルを作成しましょう。
var/www/html/tests_app# php artisan migrate
準備はできたので、早速プルダウンでスマートに書く方法の解説です。まずはコードから。
foreachを使って以下のように書くのがシンプルでおすすめです。
<!-- カテゴリープルダウン -->
<div class="form-group">
<label for="category-id">{{ __('カテゴリー') }}<span class="badge badge-danger ml-2">{{ __('必須') }}</span></label>
<select class="form-control" id="category-id" name="category_id">
@foreach ($categories as $category)
<option value="{{ $category->category_id }}">{{ $category->category_name }}</option>
@endforeach
</select>
</div>
解説します。
先程のoptionたくさん状態からforeachを使ってoptionは一つだけになりました。
これでも同様の結果が得られます。
一番気になるのが、ここでしょう。
@foreach ($categories as $category)
<option value="{{ $category->category_id }}">{{ $category->category_name }}</option>
@endforeach
やってることとして、コントローラーで$categoriesを定義し、それをビューにわたします。
$categoriesには、カテゴリーテーブルにあるデータが全て取得されるようにして、それをforeachで一つずつデータを取り出しています。
valueには取得したcategory_id、表示名にはcategory_nameを書くことでオッケーです。
$categoriesはコントローラーで定義しましょう。
コントローラー
public function __construct()
{
$this->category = new Category();
}
/**
* 登録画面
*/
public function create(Request $request)
{
$categories = $this->category->get();
return view('book.create', compact('categories'));
}
// 解説
get()で取得したいデータを全てコレクションとして取り出せます。
詳しくはlaravel公式ドキュメントのgetを参照ください。
compact関数で、ビューに変数を渡せます。
compact('$をなくした変数名')って感じで使えます。
withを使う場合は、
with('categories',$categories)と書けばいいのですが、私はが書く量が少ないのでcompact関数をいつも使っています。
configファイルを使う場合
今回はタグのプルダウンをconfigを使って作成する予定です。
config配下にファイル名はなんでもいいですがわかりやすいようにtag.phpを作成しましょう。
config>tag.phpになります。
(config>tag.php)
<?php
return [
'tag_name' => [
1 => '面白い',
2 => '最高',
3 => 'つまらない'
]
];
<!-- タグープルダウン -->
<div class="form-group">
<label for="tag-id">{{ __('タグ') }}<span class="badge badge-danger ml-2">{{ __('必須') }}</span></label>
<select class="form-control" id="tag-id" name="tag_id">
@foreach (Config::get('tag.tag_name') as $key => $val)
<option value="{{ $key }}">{{ $val }}</option>
@endforeach
</select>
</div>
ポイントは、以下の部分です。
@foreach (Config::get('tag.tag_name') as $key => $val)
<option value="{{ $key }}">{{ $val }}</option>
@endforeach
Config::get(‘configファイル名.キー名’)をfoeaechでキーと値を一つずつ取り出すことで、value値にはそれぞれの値が入り(1,2,3)、{{ $val }}で対応する表示名を出力できます。
このようにプルダウンを作成する際は、変数を使ってスマートに書いていきましょう!!
もしわかりずらいところなどがあればコメントにてお知らせください。
編集画面で初期表示はDBの値、エラー時はoldの値を保持するには?
編集画面で、
- プルダウンの初期表示はDBの値を表示させる
- プルダウンを変更したときにバリデーションに引っかかってしまった場合は、oldの値を保持させて選択した値にしておく
こんな感じの実装をする場合は以下のように書けます。
<div class="form-group">
<label for="post_code">{{ __('投稿番号') }}<span class="badge badge-secondary ml-2">{{ __('任意') }}</span></label>
<select class="form-control{{ $errors->has('post_code') ? ' is-invalid' : '' }}" name="post_code" id="post-code">
<option></option>
@foreach ($posts as $post)
@if (!is_null(old('post_code')))
<!-- バリデーションエラー等による再表示時 -->
@if ($post->post_code == old('post_code'))
<option value="{{ $post->post_code }}" selected>{{ $post->post_name }}</option>
@else
<option value="{{ $post->post_code }}">{{ $post->post_name }}</option>
@endif
@else
<!-- 初期表示時 -->
@if ($post->post_code == $user->code)
<option value="{{ $post->post_code }}" selected>{{ $post->post_name }}</option>
@else
<option value="{{ $post->post_code }}">{{ $post->post_name }}</option>
@endif
@endif
@endforeach
</select>
@if($errors->has('post_code'))
<div class="invalid-feedback">
{{ $errors->first('post_code') }}
</div>
@endif
</div>
休日で空いた時間の暇つぶしを探せるアプリを公開しています。
コメント