Laravel5では、ビューで利用するForm、Htmlファサードを含むコンポーネントはコアから外され、コミュニティパッケージLaravel CollectiveからForm & Htmlとして提供されています。
Laravelフレームワークが提供するbladeテンプレートの機能だけでもそこまで困ることは無いですが、フォーム要素の中でとくに扱いが面倒なプルダウン(select
要素)とチェックボックスあたりはやはり便利なので入れておいた方が良いパッケージです。
セットアップ手順
利用するための手順は以下の通りです(Laravel 5.5で確認)。
Composerでコンポーネントを追加
$ composer require "laravelcollective/html":"^5.4.0"
プロバイダとファサードの登録
v5.6以前のドキュメントには、config/app.php
にproviders
とalias
に設定を追加するように書いてありますが、現在は、composer.json
のextra.laravel
にロードすべきプロバイダとファサードが指定してあるので、手動で追加する必要はありません。
// laravelcollective/htmlのcomposer.json
"laravel": {
"providers": [
"Collective\\Html\\HtmlServiceProvider"
],
"aliases": {
"Form": "Collective\\Html\\FormFacade",
"Html": "Collective\\Html\\HtmlFacade"
}
}
参照: Package Development – Laravel – The PHP Framework For Web Artisans
使い方
Bootstrapを利用したフォームの実装例で説明してみます。
Laravel 5.5 は bootstrap-sass を利用しているので、Bootstrapのバージョンは3になります。
$ php artisan make:model Customer -mc
マイグレーションには以下のようなフィールドを追加します。
// database/migrations/YYYY_MM_DD_070946_create_customers_table.php
public function up()
{
Schema::create('customers', function (Blueprint $table) {
$table->increments('id');
$table->string('name'); // テキスト
$table->string('state'); // プルダウン
$table->integer('age'); // プルダウン
$table->boolean('has_contract'); // チェックボックス
$table->timestamps();
});
}
コントローラは、フォームのテンプレート resources/views/customer/create.blade.php
を返すcreate
アクションと、フォームのPOST先のアクションstore
のみを実装しておきます。
store
アクションはPOSTされたリクエストパラメータをflashしてフォームにリダイレクトするだけです。これは、テンプレートでパラメータの値をold
メソッドで取得し、セットし直す動作を確認するための最小限の実装をしています。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class CustomerController extends Controller
{
public function create() {
return view('customer.create');
}
public function store(Request $request) {
// TODO store customer
$request->flash();
return redirect()->route('customer.create');
}
}
ルーティングに以下を追加しておきます。
Route::get('/customer/create', 'CustomerController@create')->name('customer.create');
Route::post('/customer/store', 'CustomerController@store')->name('customer.store');
フォームのテンプレートは以下のようになります。
<!doctype html>
<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>LaravelCollective/HTML</title>
<link rel="stylesheet" href="{{ asset('css/app.css') }}">
<style>
html, body {
background-color: #fff;
color: #636b6f;
font-family: 'Raleway', sans-serif;
font-weight: 100;
height: 100vh;
margin: 1.5rem;
}
</style>
</head>
<body>
{{ Form::open(['route' => 'customer.store']) }}
<div class="form-group">
<label>氏名</label>
{{Form::text('name', old('name'), ['class' => 'form-control'])}}
</div>
<div class="form-group">
<label>都道府県</label>
{{Form::select('state', ['01' => '北海道', '02' => '青森'], old('state'), ['class' => 'form-control'])}}
</div>
<div class="form-group">
<label>住所</label>
{{Form::textarea('address', old('address'), ['class' => 'form-control', 'rows' => '3'])}}
</div>
<div class="form-group">
<label>年齢</label>
{{Form::selectRange('age', 20, 100, old('age'), ['class' => 'form-control'])}}
</div>
<div class="form-group">
<label>購入済み</label>
{{Form::checkbox('has_contract', 'true', old('has_contract'))}}
</div>
<div>
{{Form::submit('保存', ['class' => 'btn btn-primary'])}}
</div>
{{ Form::close() }}
</body>
</html>
上記コードのポイントとしては、スタイルシートcss/app.css
を読み込んでBootstrapのスタイルシートを適用していること、flash
した入力データをold関数で取得して値にセットし直しているあたりです。
実行結果は以下、フォームを適当に入力して[保存]すると値が保持されていることを確認できます。(コントローラの$request->flash
を削除すると保持されないことも確認できます)