35
Help us understand the problem. What are the problem?

posted at

updated at

【Laravel】初めてのフォーム作成

  • Bladeでの送信フォーム作成時の備忘録。

フォームの導入

  • Laravelでは、LaravelCollective をインストールしないと、フォームを作成できない。
インストール
% composer require laravelcollective/html

Bladeでのフォーム作成

  • エスケープしたい時は、{{ }}、 エスケープしたくない時は、{!! !!} で記述する。

■ フォームの開始

  • デフォルトでは、method: POST。HTMLがサポートしてる隠しフィールドは、POSTとGETだけ
  • PUTやDELETEは、_methodの追加が必要(例えば、編集フォーム、削除ボタンなど)。
  • 参)postで送信したものは、$_POST['name属性名']に格納される(配列でも同様)。
    • $_GET:postで送信したもの。URLの ? 以降も含む情報。
    • $_COOKIE:ブラウザから送信されたクッキー情報。
    • $_REQUEST:$_GET、$_POST、$_COOKIE の全て。
    • $_SESSION:サーバー側に保存される変数。

- 新規投稿フォーム

フォーム入力データの送信先の指定方法のイロイロ
{{ Form::open([ データ送り先の指定  action, ファイル使用の有無]) }}
{{ Form::open(['url' => '/']) }}                                 // URLパスでの指定
{{ Form::open(['url'=>'foo/bar', 'files'=>true]) }}              // ファイルのアップロードの場合(filesオプション)
{{ Form::open(['route' => 'route.name']) }}                      // 定義したルーティングでの指定
{{ Form::open(['route' => ['route.name', $user->id]]) }}         // パラメーター(/{●●}の部分)も一緒に渡す
{{ Form::open(['action' => 'Controller@method']) }}              // コントローラーアクションでの指定
{{ Form::open(['action' => ['Controller@method', $user->id]]) }} // パラメーターも一緒に渡す
{{ Form::open(['route' => ['user.update', 'user' => $user->id], 'method' => 'put']) }}

// POST以外のメソッドを指定する場合
{{ Form::open(['method'=>'put', 'url'=>'/']) }}
{{ Form::open(['method'=>'delete', 'route' => ['article.destroy', $article->id] ]) }}
        :
{{ Form::close() }}

- デフォルトでテーブルからデータを表示したい場合

  • 編集フォームなど、既に入ってる値を取得して、フォームに表示させたい場合。
  • 注) Form::model では、初期値をnullにする必要がある!!
    • null 部分に、取得した値を入れてくれるから。
編集フォーム
{{ Form::model($user, ['route'=>['user.update', $user->id]]) }}   // POSTメソッドの場合
{{ Form::model(['method'=>'put', 'url'=>'foo/bar']) }}            // PUTメソッド(編集フォームなど)
{{ Form::model(['method'=>'delete', 'url'=>'foo/bar']) }}         // DELETEメソッド(データ削除ボタンなど)
// 例
{{ Form::model($article, ['method'=>'put', 'route'=>['article.update', $article->id], 'class'=>'form-article' ]) }}
  {{ Form::text('name', null, ['placeholder'=>'名前を入力']) }}
  {{ Form::select('category_id', $categories) }}
  {{ Form::select('type', ['タイプ1'=>'名前1', 'タイプ2'=>'名前2'], null, ['data-rel'=>'chosen']) }}
  // 異なるテーブルから既存データを取得表示したい場合
  {{ Form::label('brand[name]', 'Brand (name1)', array('class' => 'brand')) }}
  {{ Form::text('brand[name1]') }}
        :
{{ Form::close() }}

■ CSRF対策

  • Laravelはクロスサイトリクエストフォージェリから保護する方法がある。
    • Form::openで、POST、PUT、DELETEメソッドでは、自動でCSRFトークンが追加されてる
    • 隠しCSRFフィールドを自分で追加したい時は、tokenメソッド。
自分でCSRFトークンを追加する方法
// Bladeのフォームに設置する場合
  {{ Form::token() }}
//ルートにCSRFフィルターを設置する場合
  Route::post('profile', ['before'=>'csrf', function(){
       :
  }]);

■ ラベル

  • ラベル名と同じ名前のフォーム要素は、自動で、ラベル名と同じidを取得する。
{{ Form::label('関連付けるカラム名', '表示する文字', ['class'=>'クラス名', ..]) }}
{{ Form::label('name', 'なまえ', ['class'=>'post_name']) }}

■ text、textarea、hidden

text、textarea、hidden用フォーム
{{ Form::text('カラム名', 'デフォルト値', ['class'=>'クラス名', 'placeholder'=>'プレースホルダー', ..]) }}
{{ Form::text('titel', 'タイトル') }}
{{ Form::text('name', old('name', $user->name), ['class' => 'form-control']) }}
{{ Form:: textarea('content', null, ['placeholder' => '入力してください', 'rows' => '5']) }}
{!! Form::textarea('memo', old('memo', $user->memo), ['class' => 'form-control']) !!}

{{ Form::hidden('test', 1) }}          // name='test'、 type='hidden'、 value='1'
{{ Form::hidden('test[]', $tests) }}   // 配列を渡したい時

■ パスワード

  • セキュリティ的に、value属性は設定できない仕様。初期値設定は不可。
パスワード用フォーム
{{ Form::password('カラム名', ['class'=>'クラス名', ..]) }}
{{ Form::password('password', ['class'=>'awesome']) }}

■ メールアドレス

メールアドレス用フォーム
{{ Form::email('カラム名', , 属性など) }}
{{ Form::email('owner_email', 'xxxxx@gmail.com', ['class'=>'field']) }}

■ ファイル

  • フォーム開始時に、「 'files' => true 」にしとく必要がある。
  • セキュリティ的に、value属性は設定できない仕様。初期値設定は不可。
ファイル投稿フォーム
{{ Form::file('カラム名', ['class'=>'クラス名', ..]) }}
{{ Form::file('image') }}
{{ Form::file($name, $attributes = []) }}

■ チェックボックス、 ラジオボタン

チェックボックス、ラジオボタン
{{ Form::checkbox('カラム名', '送信する値', デフォルト値の指定(checked), ['class'=>'クラス名', ..]) }} 
{{ Form::checkbox('name', 'value') }}
{{ Form::checkbox('name', 'value', true) }}  // デフォルトを選択済みにする
// 使用例
@foreach($array as $key => $val)
  {{ Form::checkbox('sample_check[]', $key, in_array($key, old('sample_check', $user->sample_check)), ['id' => 'check'.$key]) }}
  {{ Form::label('check'.$key, $val) }}
@endforeach

{{ Form::radio('name', 'value') }}
{{ Form::radio('name', 'value', true) }}     // デフォルトを選択済みにする
// 使用例
{{ Form::radio('score', $i, $i == old('score', $review->score)) }}
{{ Form::radio('gender', 'male', (old('gender')== 'male' ? true : ($user->gender == 'male')) ? true : false, ['class' => 'radio-button']) }}
@foreach($array as $key => $val)
  {{ Form::radio('sample_radio', $key, ($key == old('sample_radio', $user->sample_radio)), ['id' => 'radio'.$key]) }}
  {{ Form::label('radio'.$key, $val) }}
@endforeach

■ ドロップダウン

ドロップダウン
{{ Form::select('カラム名', 配列(キー/), 'デフォルト値(キー名)', ['placeholder' => 'null']) }}
{{ Form::select('size', ['L'=>'Large', 'S'=>'Small']) }}        // デフォルト値、placeholderの指定ない時は、配列の最初の要素が表示される
{{ Form::select('category_id', $categories) }}                  // コントローラーなどで、配列を定義してる場合  
{{ Form::select('size', ['L'=>'Large', 'S'=>'Small'], 'S') }}   // デフォルト値を選択済みにする
{{ Form::select('size', ['L'=>'Large', 'S'=>'Small'], null, ['placeholder'=>'選択してください']) }}  // 空のプレースホルダー(optionタグに、空の要素が作成される)

// グループ分けしたリスト
{{ Form::select('animal', [
  'Cats'=>['leopard'=>'Leopard'], 
  'Dogs'=>['spaniel'=>'Spaniel'] ])
}}

// 範囲を指定して、ドロップダウンリストを作成
{{Form::selectRange('カラム名', 範囲(数値orアルファベット), デフォルト値(selected), ['class'=>'クラス名', ..])}}
{{ Form::selectRange('number', 10, 20, null, ['class'=>'size']) }}

// 月名を指定して、ドロップダウンリストを生成
{{ Form::selectMonth('カラム名', デフォルト値(数値), ['class'=>'クラス名', ..]) }}
{{ Form::selectMonth('month') }}    

{{ Form::select('sample_id', $array , old('sample_id', $user->sample_id) , ['class' => 'form-control']) }}         

■ 数値入力フォーム

数値入力フォーム
{{ Form::number('カラム名', 送る値, ['class'=>'クラス名']) }}
{{ Form::number('age', 25) }}

■ 日付

日付入力フォーム
{{ Form::date('カラム名', 送る値, ['class'=>'クラス名', ..]) }}
{{ Form::date('day', \Carbon\Carbon::now()) }}  // 今日を指定する場合

■ URL

  • HTMLリンクの生成。
URLの生成
// URLへのHTMLリンクの生成 (link_to)
echo link_to('foo/bar', $title = null, $attributes = [], $secure = null);

// アセットへのHTMLリンク生成 (link_to_asset)
echo link_to_asset('foo/bar.zip', $title = null, $attributes = [], $secure = null);

// 名前付きルートへのHTMLリンク生成 (link_to_route)
echo link_to_route('route.name', $title = null, $parameters = [], $attributes = []);

// コントローラーアクションへのHTMLリンク生成 (link_to_action)
echo link_to_action('ArticleController@getIndex', $title = null, $parameters = [], $attributes = []);

■ 送信ボタン

  • buttonメソッドも同じ使い方ができる。
送信ボタン
{{ Form::submit('送信ボタン', ['class'=>'クラス名', ..]) }}

{{ Form::button('登録', ['type' => 'submit', 'onfocus' => 'this.blur();']) }}
{{ Form::button('リセット', ['type' => 'reset']) }}
{{ Form::reset('リセット') }}

参) フォームマクロ

  • マクロに名前とクロージャーを登録して、その名前で呼び出して使う。
  • 定義方法: Form::macro 。
フォームマクロの使い方
Form::macro('myField', function() {
  return '<input type="awesome">';
});

// カスタムマクロフォームの呼び出し
{{ Form::myField() }}

参) カスタムコンポーネント

  • クロージャを使って、Bladeを生成するもの。
  • サービスプロバイダーのbootメソッド内にコンポーネントを定義して使う。

参) フォームモデルアクセサー

  • LaravelのEloquentAccessorを使うと、モデル属性を返す前に操作できる。
    • 例えば、日付形式を定義する場合などに便利。フォームの形式と一致しない場合は、標準アクセサー or フォームアクセサーを作成する。
  • モデルでメソッドを定義して、Form::model で呼び出す流れ。

参) 入力値を連想配列として送信したい

  • inputタグのname属性を"配列名[キー名]"にすれば、連想配列で送信できる(※ "配列名['キー名']"ではないことに注意)。

フォームの入力欄の長さで使うBootstrap例

class名
.size-xs-100
.size-sm-50
[xs]-[sm]-[md]-[lg]
5~100%で5%刻み
.size-xs-** xs以上の時、**% の長さ
(**は、5~100%の間で5%刻み)
.size-sm-** sm以上の時、**% の長さ
.size-md-** md以上の時、**% の長さ
.size-|g-** lg以上の時、**% の長さ
.size-input-name 氏名:全角15文字
.size-input-nameS 氏名(分割):全角7文字
.size-input-company 会社名:全角16文字
.size-input-division 部署名:全角16文字
.size-input-quantity 従業員数:全角4文字
.size-input-zip 郵便番号:半角7文字
.size-input-zip3 郵便番号:半角3文字
.size-input-zip4 郵便番号:半角4文字
.size-input-pref 都道府県:全角5文字
.size-input-address 住所:全角25文字
.size-input-tel 電話番号:半角14文字
.size-input-telS 電話番号(分割):半角4文字
.size-input-homepage webサイト:半角60文字
.size-input-email メールアドレス:半角34文字
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
35
Help us understand the problem. What are the problem?