【问题标题】:Disable or change validation for embedded form fields in Symfony1 form禁用或更改 Symfony1 表单中嵌入表单字段的验证
【发布时间】:2014-05-09 11:44:59
【问题描述】:

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

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

我想要做的是将 option:"required" 更改为嵌入表单中所有字段的 false。

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

主窗体代码:

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>

【问题讨论】:

    标签: forms symfony-1.4


    【解决方案1】:

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

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

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

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

    $itemValidatorScheme['color']->setOption('required',false);
    $itemValidatorScheme['color']->clean($values['name_of_the_field']);
    

    【讨论】:

    • 我会试试 preValidator,看来它可能会起作用。 setOption() 和 clean() 的另一个解决方案不起作用,已经尝试过了。
    • 是的,它有效。刚刚在主窗体类代码中将postValidate 更改为preValidate。谢谢。
    猜你喜欢
    • 2011-10-09
    • 1970-01-01
    • 2018-02-23
    • 2012-01-24
    • 2015-07-17
    • 1970-01-01
    • 2021-10-29
    • 2019-06-15
    • 2012-11-14
    相关资源
    最近更新 更多