
目次
- Formファサードはとりあえず使わない
- べた書きで画面イメージを確認するサンプル
- 選択値をコントローラで受け取るサンプル
- コントローラクラスで初期値をセットするサンプル。
- Bladeテンプレート側で配列変数を処理するサンプル
- 実行イメージ
今回は、入力画面でよく使う部品である、SELECTについて整理します。
Formファサードはとりあえず使わない
Laravelには「Formファサード」があります。
これは標準インストールには含まれません。
別途インストールすれば使えます。
それを使えば、例えば、SELECTならこんな感じで書けます。
{{Form::select('size', ['L' => 'Lサイズ', 'S' => 'Sサイズ'], 'S', ['placeholder' => 'null'])}}
便利そうには見えますが、今回は使いません。
理由は「依存するのが怖い気がするから」です。
最新では標準に含まれていないけど、以前は標準に含まれていた・・というパターンの機能に依存して、後で後悔する・・パターンは、さんざん体験してきましたから。
べた書きで画面イメージを確認するサンプル
blade.phpファイルだけ編集して、画面表示から確認します。
まずはベタ書きで。
単一選択のSELECT(プルダウン)
<div class="form-group row">
<label for="sel01" class="col-md-4 col-form-label text-md-right">性別</label>
<div class="col-md-6">
<select class="form-control" id="sel01" name="sel01">
<option value="1">男性</option>
<option value="2" selected>女性</option>
</select>
</div>
</div>
表示すると、こうなります。

複数選択のSELECT
<div class="form-group row">
<label for="sel02" class="col-md-4 col-form-label text-md-right">選択言語</label>
<div class="col-md-6">
<select multiple class="form-control" id="sel02" name="sel02[]">
<option value="ja" selected>日本語</option>
<option value="en">英語</option>
<option value="de">ドイツ語</option>
<option value="zh">中国語</option>
</select>
</div>
</div>
表示するとこうなります。

単一SELECTとことなり、注意することがひとつ。
<select multiple class="form-control" id="sel02" name="sel02[]">
この部分の「name="sel02[]"」のように、multipleの場合は、nameを配列で定義しておく必要があることです。
こうしておかないと、複数選択された結果をコントローラ側で配列で受け取ることができず、一番最後に選択された値のみになってしまします。
選択値をコントローラで受け取るサンプル
nameを設定しているので、Requestクラスオブジェクトで、選択値を受け取れます。
public function store(Request $request)
{$sel01 = $request->sel01;
$sel02 = $request->sel02;}
この各変数に何がはいっているか?です。
まず、単一選択の$sel01には"1"または"2"など、選択されたoptionのvalue値です。
複数選択の$sel02は、選択されたoptionのValue値が配列ではいってきます。
なので、大抵の場合「implode」関数などを使って
$sel02ForSave = implode(',', $sel02)
のようにして「ja,de,en」のような選択されたValue値をカンマつなぎのテキストに変換してDBに保存したりします。
コントローラクラスで初期値をセットするサンプル。
DBからデータを読み込んだ・・体で、コントローラクラスから初期値をわたして表示するケースです。
Http\Controllers\DummyController.php
public function index()
{
$sel01Mock = "2";
$sel01Datas = [
"1" => "男性",
"2" => "女性"
];
$sel01Selected = [
"1" => "",
"2" => ""
];
$sel01Selected[$sel01Mock] = "selected";
$sel02Mock = preg_split("/,/", "en,zh");
print_r($sel02Mock);
$sel02Datas = [
"ja" => "日本語",
"en" => "英語",
"de" => "ドイツ語",
"zh" => "中国語"
];
$sel02Selected = [
"ja" => "",
"en" => "",
"de" => "",
"zh" => ""
];
foreach ($sel02Mock as $key => $val) {
$sel02Selected[$val] = "selected";
}
return view('dummy', compact(
'sel01Datas',
'sel01Selected',
'sel02Datas',
'sel02Selected'
));
}
単一SELECTと複数SELECTの両方共、コントローラでoptionの選択肢と、初期選択状態(selected)をセットしてます。
補足していきます。
単一SELECT
こちらの「DBから取得した体」は「$sel01Mock = "2";」です。
前半の例のとおり、コントローラクラスではRequestオブジェクトから、選択された「Value値」が取得できますから、DBに保存するとしたら、その値です。
つまり、"2"の女性が選択されていたものを保存して、DBから取得した想定です。
データと同じキーで「 $sel02Selected」配列を用意して、$sel01Mockの値をキーにして「selected」をセットするわけです。
複数SELECT
こちらの「DBから取得した体」は「$sel02Mock = preg_split("/,/", "en,zh");」です。
前半の例で、Multipleの場合は選択されたValue値が配列でわたってくるので、DBに保存するときには「カンマつなぎ」の文字列にして保存すると書きました。
こちらの例はその想定で、enとzhが選択されてDBに保存されていたものを読み出し、カンマで分割して、配列に戻しているわけです。
なので。
foreach ($sel02Mock as $key => $val) {
$sel02Selected[$val] = "selected";
}
こんな感じで、$sel02Selected配列を用意して、配列の値をキーにして「selected」をセットすれば良いわけです。
Bladeテンプレート側で配列変数を処理するサンプル
上記のコントローラで設定し受け渡した配列変数を処理するVIEW側です。
単一SELECT
<div class="form-group row">
<label for="sel01" class="col-md-4 col-form-label text-md-right">性別</label>
<div class="col-md-6">
<select class="form-control" id="sel01" name="sel01">
@foreach($sel01Datas as $key01 => $val01)
<option value="{{$key01}}"
@if(empty(old())) {{ $sel01Selected[$key01] }}
@elseif(old('sel01')==$key01) selected
@endif
>{{$val01}}</option>
@endforeach
</select>
</div>
</div>
SELECTのプルダウンリストに出力する表示項目情報は以下のループで取り出します。
@foreach($sel01Datas as $key01 => $val01)
ここで、$sel01Datasにはコントローラで
$sel01Datas = [ "1" => "男性", "2" => "女性" ];
のようにセットされているので、それを1セットずつ取り出して<option>タグを組み立てればよいわけです。
でも。
それだけでは初期表示時に明示的に「選択された状態」にすることはできません。
選択された状態にするポイントは、以下の@if~ @endifの部分です。
@if(empty(old())) {{ $sel01Selected[$key01] }}
@elseif(old('sel01')==$key01) selected
@endif
表示するケースとして
- 初期表示時にSELECTED(選択状態)にする。
- バリデーションエラーで戻った時に直前の選択状態を復元する
の2つがあります。
初期表示時は「old()」が空(empty)になりますから、それを利用して。
@if(empty(old())) {{ $sel01Selected[$key01] }}
で、コントローラでセットした「SELECTED」文字列を適用する・しないで制御することができます。
逆に、バリデーションエラーで戻った時は「old('sel01')」で直前に選択されていたValue値が取得できますから、それと一致するものに「SELECTED」をつけることで復元することができます。
マルチSELECT
マルチSELECTの場合も理屈は同じです。
ただ、SELECTEDになる項目が1つではないので、そこだけ配慮がいります。
ソースはこんな感じです。
<div class="form-group row">
<label for="sel02" class="col-md-4 col-form-label text-md-right">選択言語</label>
<div class="col-md-6">
<select multiple class="form-control" id="sel02" name="sel02[]">
@foreach($sel02Datas as $key02 => $val02)
<option value="{{$key02}}"
@if(empty(old())) {{$sel02Selected[$key02]}}
@elseif(in_array($key02,old('sel02'))) selected
@endif
>{{$val02}}</option>
@endforeach
</select>
</div>
</div>
表示項目のセットや、初期表示字のSELECTED(選択状態)の指定はほぼ同じです。
ただ。
@if(empty(old())) {{$sel02Selected[$key02]}}
@elseif(in_array($key02,old('sel02'))) selected
@endif
の「バリデーションエラーで戻った場合の直前の選択状態の復元」時、「 old('sel02')」で返されるのは「配列」であるという点が違います。
そのため単純に「==」などで比較はできません。
PHP関数の「in_array()」を使って、$key02の値が「 old('sel02')」で返される配列に含まれているかどうかで判断して、SELECTEDをつけています。
実行イメージ
MariaDB(MySQL)を起動し、ビルトインサーバーを動かします。
php artisan serve
それで以下のURLで動かしてみます。
初期表示は

2種類のSElECTで項目表示と初期選択はできています。
これを、「男性」「日本語」「ドイツ語」を選択に変更したうえで、コード・名前・カナを適当に入力して、バリデーションエラーを発生させます。

バリデーションエラーの直前の状態が、SELECTでも復元されてます。
OKそうですね。
このパターンを覚えておけば、SELECTはいけそうですね。
今回はこんなところで。
ではでは。