Laravelでフォームの生成

今日は、Laravelでフォームの生成について調べてみましょう。『LaravelでHTMLの生成』の最初の方で、HTMLエンティティについて検証してみました。クロスサイトスクリプティング攻撃を最も受ける可能性の高いのが、このフォームからの入力です。

Laravelでは、フォーム要素に表示される全ての入力データはHTML::entitiesメソッドを通してフィルタリングされるみたいですので、安心ですね。

Formクラスの各メソッド

1. まず最初に、Formクラスの各メソッドを調べていきましょう。各メソッドは静的メソッドですので、Form::メソッド名()でHTMLタグを生成します。

  • open(‘URI,リクエスト方法,HTML属性)
    openメソッドは、フォームを開くときに使用します。第1引数がリクエスト先のURI(パス)、第2引数がリクエスト方法(GET、POST、PUT等)、第3引数がHTML属性(id、class、style、title等)を配列で指定します。第1引数のデフォルト値は現在のURI、第2引数のデフォルト値はPOSTです。引数を全て省略すると、現在のURIへPOSTするフォームを開きます。
  • close()
    closeメソッドは、フォームを閉じるタグ</form>を生成します。
  • token()
    tokenメソッドは、セッションのCSRFトークンを埋め込む隠しフィールドを生成します。そして、CSRFトークンを受け取るには、Sessionクラスのtokenメソッドを使用します。尚、LaravelのCSRFプロテクション機能を使用する前に、セッションドライバーを指定する必要がありますので、tokenメソッドについては、後日セッションクラスを調べるときに同時に検証したいと思います。
  • label(ラベル名,表示名,HTM属性) 
    labelメソッドは、ラベルタグを生成します。第1引数がラベル名、第2引数がそのラベルの表示名、第3引数にラベルに追加するHTML属性を配列で指定します。尚、ラベル生成後にラベル名と一致する名前のHTML要素は、その名前と同じIDも生成されます。
  • text(要素名,既定値,HTML属性)
    textメソッドは、テキスト入力要素を生成します。 第1引数が要素名、第2引数は既定(デフォルト)値、第3属性がHTML属性の配列です。
  • hidden(要素名,既定値,HTML属性)
    heddenメソッドは、hidden要素(隠し文字)を生成します。上記、textメソッドとほぼ同様です。
  • textarea(要素名,既定値,HTML属性)
    textaraメソッドは、textara要素を生成します。これも上記、textメソッドとほぼ同様です。
  • password(要素名,既定値,HTML属性)
    これも上記、textメソッドとほぼ同様ですが、入力値がブラウザ上では黒丸で表記され、入力値が見えないようになっています。
  • checkbox(要素名,値,チェック状態)
    checkboxメソッドは、チェックボックス要素を生成します。第3引数は、チェックがONかOFFかの指定です。第3引数をtrueに指定するとcheckboxのチェックがONになります。
  • radio(要素名,値,チェック状態)
    radioメソッドは、ラジオボタン要素を生成します。上記のcheckboxメソッドとほぼ同様です。
  • select(要素名,選択値の配列,初期値)
    selectメソッドは、select要素(ドロップダウンリスト)を生成します。第2引数にリストの配列をセットします。第3引数は、初期選択値を指定します。
  • submit(表示文字列)
    submitメソッドは、submitボタンを生成します。尚、submitメソッドと同様の働きをするbuttonメソッドもあります。

Bladeテンプレートでフォームの生成

2. それでは、実際にフォームを作成してみましょう。formビューファイルを下記のように作成します。尚、Bladeテンプレートで作成しますので、Bladeテンプレートについては、『LaravelのBladeテンプレート』を一読下さい。

laravel/application/views/hello/form.blade.php

@layout('layouts.master')
@section('content')
 {{ Form::open('hello/form','POST',array('class'=>'form-horizontal')) }}
 <fieldset>
 <div class="control-group">
 {{ Form::label('username','ユーザー名',array('class'=>'control-label')) }}
 <div class="controls">
 {{ Form::text('username') }}
 </div>
 </div>
 <div class="control-group">
 {{ Form::label('email','Eメール',array('class'=>'control-label')) }}
 <div class="controls">
 {{ Form::text('email','nakada@winroad.info') }}
 </div>
 </div>
 <div class="control-group">
 {{ Form::label('password','パスワード',array('class'=>'control-label')) }}
 <div class="controls">
 {{ Form::password('password') }}
 </div>
 </div>
 <div class="control-group">
 {{ Form::label('sex','性別',array('class'=>'control-label')) }}
 <div class="controls">
 <div class="control-group form-inline">
 {{ Form::label('men','男性',array('class'=>'span1')) }}
 {{ Form::radio('men','1',true) }}
 </div>
 <div class="control-group form-inline">
 {{ Form::label('famale','女性',array('class'=>'span1')) }}
 {{ Form::radio('famale','2') }}
 </div>
 </div>
 <div class="control-group">
 {{ Form::label('native','出身地',array('class'=>'control-label')) }}
 <div class="controls">
 {{ Form::select('native',array('1'=>'関東','2'=>'関西','3'=>'他'),'1') }}
 </div>
 </div>
 <div class="control-group">
 {{ Form::label('textarea','ご意見',array('class'=>'control-label')) }}
 <div class="controls">
 {{ Form::textarea('textarea','',array('rows'=>'3','class'=>'span6','placeholder'=>'ご意見をお聞かせ下さい')) }}
 </div>
 </div>
 </div>
 <div class="form-actions">
 {{ Form::submit('フォーム送信',array('class'=>'btn btn-primary')) }}
 </div>
 </fieldset>
 {{ Form::close() }}
 @endsection

3. Helloコントローラに下記のformアクションを作成します。

laravel/application/controllers/hello.php

public function action_form(){
 return View::make('hello.form');
 }

4. 又は、formアクションを作成せずに、ルーターに下記のように記述しても同様にビューファイルを表示します。

laravel/application/routes.php

Route::get('hello/form',function(){
 return View::make('hello.form');
 });

5. ブラウザで確認してみます。

6. 一応念のため、上記ブラウザのHTMLソースを下記に表示しておきますので、参考にして下さい。

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>マスタービュー</title>
<meta name="viewport" content="width=device-width,minimum-scale=1">
<link href="http://localhost/laravel/public/bootstrap/css/bootstrap.min.css" media="all" type="text/css" rel="stylesheet">
<link href="http://localhost/laravel/public/bootstrap/css/bootstrap-responsive.min.css" media="all" type="text/css" rel="stylesheet">
<!--
<link href="bootstrap/css/bootstrap.min.css" rel="stylesheet">
<link href="bootstrap/css/bootstrap-responsive.min.css" rel="stylesheet">
-->
</head>
<body>
<div class="navbar">
<div class="navbar-inner">
<a class="brand" href="#">WinRoad徒然草</a>
<ul class="nav">
 <li><a href="http://localhost/laravel/public/hello/index">トップページ</a></li>
 <li><a href="http://localhost/laravel/public/hello/list">一覧</a></li>
 </ul>
</div>
</div>
<div class="container">
<div class="row">
 <form class="form-horizontal" method="POST" action="http://localhost/laravel/public/hello/form" accept-charset="UTF-8"><fieldset>
<div class="control-group">
<label for="username" class="control-label">ユーザー名</label><div class="controls">
<input type="text" name="username" id="username"></div>
</div>
<div class="control-group">
<label for="email" class="control-label">Eメール</label><div class="controls">
<input type="text" name="email" value="nakada@winroad.info" id="email"></div>
</div>
<div class="control-group">
<label for="password" class="control-label">パスワード</label><div class="controls">
<input type="password" name="password" id="password"></div>
</div>
<div class="control-group">
<label for="sex" class="control-label">性別</label><div class="controls">
<div class="control-group form-inline">
<label for="men" class="span1">男性</label><input checked="checked" id="men" type="radio" name="men" value="1"></div>
<div class="control-group form-inline">
<label for="famale" class="span1">女性</label><input id="famale" type="radio" name="famale" value="2"></div>
</div>
<div class="control-group">
<label for="native" class="control-label">出身地</label><div class="controls">
<select id="native" name="native"><option value="1" selected="selected">関東</option><option value="2">関西</option><option value="3">他</option></select></div>
</div>
<div class="control-group">
<label for="textarea" class="control-label">ご意見</label><div class="controls">
<textarea rows="3" class="span6" placeholder="ご意見をお聞かせ下さい" name="textarea" id="textarea" cols="50"></textarea></div>
</div>
</div>
<div class="form-actions">
<input class="btn btn-primary" type="submit" value="フォーム送信"></div>
</fieldset>
</form></div>
</div>
<script src="http://localhost/laravel/public/js/jquery-1.8.2.min.js"></script>
<script src="http://localhost/laravel/public/bootstrap/js/bootstrap.min.js"></script>
<!--
<script src="js/jquery-1.8.2.min.js"></script>
<script src="bootstrap/js/bootstrap.min.js"></script>
-->
</body>
</html>

7. さて、これでいよいよ次回から実践編に突入したいと思います。尚、実際にプログラムを作成する上で必要なクラスが発生した場合、基礎編にもどって、調べ直すかもしれませんが、そのときはお付き合い下さい。

本日は、以上です。

このエントリーを含むはてなブックマーク Buzzurlにブックマーク livedoorクリップ Yahoo!ブックマークに登録

トラックバック&コメント

この投稿のトラックバックURL:

トラックバック

コメント

  1. hidehide55 より:

    こんにちは、有用な情報をありがとうございます。

    「フォーム要素に表示される全ての入力データはHTML::entitiesメソッドを通してフィルタリングされる」ということで、Laravel のソースも見てみました。

    バリデーション後のエラー時に、Input::old() で入力された値を取得する場合等も、HTML::entities が効きます。
    例えば、&amp;(実際は半角で)と入力し、バリデーションでエラーとなった場合のフォームの値は、&(実際は半角)となってしまいます。
    HTML 上 &amp;amp;となってほしいところも、&amp;になってしまいます。

    これを回避する方法はないでしょうか?

    HTML::entities では、htmlentities() の $double_encode (4番目のパラメータ) に false を指定しているので、この辺りなのですが、HTML:: の各種 function でも利用していますので、単純に true にはできませんね。
    $double_encode の false 指定は、「何回 HTML::entities されても大丈夫」という、ある意味の逃げだと思うのですが、いかがでしょう?


コメントをどうぞ

このページの先頭へ