11

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

现在我只想在复选框被选中的情况下验证这个新地址的字段。否则,它们应该被忽略。

如何使用 Zend_Form 和 Zend_Validate 来做到这一点?

谢谢!

4

7 回答 7

7

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

您可以通过两种不同的方式执行此验证器,一种是使用传递给方法 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 ) );

        //...
    }

}

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

于 2012-03-30T01:07:55.660 回答
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);
    }

  }

}
于 2009-09-17T04:36:48.143 回答
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
    ...
    ...
  }
}
于 2009-09-17T14:36:28.770 回答
1

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

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

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

于 2009-09-16T09:48:57.597 回答
1

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

这是完整的代码。我希望这可以帮助别人。

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

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

于 2013-07-26T00:21:58.150 回答
1

在 Zend 1 上扩展 isValid 方法,根据发布的数据设置 required 例如:

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

        return parent::isValid($data);
    }
于 2016-12-30T09:58:48.423 回答
0

感谢 JCM 提供了很好的解决方案。

但是我注意到了两件事:

  • 如果成功,验证器的isValid方法必须返回true
  • 如果没有将allowEmpty选项传递给文本字段,验证器将不会在表单验证期间执行。
于 2013-05-15T09:22:52.983 回答