@blog.justoneplanet.info

日々勉強

Zend_Formをもっと触ってみる

特定の要素をグルーピングしたい時だってある。

<?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">&nbsp;</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">&nbsp;</dt>
<dd id="checkHash-element"><input type="hidden" name="checkHash" value="c15806d5c0f9bc7f6b414ba2cf40468d" id="checkHash"></dd>
<dt id="送信-label">&nbsp;</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">&nbsp;</dt>
<dd id="checkHash-element"><input type="hidden" name="checkHash" value="784473de7bc7e8048eff4538060bce03" id="checkHash"></dd>
<dt id="送信-label">&nbsp;</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);

コメントはまだありません»

No comments yet.

RSS feed for comments on this post.TrackBack URL

Leave a comment