【问题标题】:Symfony-form not treated, if checkboxes are unchecked (= request empty)如果未选中复选框(= 请求为空),则不处理 Symfony 表单
【发布时间】:2021-07-17 23:14:29
【问题描述】:

我有一个只有两个复选框的表单。当两者都未选中时,request 为空,因此提交的表单不会在控制器中处理。

任何想法,我如何在“未选中”复选框的请求中发布一些内容?

MyChoiceFormType

    [...]

    public function buildForm(FormBuilderInterface $builder, array $options) {

        $builder
            ->add('voucher_buy', CheckboxType::class, [
                'label' => 'buy voucher',
                'data'  => false,               // un-checked as default
                'label_attr' => [
                    'class' => 'switch-custom'  // Bootstrap-toggle (=switch-button)
                ],
            ])
            ->add('voucher_use', CheckboxType::class, [
                'label' => 'use voucher',
                'data'  => false,               // un-checked as default
                'label_attr' => [
                    'class' => 'switch-custom'  // Bootstrap-toggle (=switch-button)
                ],
            ])
        ;
    }

    [...]

控制器

    [...]

    // generate the FORM
    $form = $this->createForm(MyChoiceFormType::class);


    // handle the submitted FORM
    $form->handleRequest($request);

    if ( $form->isSubmitted() && $form->isValid() ) {
        dd($form->getData());   // <-- not getting here, when both checkboxes are unchecked

        // form shall be treated here and then
        // redirect to another page
    }

    [...]

【问题讨论】:

  • 如果它没有进入isValid,那么你可能有错误。当你转储 $form->getErrors() 时,你能说出你得到了什么吗?
  • 错误为空。备注:请求也是空的(dump($request->request);)
  • $form->isSubmitted() 怎么样?是真的吗?
  • 您应该添加一个提交按钮(这将发送其值而不会产生进一步的后果)或带有一些随机字段的隐藏字段(隐藏类型)。 csrf_protection 也足够了。但是,请检查提交按钮是否在 &lt;form&gt;
  • 您是否禁用了 csrf 保护?如果不是,则应添加隐藏输入,使请求非空(并提高整体安全性)

标签: forms symfony checkbox toggle is-empty


【解决方案1】:

肮脏的黑客

我添加了一个隐藏字段,解决了这个问题。

MyChoiceFormType

    [...]

    public function buildForm(FormBuilderInterface $builder, array $options) {

        $builder
            ->add('voucher_buy', CheckboxType::class, [
                'label' => 'buy voucher',
                'data'  => false,               // un-checked as default
                'label_attr' => [
                    'class' => 'switch-custom'  // Bootstrap-toggle (=switch-button)
                ],
            ])
            ->add('voucher_use', CheckboxType::class, [
                'label' => 'use voucher',
                'data'  => false,               // un-checked as default
                'label_attr' => [
                    'class' => 'switch-custom'  // Bootstrap-toggle (=switch-button)
                ],
            ])
        ;

        // as the from post will be empty, if both checkboxes are unchecked
        // this dummy-field only ensures that at least something is in the
        // posted form
        $builder->add('dummy', HiddenType::class, [
            'data' => 'only_dummy_data',
        ]);
    }

    [...]

【讨论】:

    【解决方案2】:

    我今天学到了一件事:未选中的复选框不会被传输。我不明白为什么,我有一个我需要传输错误值,因为我的意思是在 PRE_SUBMIT 上用它做一些事情。好吧,我有一个choiceType 而不是checkbox,看起来不太漂亮,但它确实有效!

    【讨论】:

      【解决方案3】:

      有同样的问题,不明白为什么没有像 'unchecked_value' => false 这样的未选中复选框类型的选项值。

      我必须手动检查提交的字段,检查字段是否尚未提交,然后我知道它在表单提交中丢失,这意味着它等于 false。

      这是我的课

      public function setUncheckedReplacementFields(array $data)
      {
          foreach($this as $property => $value){
              if(str_contains('Replacement', $property) !== false){
                  if(!in_array($property, $data)){
                      $method = sprintf('set%s', ucfirst($property));
                      if(method_exists(this, $method)){
                          $this->$method(false);
                      }
                  }
              }
          }
      }
      

      在我坚持表格之前,我会运行这个

      $object->setUncheckedReplacementFields($request->request->get($form->getName()));
      

      所以如果字段不是表单的一部分,我知道它已被取消选中,我循环对象以找到这些复选框并将它们设置为 false 在我的情况下未选中。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-15
        • 1970-01-01
        相关资源
        最近更新 更多