【问题标题】:How to clear field value with Symfony2 forms如何使用 Symfony2 表单清除字段值
【发布时间】:2013-02-22 00:19:52
【问题描述】:

我正在编写自己的 CAPTCHA 类,当表单无法验证时,出于显而易见的原因,我不想使用之前的答案预先填充验证码输入。我只想在渲染之前清除输入。

我发现 data 选项仅适用于默认值,它会被用户输入的内容覆盖。我尝试了以下代码:

$form->get('captcha')->setData(null);

.. 请求与表单绑定后,却抛出了AlreadyBoundException。我实际上已经设法让它工作:

if (isset($formView->children['captcha'])) {
    $formView->children['captcha']->vars['value'] = null;
}

但这看起来是错误的,而且绝对不符合 Symfony 的标准。我查看了您在构建表单时可以提供的其他选项,但没有看到任何值得注意的内容。

有人知道吗?

顺便说一句,我有一半希望 Symfony2 附带一个 CAPTCHA 解决方案,这主要是我习惯该框架时的学习练习。

【问题讨论】:

  • 如何构建表单?直接在您的控制器中?你是使用全栈还是只使用表单组件?
  • 我有完整的 Symfony 应用程序。表单有它自己的类,它扩展了 AbstractType,它处理添加每个字段。
  • 你能发布你的类型代码吗?
  • 我也有类似的情况:$form = $this->createFormBuilder()->add('order_id', 'text', array('label' => 'Scan Barcode'))- >getForm();除了作者的方法之外,我无法找到一种不同的方法来从模板中的渲染中删除提交的值。

标签: forms symfony symfony-forms


【解决方案1】:

我认为您想像 Symfony 处理 password 字段一样处理此表单字段:它不会被填充。一起来看看PasswordType

namespace Symfony\Component\Form\Extension\Core\Type;

class PasswordType extends AbstractType
{
    public function buildView(FormView $view, FormInterface $form, array $options)
    {
        if ($options['always_empty'] || !$form->isSubmitted()) {
            $view->vars['value'] = '';
        }
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'always_empty' => true,
            'trim' => false,
        ));
    }

    //...
}

所以,这很简单:只需在 FormType(即 CaptchaType)的 buildView 方法中添加 $view->vars['value'] = ''。这意味着该字段的数据不会被清除,但不会传递给 Twig 模板。方法不同,但结果是一样的:验证失败后密码字段为空。

如果你真的很懒,你可以使用 PasswordType,但是由于该字段的输入将被屏蔽 (*****),这会使烦人的验证码字段变得更糟。

您的表单类型可能如下所示:

class CaptchaType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildView(FormView $view, FormInterface $form, array $options)
    {
        $view->vars['value'] = '';
    }

    /**
     * {@inheritdoc}
     */
    public function getParent()
    {
        return __NAMESPACE__.'\TextType';
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return $this->getBlockPrefix();
    }

    /**
     * {@inheritdoc}
     */
    public function getBlockPrefix()
    {
        return 'captcha';
    }
}

编辑: 刚发现CaptchaBundle取了same approach

【讨论】:

    【解决方案2】:

    有一种有趣的方法可以在处理请求之前对其进行修改。不过,我会研究 Stephan 的答案,因为它看起来更干净。

    类似这样的:

    public function indexAction(Request $request)
    {
    
        $form = $this->createForm(Form::class);
    
        $subData=$request->request->get('form');
    
        $subData['task']=null;
    
        $request->request->set('form',$subData);
    
        $form->handleRequest($request);
    
    
        if ($form->isValid()) {
    
          //do stuff
        }
    
    
        return $this->render('default/index.html.twig', array(
            'form' => $form->createView()
        ));
    }
    

    以数组的形式获取名称为“form”的提交数据,将所述值更改为null,然后将请求的值设置为新值并让表单处理它。

    还有一个简单的表格

    class Form extends AbstractType
    {
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
                ->add('task')
                ->add('save', SubmitType::class);    
    
        }
    
    }
    

    无论你输入什么,提交表单后数据始终为空。当然,您需要先验证验证码,然后再将值设置为 null。

    【讨论】:

      【解决方案3】:

      您可以将不完整的实体传递给当您的控件发现表单无效时调用的操作。

      public function updateAction(Request $request, $id)
      {
          $entity = $this->EM()->getRepository('Bundle:Entity')->find($id);
          if (!$entity) {
              throw $this->createNotFoundException('Unable to find Entity entity.');
          }
      
          $form = $this->createForm(new RecommendationType()
              ,$entity
              ,array(
                  'attr'            => array(
                      ,'entity'         => $entity
                      )
                  )
              );
      
          $form->bind($request);
          if ($form->isValid()) {
              $this->EM()->persist($entity);
              $this->EM()->flush();
      
              return $this->redirect($this->generateUrl('entity_show'
                  ,array('id' => $id)));
          } else {
              $entity->setCapthca(Null);
          } 
      
          return $this->render('Bundle:Entity:edit.html.twig'
              ,array(
                  'entity'            => $entity
                  ,'form'             => $form->createView()
                  )
              );
      }
      

      创建动作会有类似的修改。

      【讨论】:

      • 谢谢,但联系表不是实体。它只是一种通过电子邮件发送详细信息的表单类型;上面没有 getter/setter。
      猜你喜欢
      • 2010-09-30
      • 1970-01-01
      • 2017-08-23
      • 2014-01-11
      • 2011-09-15
      • 1970-01-01
      • 2023-04-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多