我正在尝试验证Zend_Form,它有几个可选字段,我想要至少填写其中一个。在我的情况下,我有手机,家庭和办公室电话号码,我想要至少提供其中一个。
我试图通过创建扩展Zend_Validate_Abstract的自定义验证器来实现验证上下文(如建议here)。问题是,如果所有可选字段都为空,则表单$ context(传递给验证器类)中缺少这些字段,这种方式根本没有验证。 因此,如果你填写三个选项中的任何一个或几个(移动,家庭,工作),他们都将被验证(这很好,但为此不需要自定义验证器),但如果你没有填写它们,那么没有选择强迫客户填写至少一个字段(这是我的目标)。
这就是我所拥有的:
<?php
class Application_Form_Application extends Zend_Form {
public function init() {
$this->setName('application');
// attach sub forms to main form
$this->addSubForms(array(
'application' => $this->application(),
...
));
}
private function application() {
$application = new Zend_Form_SubForm();
// custom phone validation
$phone_validation = array('phone_mobile' => 'Mobile', 'phone_home' => 'Home', 'phone_work' => 'Work');
// phone mobile
$app['phone_mobile'] = new Zend_Form_Element_Text('phone_mobile');
$app['phone_mobile']->setLabel('Mobile')
->addFilter('StripTags')
->addFilter('StringTrim')
->addValidator('Regex', false, array('/^[0-9]{8}$/i'))
->addValidator(new Application_Form_PhoneMobileHomeWork($phone_validation), false);
// phone home
$app['phone_home'] = new Zend_Form_Element_Text('phone_home');
$app['phone_home']->setLabel('Home')
->addFilter('StripTags')
->addFilter('StringTrim')
->addValidator('Regex', false, array('/^[0-9]{8}$/i'))
->addValidator(new Application_Form_PhoneMobileHomeWork($phone_validation), false);
// phone work
$app['phone_work'] = new Zend_Form_Element_Text('phone_work');
$app['phone_work']->setLabel('Work')
->addFilter('StripTags')
->addFilter('StringTrim')
->addValidator('Regex', false, array('/^[0-9]{8}$/i'))
->addValidator(new Application_Form_PhoneMobileHomeWork($phone_validation), false);
$application->AddElements($app);
}
}
?>
<?php
class Application_Form_PhoneMobileHomeWork extends Zend_Validate_Abstract {
const NOT_PRESENT = 'notPresent';
protected $_messageTemplates = array(
self::NOT_PRESENT => 'At least one contact phone shall be provided!'
);
protected $_listOfFields;
public function __construct(array $listOfFields) {
$this->_listOfFields = $listOfFields;
var_dump($listOfFields);exit;
}
public function isValid($value, $context = null) {
var_dump($context);exit;
...
}
?>
验证器总是通过第一个转储($ listOfFields),但是如果我将其删除,则永远不会调用isValid(),除非在某些电话字段(我们想要阻止)中键入一些数据。
当我进一步检查时,我找到了一个通过将空字段传递给$ context参数来扩展Zend_Validate类的解决方案,但如果有人知道,我希望有更好的解决方案。
总结一下 - 如何验证某个表单,强制用户填写几个可选字段中的至少一个?
答案 0 :(得分:1)
如果我理解正确,您希望不需要表单元素,但是使用自定义验证器阻止它们为空(除非其中一个不为空)?然后,为了不跳过验证链,您需要在每个元素中调用方法setAllowEmpty(false)
来阻止它们为空。
最后,在您的自定义验证器中,您将拥有以下内容:
foreach ($this->_listOfFields as $field) {
if (isset($context[$field]) AND $context[$field])
{
return true;
}
}
另外,请确保您的元素不是必需的(setRequired(false)
)。
答案 1 :(得分:0)
问题是如果填写了任何字段,表单中不存在multi_checkbox元素,那么它将不会被验证。
以下是一个解决方案: 使用始终选中的隐藏选项并验证是否始终检查此选项。