Zend形成动态选择框

时间:2012-01-06 16:16:33

标签: php javascript zend-framework

我有一个带有三个选择框的Zend表单。首次加载表单时,仅填充第一个选择框。用户从第一个框中选择一个值,然后填充第二个和第三个框。

$element = $this->createElement('select', 'clinicId');
$element->addMultiOption('', ' ');
foreach($this->_clinics as $id => $details)
    $element->addMultiOption($id, $details['clinic_name']);
$element->setAttribs(array('onchange' => 'toggleClinic(this.value, ' . $json . ')'));
$element->setRequired(true);
$element->addErrorMessage('You must select a clinic');
$element->addFilter('StringTrim');
$element->setLabel('Clinic');
$element->clearDecorators();
$element->addDecorator('StandardTable');
if(isset($this->_info['clinic_id']))
    $element->setValue($this->_info['clinic_id']);
$this->addElement($element);
$this->_elementNames[] = 'clinicId';

$element = $this->createElement('select', 'attendeeId');
$element->addMultiOption('', ' ');
$element->setRequired(true);
$element->addErrorMessage('You must select an attendee');
$element->addFilter('StringTrim');
$element->setLabel('Appointment With');
$element->clearDecorators();
$element->addDecorator('StandardTable');
if (empty($this->_info['clinic_id']))
    $element->setAttribs(array('disabled' => true));
else
{
    foreach($this->_clinics[$this->_info['clinic_id']]['physicians'] as $userId => $userName)
        $element->addMultiOption($userId, $userName);
    if(isset($this->_info['provider_id']))
        $element->setValue($this->_info['provider_id']);
}
$this->addElement($element);
$this->_elementNames[] = 'attendeeId';

第三个选择框几乎与第二个选择框相同,只是使用不同的标签,变量等。

在我的javascript toggleClinic()函数中,我有:

$("#attendeeId").removeAttr('disabled');
$("#appointmentType").removeAttr('disabled');
for(id in jsonClinics[selectedId].physicians)
{
    var o = new Option(jsonClinics[selectedId].physicians[id], id); 
    $(o).html(jsonClinics[selectedId].physicians[id]); 
    $("#attendeeId").append(o);
}
for(id in jsonClinics[selectedId].appointment_types)
{
    var o = new Option(jsonClinics[selectedId].appointment_types[id]['name'], id); 
    $(o).html(jsonClinics[selectedId].appointment_types[id]['name']); 
    $("#appointmentType").append(o);
}

这一切似乎都有效。我选择了一家诊所,另外两个下降点正确填充。我可以从所有三个复选框中选择项目,提交表单,Firebug显示通过post发送的所有变量。但是,在我在控制器中的操作中,if ($this->_loader->appointmentform->isValid($request->getPost()))返回false,并且表单将重新显示第二个和第三个选择框的错误。它们的值也已被删除,因此我必须将第一个选择框的选定选项更改为重新触发toggleClinic。

主要关注的是第一部分,显然有一些东西被选中,为什么isValid会返回false?任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:2)

我在ZF中使用动态表单字段做了一些工作,它可能会有点棘手。要记住的是,即使你通过FireBug在POST中看到了正确的值,Zend_Form也不一定会看到它们。

在表单创建时,当您向表单添加attendeeId和appointmentType选择元素时,Zend_Form会看到空的select元素。从Zend Form的角度来看,当您提交表单时,它们仍然是空的。您对这些元素所做的唯一更改是通过JavaScript而不是Zend_Form对象中的DOM。

在这些情况下,我通常会在表单中添加preValidation(array $data)方法。在我的控制器中,我会做类似的事情:

if ($request->isPost()) {
    $form->preValidation($request->getPost());
    $form->isValid($request->getPost());
    . . . 
}

preValidation()会根据为attendeeId和appointmentType select元素提供的值将表单设置为适当的状态。此时,表单可以被验证,如果验证失败,表单将以预期的方式重新显示(可能会对表单的JavaScript进行一些小的修改)。

在您的情况下,preValidation()可能会以下列方式运作:

  • 检查$ data是否为clinicalId。
  • 根据该值,为attendeeId设置适当的multiOptions。
  • 检查attendeeId的值并为appointmentType
  • 设置适当的multiOptions

此时,您的表单知道它应该验证哪个multiOptions attendeeId和appointmentType,并且它在重新显示无效表单时具有多个选项。我经常对preValidation()中的动态元素进行其他修改,例如根据发布时表单的状态添加或修改验证器。

我知道我的答案相当普遍,但我希望它能让你指出正确的方向。

答案 1 :(得分:1)

要更深入地了解这类问题,请在验证表单后查看错误消息。

来自doc

  

如果要检查错误,可以使用两种方法。 getErrors()   返回元素名称/代码的关联数组(代码为   一系列错误代码)。 getMessages()返回一个关联数组   元素名称/消息(其中消息是关联数组)   错误代码/错误消息对)。如果给定元素没有   任何错误,它都不会包含在数组中。

一旦找到哪个元素未通过验证,就可以很容易地检查该元素的值是否以预期的键和值发送到服务器。

答案 2 :(得分:0)

这是一个非常简单的错误。

我的操作方式有效,相同的操作用于创建表单并提交表单,因此在创建表单后检查请求是否为发布请求。我没有将提交的值从第一个选择框传递到表单,因此在没有选择任何内容的情况下重新创建它,从而导致两个动态选择框未填充,从而导致错误。

在创建表单之前添加额外的检查允许我将提交的信息作为参数发送回表单,并修复了问题。