如何使用Symfony2表单清除字段值

时间:2013-02-22 00:19:53

标签: forms symfony

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

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

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

..请求与表单绑定后,但抛出AlreadyBoundException。我实际上已经设法使用它:

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

但这看起来不错,绝对不符合Symfony的标准。我已经查看了构建表单时可以提供的其他选项,但我看不到任何注意事项。

有没有人有任何想法?

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

3 个答案:

答案 0 :(得分:5)

我认为您希望处理此表单字段,例如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的$view->vars['value'] = ''方法中添加buildView(即CaptchaType)。这意味着该字段的数据未被清除,但不会传递给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

答案 1 :(得分:3)

在处理请求之前,有一种有趣的方法可以修改请求。然而,我看看斯蒂芬的答案,因为它看起来更干净。

像这样:

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()
    ));
}

使用名称'表格'获取提交的数据作为一个值数组,将所述值更改为null,然后使用新值设置请求的值并让表单处理它。

一个简单的表格

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

    }

}

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

答案 2 :(得分:0)

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

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()
            )
        );
}

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