如何在Zend子表单中一次验证> 1个字段?

时间:2009-07-12 19:24:13

标签: zend-form zend-validate zend-form-sub-form

我使用在线参考文档中的Zend_Form_SubForm示例创建了一个3屏幕“向导”。

我遇到麻烦的要求是这样的: 如果字段1,2和&第一个屏幕中的3个已经在数据库中,通知用户他们正在尝试添加重复记录。每个字段都有自己的验证器。不知何故,我需要添加这个“组验证器”。

所以,在最基本的层面上,我正在尝试:

if($field_1_not_in_db && $field_2_not_in_db && $field_3_not_in_db){ 
   return true;//validation OK 
} else { 
   return false;//invalid data
}

我遇到了几个问题: 1)因为它适用于多个字段,我不知道将它附加到哪个字段。错误消息出现在它们所附加的字段旁边,所以这很重要......除非我能将这些“多字段验证器”错误显示在屏幕顶部,这将是理想的。 2)我的验证器只接收一个值(我附加到的字段的值,而不是它应该验证的多个字段的值)。 3)我在错误消息中提供了原始(非重复)记录的链接,但它逃脱了链接,我无法弄清楚如何解决这个问题。

我正在使用的设置(下面)实际上执行正常,但NewPlace验证器接收$ _POST ['city_fk']作为$ fields,而不是所需的发布值组。

$city_fk = new Zend_Form_Element_Select('city_fk');
$cities = array();
$city_fk->setMultiOptions($cities)
        ->setLabel('City')
        ->setDescription('The city this place is in')
        ->setRequired(true);

$v = array(
      'place_is_unique' => array(
                'NewPlace',
                'fields' => array('place_name','phone_number','phone_extension','street','post_code_name'),
        )
    );
$city_fk->addValidators($v);

$addressSubForm->addElement($city_fk);

class My_Validate_NewPlace extends Zend_Validate_Abstract
{ 
    public function isValid($fields)
    {  
        $result = false;

    if(!$result)
        {
            $this->_error('sorry, this is duplicate data. see it <a href="linktoduplicate">here</a>');
        return false;
        }

        return true;
    }
}

1 个答案:

答案 0 :(得分:1)

这无法帮助您确定将验证附加到哪个字段,但是...... 有一种叫做“validation context”的东西很有帮助。 当您创建自定义验证器或表单IF时,指定第二个可选参数($ context = null),然后Zend将使用整个发布数据数组自动填充该数据,您可以使用该数据将其他字段值合并到验证中。这是一个非常基本的例子:

$city_name = new Zend_Form_Element_Text('city_name');

$place_name = new Zend_Form_Element_Text('place_name');
$place_name->addValidator('NewPlace');

class My_Validate_NewPlace extends Zend_Validate_Abstract
{ 
    public function isValid($value, **$context = null**)
    {  
        if(trim($value)!='' && trim($context['city_name']) != '')
        { 
            return true;
        }

        return false;
    }
}