特定の要素をグルーピングしたい時だってある。
<?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);