Zend_Form:只有在选中复选框时才需要元素

时间:2009-09-16 09:25:14

标签: php zend-framework zend-form

我有一个表格,用户可以勾选“创建新地址”复选框,然后可以用同一表格填写这个新地址的字段。

现在,我想仅在选中复选框时验证此新地址的字段。否则,应该忽略它们。

如何使用Zend_Form和Zend_Validate来实现这一点?

谢谢!

7 个答案:

答案 0 :(得分:6)

我认为最好,更正确的方法是创建一个自定义验证器。

您可以通过两种不同的方式执行此验证程序,一种是使用传递给方法isValid的第二个参数,$ context,即要验证的当前表单,或者,注入需要检查以进行验证的Checkbox元素在构造函数中发生。我更喜欢上一个:

<?php
class RequiredIfCheckboxIsChecked extends Zend_Validate_Abstract {

    const REQUIRED = 'required';

    protected $element;

    protected $_messageTemplates = array(
        self::REQUIRED => 'Element required'
    );

    public function __construct( Zend_Form_Element_Checkbox $element )
    {
        $this->element = $element;
    }

    public function isValid( $value )
    {
        $this->_setValue( $value );

        if( $this->element->isChecked() && $value === '' ) {
            $this->_error( self::REQUIRED );
            return false;
        }

        return true;
    }

}

用法:

class MyForm extends Zend_Form {

    public function init()
    {
        //...

        $checkElement = new Zend_Form_Element_Checkbox( 'checkbox' );
        $checkElement->setRequired();

        $dependentElement = new Zend_Form_Element_Text( 'text' );
        $dependentElement->setAllowEmpty( false )
            ->addValidator( new RequiredIfCheckboxIsChecked( $checkElement ) );

        //...
    }

}

我没有测试过代码,但我认为它应该可行。

答案 1 :(得分:2)

我实际上没有运行它,但它应该在合理的范围内工作。我之前做过类似的事情,但不记得代码在哪里。

<?php

class My_Form extends Zend_Form
{
  public function init()
  {
    $checkbox = new Zend_Form_Element_Checkbox("checkbox");
    $checkbox->setValue("checked");

    $textField = new Zend_Form_Element_Text("text");

    $this->addElements(array("checkbox", "text"));

    $checkbox = $this->getElement("checkbox");

    if ($checkbox->isChecked() )
    {
       //get textfield
       $textField = $this->getElement("text");

       //make fields required and add validations to it.
       $textField->setRequired(true);
    }

  }

}

答案 2 :(得分:2)

如果我需要相互验证多个元素,我就会这样做

$f = new Zend_Form();

if($_POST && $f->isValid($_POST)) {
  if($f->checkbox->isChecked() && strlen($f->getValue('element')) === 0) {
    $f->element->addError('Checkbox checked, but element empty');
    $f->markAsError();
  }

  if(!$f->isErrors()) {
    // process
    ...
    ...
  }
}

答案 3 :(得分:1)

我一直想知道如何在ZF中做到这一点,尽管从来没有实现过这样的表单功能。

我想到的一个想法是创建一个自定义验证器,它接受复选框字段作为参数,并在验证器链中运行它,如documented。如果选中该复选框,验证器可能会返回失败。然后,您可以检查所有验证是否都失败,然后将表单视为验证失败。

表单验证的自定义级别可能不方便,因此使用表单的isValidPartial方法会更好。

答案 4 :(得分:1)

我创建了一个自定义验证器,它将根据另一个zend表单元素的值使您的元素成为必需元素。

这是完整的code。我希望这有助于某人。

我们的想法是创建一个自定义验证器,并将条件元素的名称和条件元素的值传递给构造函数。 Zend_Validor的isValid方法已经可以访问要附加验证器的元素的值以及所有表单元素的名称和值。

因此,在isValid方法中,您可以获得确定表单元素是否为必需元素所需的所有信息。

答案 5 :(得分:1)

On Zend 1扩展了isValid方法,根据发布的数据设置所需的方法,例如:

    public function isValid($data)
    {
        if (!empty($data['companyCar'])) {
            $this->getElement('carValue')->setRequired(true);
        }

        return parent::isValid($data);
    }

答案 6 :(得分:0)

感谢JCM的出色解决方案。

然而我注意到了两件事:

  • 验证者的 isValid 方法必须在成功时返回 true
  • 在表单验证期间,如果没有将 allowEmpty 选项传递给 false 到文本字段,则不会执行验证程序。