1

假设我有一个 Zend_Form 表单,它有几个文本字段,例如:

$form = new Zend_Form();
$form->addElement('text', 'name', array(
    'required' => true,
    'isArray' => true,
    'filters' => array( /* ... */ ),
    'validators' => array( /* ... */ ),
));
$form->addElement('text', 'surname', array(
    'required' => true,
    'isArray' => true,
    'filters' => array( /* ... */ ),
    'validators' => array( /* ... */ ),
));

渲染后,我有以下 HTML 标记(简化):

<div id="people">
    <div class="person">
        <input type="text" name="name[]" />
        <input type="text" name="surname[]" />
    </div>
</div>

现在我希望能够添加任意数量的人。我创建了一个“+”按钮,在 Javascript 中将下一个 div.person 附加到容器中。在我提交表单之前,我有例如 5 个姓名和 5 个姓氏,以数组的形式发布到服务器。除非有人将值放在未验证的字段中,否则一切都很好。然后整个表单验证失败,当我想再次显示表单(有错误)时,我看到 PHP 警告:

htmlspecialchars() expects parameter 1 to be string, array given

票证中或多或少地描述了这一点:http: //framework.zend.com/issues/browse/ZF-8112

但是,我想出了一个不太优雅的解决方案。我想要达到的目标:

  • 在视图中再次呈现所有字段和值
  • 仅在包含错误值的字段旁边显示错误消息

这是我的解决方案(查看脚本):

<div id="people">
<?php
$names = $form->name->getValue(); // will have an array here if the form were submitted
$surnames= $form->surname->getValue();

// only if the form were submitted we need to validate fields' values
// and display errors next to them; otherwise when user enter the page
// and render the form for the first time - he would see Required validator
// errors
$needsValidation = is_array($names) || is_array($surnames);

// print empty fields when the form is displayed the first time
if(!is_array($names))$names= array('');
if(!is_array($surnames))$surnames= array('');

// display all fields!
foreach($names as $index => $name):
    $surname = $surnames[$index];
    // validate value if needed
    if($needsValidation){
        $form->name->isValid($name);
        $form->surname->isValid($surname);
    }
?>
  <div class="person">
     <?=$form->name->setValue($name); // display field with error if did not pass the validation ?>
     <?=$form->surname->setValue($surname);?>
  </div>
<?php endforeach; ?>
</div>

代码有效,但我想知道是否有合适、更舒适的方法来做到这一点?当需要更动态的多值表单并且很长时间没有找到更好的解决方案时,我经常遇到这个问题。

4

1 回答 1

0

没有更好的主意,我创建了一个处理上述逻辑的视图助手。可以在这里找到。

如果帮助器在视图中可用,则可以通过以下方式使用它(使用问题中的表格):

<?= 
    $this->formArrayElements(
        array($form->name, $form->surname), 
        'partials/name_surname.phtml'
    );
?>

application/views/partials/name_surname.phtml部分视图的内容是:

<div class="person">
    <?= $this->name ?>
    <?= $this->surname ?>
</div>

这些字段根据发布的表单呈现,验证消息仅显示在未通过验证的值旁边。

助手的代码远非完美(我只是从问题中重写了这个想法)但易于使用并且可以被认为是一个很好的起点。

于 2013-11-03T09:50:17.530 回答