FuelPHP の Fieldset を使おう(Form の自動生成)

HTML の Form での、チェックボックスラジオボタン、セレクトボックスの値の保持機能の話が以下のブログに出ています。

このあたりの処理を FuelPHP で処理するのは、Fieldset クラスを使います。

Fieldset クラスを使えば、Form の HTML を自動生成でき、値の保持などもしてくれます。

Form を定義する

まず、Form を定義します。

Fieldset::forge() メソッドで Fieldset クラスのインスタンスを生成し、add() メソッドでフィールドを追加していきます。
add_rule() メソッドではバリデーションのルールを定義できます。

<?php
…略…
		$form = Fieldset::forge();

		$form->add('name', '名前')
			->add_rule('trim')
			->add_rule('required')
			->add_rule('no_controll')
			->add_rule('max_length', 20);

		$form->add('email', 'メールアドレス')
			->add_rule('trim')
			->add_rule('required')
			->add_rule('no_controll')
			->add_rule('valid_email');

		$form->add('comment', 'コメント', 
					array('type' => 'textarea', 'cols' => 70, 'rows' => 6))
			->add_rule('required')
			->add_rule('max_length', 400);

		$ops = array(
			'男性' => '男性', 
			'女性' => '女性',
		);
		$form->add('gender', '性別', 
					array('options' => $ops, 'type' => 'radio'))
			->add_rule('in_array', $ops);
		
		$ops = array(
			''                         => '',
			'製品購入前のお問い合わせ' => '製品購入前のお問い合わせ', 
			'製品購入後のお問い合わせ' => '製品購入後のお問い合わせ', 
			'その他'                   => 'その他',
		);
		$form->add('kind', '問い合わせの種類', 
					array('options' => $ops, 'type' => 'select'))
			->add_rule('in_array', $ops);
		
		$ops = array(
			'PHP'    => 'PHP', 
			'Perl'   => 'Perl', 
			'Python' => 'Python',
		);
		$form->add('lang', '使用プログラミング言語', 
					array('options' => $ops, 'type' => 'checkbox'))
			->add_rule('in_array', $ops)
			->add_rule('not_required_array');
		
		$form->add('submit', '', array('type'=>'submit', 'value' => '確認'));

これで準備完了です。

Form の HTML を生成する

準備ができましたので、Form の HTML を生成したい場合は、build() メソッドを使います。

$form->build('/form/confirm')

引数は Form を投稿する URL です。

通常は、ビューに渡すでしょうから、コントローラのコードは以下のようになります。

$this->template->content->set_safe('html_form', $form->build('/form/confirm'));

この場合、ビューでは echo する 1行だけです。

<?php echo $html_form; ?>

もし、Fieldset を使わずに、HTML を書いていく場合だと、例えば、以下のようになります。

<?php echo Form::open('/form/confirm'); ?>
<p>
	<?php echo Form::label('名前', 'name'); ?>(*) :
	<?php echo Form::input('name', Input::post('name')); ?>
</p>
<p>
	<?php echo Form::label('メールアドレス', 'email'); ?>(*) :
	<?php echo Form::input('email', Input::post('email')); ?>
</p>
<p>
	<?php echo Form::label('コメント', 'comment'); ?>(*) :
	<?php echo Form::textarea('comment', Input::post('comment'), array('rows' => 6, 'cols' => 70)); ?>
</p>
<p>
	性別:
	<?php echo Form::radio('gender', '男性', Input::post('gender') === '男性' ? array('checked' => 'checked', 'id' => 'form_male') : array('id' => 'form_male')); ?>
	<?php echo Form::label('男性', 'male'); ?>
	<?php echo Form::radio('gender', '女性', Input::post('gender') === '女性' ? array('checked' => 'checked', 'id' => 'form_female') : array('id' => 'form_female')); ?>
	<?php echo Form::label('女性', 'female'); ?>
</p>
<p>
	<?php echo Form::label('問い合わせの種類', 'kind'); ?>:
	<?php
	echo Form::select('kind', Input::post('kind'), array(
		'' => '',
		'製品購入前のお問い合わせ' => '製品購入前のお問い合わせ',
		'製品購入後のお問い合わせ' => '製品購入後のお問い合わせ',
		'その他' => 'その他',
	));
	?>
</p>
<p>
	使用プログラミング言語:
	<?php echo Form::checkbox('lang[]', 'PHP', in_array('PHP', Input::post('lang', array())) ? array('checked' => 'checked', 'id' => 'form_PHP') : array('id' => 'form_PHP')); ?>
	<?php echo Form::label('PHP', 'PHP'); ?>
	<?php echo Form::checkbox('lang[]', 'Perl', in_array('Perl', Input::post('lang', array())) ? array('checked' => 'checked', 'id' => 'form_Perl') : array('id' => 'form_Perl')); ?>
	<?php echo Form::label('Perl', 'Perl'); ?>
	<?php echo Form::checkbox('lang[]', 'Python', in_array('Python', Input::post('lang', array())) ? array('checked' => 'checked', 'id' => 'form_Python') : array('id' => 'form_Python')); ?>
	<?php echo Form::label('Python', 'Python'); ?>
</p>

<div class="actions">
	<?php echo Form::submit('submit', '確認'); ?>
</div>
<?php echo Form::close(); ?>

値を保持するには?

build() する前に、repopulate() メソッドを呼び出すだけで投稿された値が保持された Form の HTML が生成できます。楽ちんですね。

$form->repopulate();

バリデーションの仕方

validation() メソッドで、Validation オブジェクトを取得できます。

$val  = $form->validation();

あとは、run() メソッドでバリデーションを実行すれば、いいですね。

<?php
…略…
		if ($val->run())
		{
			$data['input'] = $val->validated();
			$this->template->title = 'コンタクトフォーム: 確認';
			$this->template->content = View::forge('form/confirm', $data);
		}
		else
		{
			$form->repopulate();
			
			$this->template->title = 'コンタクトフォーム: エラー';
			$this->template->content = View::forge('form/index');
			$this->template->content->set_safe('html_error', $val->show_errors());
			$this->template->content->set_safe('html_form', $form->build('/form/confirm'));
		}