在Zend表单中验证一组字段/字段组

时间:2010-08-03 09:15:20

标签: zend-framework orm zend-form

是否有满足以下要求的良好解决方案:

  • 包含邮政编码的一个字段和数字,长度等默认验证器的表单
  • 提交后,将根据数据库检查表单。
  • 如果邮政编码不是唯一的,我们必须要求一个城市。

示例:

案例1:提交的邮政编码在数据库中是唯一的。一切正常。流程表

案例2:提交的邮政编码不是唯一的。为表单添加城市的第二个字段。回到表单。

我们希望以通用方式(不在控制器内)处理此问题。我们需要这个逻辑 很多形式。首先想到的是将isValid()添加到每个表单或写一个 带有逻辑的验证器,用于向表单添加字段。我们无法使用子表单,因为我们需要针对不同的字段(例如名称和街道)。

2 个答案:

答案 0 :(得分:2)

目前我在我的表单中使用isValid方法为用户表单验证密码并确认密码字段。此外,当表单显示在“新建操作”中时,没有任何修改,但是当在“编辑操作”中显示时,会向表单添加新字段。

我认为这是对isValid方法的一个很好的选择,并在验证返回false时添加字段,如果你想要更易于维护的东西,你应该为此目的编写自己的验证器。

看看我的代码:

class Admin_Form_User extends Zf_Form 
{
    public function __construct($options = NULL)
    {
        parent::__construct($options);
        $this->setName('user');

        $id = new Zend_Form_Element_Hidden('id');

        $user = new Zend_Form_Element_Text('user');
        $user->setLabel('User:')
        ->addFilter('stripTags')
        ->addFilter('StringTrim')
        ->setAllowEmpty(false)
        ->setRequired(true);

        $passwordChange = new Zend_Form_Element_Radio('changePassword');
        $passwordChange->setLabel('Would you like to change the password?')
        ->addMultiOptions(array(1 => 'Sim', 2 => 'Não'))
        ->setValue(2)
        ->setSeparator('');

        $password = new Zend_Form_Element_Password('password');
        $password->setLabel('Password:')
        ->addFilter('stripTags')
        ->addFilter('StringTrim')
        ->setRequired(true);

        $confirm_password = new Zend_Form_Element_Password('confirm_password');
        $confirm_password->setLabel('Confirm the password:')
        ->addFilter('stripTags')
        ->addFilter('StringTrim')
        ->addValidator('Identical')
        ->setRequired(true);

        $submit = new Zend_Form_Element_Submit('submit');
        $submit->setLabel('Save');

        $this->addElements(array($id,$name,$lastname,$group,$user,$passwordChange,$password,$confirm_password,$submit));

        $this->addDisplayGroup(array('password','confirm_password'),'passwordGroup');
        $this->submit->setOrder(8);

        $this->setDisplayGroupDecorators(array(
            'FormElements',
            array('HtmlTag', array('tag' => 'div','id' => 'div-password'))
            )
        );

        $passwordChange->clearDecorators();

    }

    public function addPasswordOption()
    {
        $this->changePassword->loadDefaultDecorators();

        $this->getDisplayGroup('passwordGroup')
        ->addDecorators(array(
            array('HtmlTag', array('tag' => 'div','id' => 'div-password'))
            )
        );

        $this->password->setRequired(false);
        $this->confirm_password->setRequired(false);
    }

    public function setPasswordRequired($flag = true)
    {
        $this->password->setRequired($flag);
        $this->confirm_password->setRequired($flag);
    }

    public function isValid($data)
    {
        $confirm = $this->getElement('confirm_password');
        $confirm->getValidator('Identical')->setToken($data['password']);
        return parent::isValid($data);
    }

}

所以,在我的控制器中:

public function newAction()
    {
        $this->view->title = "New user";
        $this->view->headTitle($this->view->title, 'PREPEND');

        $form = $this->getForm();

        if($this->getRequest()->isPost()) 
        {
            $formData = $this->_request->getPost();

            if($form->isValid($formData))
            {
                $Model = $this->getModel();
                $id = $Model->insert($formData);

                $this->_helper->flashMessenger('The user data has beed updated.');
                $this->_helper->redirector('list');
            }
        }

        $this->view->form = $form;
    }

    public function editAction()
    {       
        $this->view->title = "Edit user";
        $this->view->headTitle($this->view->title, 'PREPEND');

        $id = $this->getRequest()->getParam('id');

        $form = $this->getForm();

        // Add yes or no password change option
        $form->addPasswordOption();

        $Model = $this->getModel();

        if($this->getRequest()->isPost()) 
        {
            $formData = $this->getRequest()->getPost();

            // Change password?
            if($formData['changePassword'] == 2) $form->setPasswordRequired(false);

            if($form->isValid($formData)) 
            {
                $Model->update($formData);

                $this->_helper->flashMessenger('The user data has beed updated.');
                $this->_helper->redirector('list');
            } 

        }

        $data = $Model->getById($id)->toArray();

        $form->populate($data);

        $this->view->form = $form;
    }

答案 1 :(得分:1)

您可能需要一个Javascript表单验证器。在submit函数中执行AJAX调用以检查zipcode是否唯一。如果没有,请显示额外的城市字段。

但是你仍然需要执行验证服务器端:永远不要相信用户输入,即使它在客户端验证了。