特定の要素をグルーピングしたい時だってある。
<?php class Admin_IndexController extends Zend_Controller_Action { public function indexAction() { $this->view->form = $this->_createForm(); } public function registerAction() { $form = $this->createForm(); if(!form->isValid($this->_getAllParams())){// error $this->view->assign('form', $form); return $this->render('index'); } else{// success $this->_dbh->register($form->getValues()); } } private function _createForm() { $form = new Zend_Form(); $form->setAction('/admin/index/register/')->setMethod('post'); $form->addElement( 'text', 'name', array( 'validators' => array( array('Regex', false, array('/^[a-z]/i')) ), 'label' => 'Name : ', 'required' => true ) ); $form->addElement( 'password', 'pass', array( 'validators' => array( 'Alnum' ), 'label' => 'Password : ', 'required' => true ) ); $form->addDisplayGroup( array( 'name', 'pass' ), 'login', array( 'disableLoadDefaultDecorators' => false ) ); $form->addElement('hash', 'checkHash'); $form->addElement('submit', '送信'); return $form; } } ?>
上述のようにしてグループ毎にfieldsetで括ることができる。addDisplayGroupは要素を定義した直後にコールしないとフォームの要素の順序が変わってしまうので注意が必要である。
出力html
<form enctype="application/x-www-form-urlencoded" action="" method="post"> <dl class="zend_form"> <dt id="login-label"> </dt> <dd id="login-element"><fieldset id="fieldset-login"> <dl> <dt id="name-label"><label for="name" class="required">Name :</label></dt> <dd id="name-element"><input type="text" name="name" id="name" value=""></dd> <dt id="pass-label"><label for="pass" class="required">Password :</label></dt> <dd id="pass-element"><input type="password" name="pass" id="pass" value=""></dd> </dl> </fieldset></dd> <dt id="checkHash-label"> </dt> <dd id="checkHash-element"><input type="hidden" name="checkHash" value="c15806d5c0f9bc7f6b414ba2cf40468d" id="checkHash"></dd> <dt id="送信-label"> </dt> <dd id="送信-element"><input type="submit" name="送信" id="送信" value="送信"></dd> </dl> </form>
なかなか構造化された綺麗なHTMLが出力される!
- Zend_Form::addElement(string $type, string $name, array $options);
- 第一引数でtype属性を指定、第二引数でname属性、第三引数でバリデータやフィルタのオプション設定をする
- Zend_Form::addDisplayGroup(array $elementNames, string $fieldsetName, array options);
- 第一引数で要素のname属性を配列で指定、第二引数でfieldsetの任意の名前、第三引数でオプション設定をする
■フォームのデコレータ
勝手にタグがついて全体をfieldsetで括ってくれて便利なんだが余計なお世話になるときだってある。そこでデフォルトでフォームに付加されるHTMLタグを変更する。
<?php class Admin_IndexController extends Zend_Controller_Action { public function indexAction() { $this->view->form = $this->_createForm(); } public function registerAction() { $form = $this->createForm(); if(!form->isValid($this->_getAllParams())){// error $this->view->assign('form', $form); return $this->render('index'); } else{// success $this->_dbh->register($form->getValues()); } } private function _createForm() { $form = new Zend_Form(); $form->setAction('/admin/index/register/')->setMethod('post'); $form->addElement( 'text', 'name', array( 'validators' => array( array('Regex', false, array('/^[a-z]/i')) ), 'label' => 'Name : ', 'required' => true ) ); $form->addElement( 'password', 'pass', array( 'validators' => array( 'Alnum' ), 'label' => 'Password : ', 'required' => true ) ); $form->addElement('hash', 'checkHash'); $form->addElement('submit', '送信'); $form->clearDecorators(); $form->addDecorator('FormElements')->addDecorator('HtmlTag', array('tag' => 'ul', 'class' => 'form'))->addDecorator('Form'); $form->setElementDecorators(array('ViewHelper', 'Label', array('HtmlTag', array('tag' => 'li')))); return $form; } } ?>
出力コード
<form enctype="application/x-www-form-urlencoded" action="" method="post"> <ul class="form"> <li><label for="name" class="required">Name :</label><input type="text" name="name" id="name" value=""></li> <li><label for="pass" class="required">Password :</label><input type="password" name="pass" id="pass" value=""></li> <li><input type="hidden" name="checkHash" value="f2bcb658321fb39cdc0bd92c61210f7d" id="checkHash"></li> <li><label for="送信" class="optional">送信</label><input type="submit" name="送信" id="送信" value="送信"></li> </ul> </form>
- Zend_Form::addDecorator(string $className, , array $options = null);
- Zend_Form::addDecorators(array $decorators);
いろんなデコレータ
private function _createForm() { $form = new Zend_Form(); $form->setAction('/admin/index/register/')->setMethod('post'); $form->addElement( 'text', 'name', array( 'validators' => array( array('Regex', false, array('/^[a-z]/i')) ), 'label' => 'Name : ', 'required' => true ) ); $form->addElement( 'password', 'pass', array( 'validators' => array( 'Alnum' ), 'label' => 'Password : ', 'required' => true ) ); $name = $form->getElement('name'); $name->setDescription('<span class="description">名前をいれる感じで</span>'); $name->addDecorator(//<p> 'description', array( 'class' => 'descrition', 'escape' => false ) ); $form->addElement('hash', 'checkHash'); $form->addElement('submit', '送信'); $form->clearDecorators(); $form->addDecorator('FormElements')->addDecorator('HtmlTag', array('tag' => 'ul', 'class' => 'form'))->addDecorator('Form'); $form->setElementDecorators(array('ViewHelper', 'Label', array('HtmlTag', array('tag' => 'li')))); return $form; }
出力HTML
<form enctype="application/x-www-form-urlencoded" action="" method="post"> <ul class="form"> <li><label for="name" class="required">Name :</label> <input type="text" name="name" id="name" value=""></li> <p class="descrition_class"><span class="description">名前をいれる感じで</span></p> <li><label for="pass" class="required">Password :</label> <input type="password" name="pass" id="pass" value=""></li> <li><input type="hidden" name="checkHash" value="0162b9bd58af60eb903fe52237bc6a8f" id="checkHash"></li> <li><label for="送信" class="optional">送信</label> <input type="submit" name="送信" id="送信" value="送信"></li> </ul> </form>
■自作デコレータ
以下のようにZend_Form_Decorator_Abstractを継承してあげればオリジナルデコレータができる!
../application/decorators/Original.php
<?php class Jop_Decorator_Original extends Zend_Form_Decorator_Abstract { public function render($content) { return "<span>{$content}</span>"; } } ?>
以下のようにして使用する。
private function _createForm() { $form = new Zend_Form(); $form->setAction('/admin/index/register/')->setMethod('post'); $form->addPrefixPath('Jop_Decorator', '../application/decorators', 'decorator'); //追加したフォーム要素に登録 //$form->addElementPrefixPath('Jop_Decorator', 'path', 'decorator'); $form->addElement( 'text', 'name', array( 'validators' => array( array('Regex', false, array('/^[a-z]/i')) ), 'label' => 'Name : ', 'required' => true ) ); $form->addElement( 'password', 'pass', array( 'validators' => array( 'Alnum' ), 'label' => 'Password : ', 'required' => true ) ); $name = $form->getElement('name'); //個別のフォーム要素に加える $name->addPrefixPath('Jop_Decorator', '../applications/decorators', 'decorator'); $name->addDecorator('Original'); $form->addElement('hash', 'checkHash'); $form->addElement('submit', '送信'); return $form; }
以下のようにspanで括られて出力される。
<form enctype="application/x-www-form-urlencoded" action="" method="post"> <dl class="zend_form"> <span><dt id="name-label"><label for="name" class="required">Name :</label></dt> <dd id="name-element"><input type="text" name="name" id="name" value=""></dd></span> <dt id="pass-label"><label for="pass" class="required">Password :</label></dt> <dd id="pass-element"><input type="password" name="pass" id="pass" value=""></dd> <dt id="checkHash-label"> </dt> <dd id="checkHash-element"><input type="hidden" name="checkHash" value="784473de7bc7e8048eff4538060bce03" id="checkHash"></dd> <dt id="送信-label"> </dt> <dd id="送信-element"><input type="submit" name="送信" id="送信" value="送信"></dd> </dl> </form>
■エラーメッセージの日本語化
以下のようにすると対応するエラーメッセージを日本語化できる。
private function _createForm() { $form = new Zend_Form(); $form->setAction('/admin/index/register/')->setMethod('post'); $form->addElement( 'text', 'name', array( 'validators' => array( array('Regex', false, array('/^[a-z]/i')) ), 'label' => 'Name : ', 'required' => true ) ); $form->addElement( 'password', 'pass', array( 'validators' => array( 'Alnum' ), 'label' => 'Password : ', 'required' => true ) ); $form->addElement('hash', 'checkHash'); $form->addElement('submit', '送信'); $adapter = new Zend_Translate( 'array', array( "'%value%' has not only alphabetic and digit characters" => "'%value%' に英数字以外の文字が含まれています", "'%value%' does not match against pattern '%pattern%'" => "'%value%' は '%pattern%' にマッチしません。" ) ); $form->setTranslator($adapter); return $form; }
全てのフォームに適用する場合は以下のようにする。
Zend_Form::setDefaultTranslator($adapter);