我有一个带有三个选择框的 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';
第三个选择框与第二个选择框几乎相同,只是标签、变量等不同。
在我的 javascripttoggleClinic() 函数中,我有:
$("#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 会显示通过邮寄发送的所有变量。但是,在我在 Controller 中的操作中, if ($this->_loader->appointmentform->isValid($request->getPost()))
返回 false,并且表单重新显示,并出现错误第二个和第三个选择框。它们的值也已被删除,因此我必须更改第一个选择框的选定选项以重新触发toggleClinic。
主要关心的是第一部分,显然有一些东西被选择了,那么为什么 isValid 返回 false 呢?任何帮助将不胜感激。
最佳答案
我已经在 ZF 中对动态表单字段进行了一些工作,但它可能会有点棘手。要记住的是,即使您通过 FireBug 在 POST 中看到了正确的值,Zend_Form 也不一定能看到它们。
在创建表单时,当您将 attendeeId 和 AppointmentType 选择元素添加到表单时,Zend_Form 会看到空的选择元素。从 Zend Form 的 Angular 来看,当您提交表单时它们仍然是空的。您对这些元素所做的唯一更改是通过 JavaScript 在 DOM 中进行的,而不是在 Zend_Form 对象中进行的。
在这些情况下,我通常会在表单中添加一个 preValidation(array $data)
方法。在我的 Controller 中,我将执行以下操作:
if ($request->isPost()) {
$form->preValidation($request->getPost());
$form->isValid($request->getPost());
. . .
}
preValidation()
将根据为 attendeeId 和 AppointmentType 选择元素提供的值将表单设置为适当的状态。此时,可以验证表单,如果验证失败,表单将以预期方式重新显示(可能需要对表单的 JavaScript 进行一些细微修改)。
在您的情况下,preValidation()
可能按以下方式工作:
- 检查 $data 中的 ClinicId 值。
- 根据该值,为 attendeeId 设置适当的 multiOptions。
- 检查 attendeeId 的值并为约会类型设置适当的 multiOptions
此时,您的表单知道应该验证哪个 multiOptions attendeeId 和 AppointmentType,并且在重新显示无效表单时可以使用 multiOptions。我经常对 preValidation()
中的动态元素进行其他修改,例如根据发布时表单的状态添加或修改验证器。
我知道我的回答相当笼统,但我希望它能为您指明正确的方向。
关于php - Zend 表单动态选择框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8760860/