禁用或更改Symfony1表单中嵌入的表单域的验证

时间:2014-05-09 11:44:59

标签: forms symfony-1.4

我正在尝试根据主窗体中的值取消嵌入表单中的验证。

默认情况下,嵌入的表单字段的验证程序选项设置为“required”=> true。所以它得到了这样的验证。如果用户将任何字段留空,则表单不会通过验证,并且空白字段会在模板中标记(不同样式)。

我要做的是将嵌入式表格中的所有字段的选项:“required”更改为false。

我试着在post验证器回调方法中这样做,但似乎不可能那样。

主要表单代码:

class TestForma extends sfForm
{
  public function configure()
  {

    $this->setWidgets(array(
    'validate_items'    => new sfWidgetFormChoice(array(
            'choices'   => array('no' => 'No', 'yes' => 'Yes'),
            'multiple'   => false,'expanded'=>true,'default' => 'no')),
    ));

   $this->setValidators(array('validate_items' => new sfValidatorPass()));

    $this->widgetSchema->setNameFormat('testforma[%s]');


    $subForm = new sfForm();

    for ($i = 0; $i < 2; $i++)
    {
        $form = new ItemForma();

        $subForm->embedForm($i, $form);
    }
    $this->embedForm('items', $subForm);



    $this->validatorSchema->setPostValidator(
        new sfValidatorCallback(array('callback' => array($this,    'postValidate')))
    );

  }

验证后代码:

public function postValidate($validator,$values)
{
    $validatorSchema = $this->getValidatorSchema();

    if($values['validate_items']=='no')
    {
        $itemsValidatorSchema = $validatorSchema['items'];
        $itemsFieldsValidatorSchemes = $itemsValidatorSchema->getFields();
        foreach($itemsFieldsValidatorSchemes as $itemValidatorScheme)
        {
            $itemValidatorScheme['color']->setOption('required',false);
            $itemValidatorScheme['shape']->setOption('required',false);
        }
    }

    return $values;
}

嵌入式表单类:

class ItemForma extends sfForm
{
  public function configure()
  {

    $this->setWidgets(array(
      'color'    => new sfWidgetFormInputText(),
      'shape'   => new sfWidgetFormInput(),
    ));

    $this->setValidators(array(
      'color'    => new sfValidatorString(array('required'=>true)),
      'shape'   => new sfValidatorEmail(array('required'=>true)),
      ));

    $this->widgetSchema->setNameFormat('items[%s]');
  }
}

模板代码:

<form action="<?php echo url_for('weather/formiranje')?>" method="post">
        <?php 
        foreach($form->getErrorSchema()->getErrors() as $e)
        {
            echo $e->__toString();
        }
        ?>

  <table>
    <tfoot>
      <tr>
        <td colspan="2">
          <input type="submit" value="OK" />
        </td>
      </tr>
    </tfoot>
    <tbody>
            <tr><th>Main form</th></tr>
      <tr><td><?php echo $form['validate_items']->renderLabel() ?>
                        <span class="<?php echo $form['validate_items']->hasError() ? 'rowError' : ''?>">
                        <?php echo $form['validate_items'] ?></span>

                </td></tr>
            <tr><td>&nbsp;</td></tr>
            <tr><th>Embedded forms</th></tr>
            <?php

            foreach($form['items'] as $item)
            {
                ?>
            <tr>
                <td><span class="<?php echo $item['color']->hasError() ? 'rowError' : ''?>">
                                                    <?php echo $item['color']->renderLabel() ?>
                                                    <?php echo $item['color'] ?></span>
                </td>
            </tr>
            <tr>
                <td><span class="<?php echo $item['shape']->hasError() ? 'rowError' : ''?>">
                    <?php echo $item['shape']->renderLabel() ?>
                        <?php echo $item['shape'] ?></span>
                </td></tr>
                <?php
            }
            echo $form['_csrf_token'];
            ?>
    </tbody>
  </table>
</form>

1 个答案:

答案 0 :(得分:2)

您组织它的方式不起作用,因为post验证器在所有字段验证器之后运行,因此它们已经被检查并标记为失败。 (因为这些字段是必需的)。

您可以尝试使用与此处相同的方法,但设置preValidator而不是postValidator。我认为它应该适用。

如果它仍无法按预期工作,我要做的是将嵌入表单字段的默认设置更改为'required' = false并使用postValidator。在验证器中,您可以检查是否需要验证嵌入字段。如果需要验证它们,可以检查它们的值是否已设置,如果不是,则可以为这些字段抛出错误。 (我希望这清楚地解释)

您可以尝试的另一件事是重新运行所选字段的验证。在postValidator

中就是这样的
$itemValidatorScheme['color']->setOption('required',false);
$itemValidatorScheme['color']->clean($values['name_of_the_field']);