【问题标题】:Symfony form doesn't change value by using FormEvents::PRE_SUBMITSymfony 表单不会通过使用 FormEvents::PRE_SUBMIT 来改变值
【发布时间】:2021-07-28 02:49:06
【问题描述】:

我有以下问题:在 Symfony(版本 4.4.22)中,我创建了一个带有日期字段和复选框的 FormType。如果选中该复选框,则该字段的值应为“31.12.9999”。

如果请求表单的字段infiniteValidTo 的值为1,则validTo 的值应从空变为“31.12.9999”。 (在我的情况下,提交表单时,日期字段的值为“null”。)

因此,我使用 pre_submit 钩子向表单构建器添加了一个 EventListener,该钩子将在表单验证之前添加此信息。


  /**
   * {@inheritdoc}
   */
  public function buildForm(FormBuilderInterface $builder, array $options) {
    $builder      
      ->add('validTo', DateType::class, [
        'required'           => FALSE,
        'format'             => 'dd.MM.yyyy'
      ])
      ->add('infiniteValidTo', CheckboxType::class, [
        'required'           => FALSE
      ])
      ->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
        $data = $event->getData();
        if (isset($data['infiniteValidTo']) && $data['infiniteValidTo'] === '1') {
          $data['validTo'] = '31.12.9999';
        }
        $event->setData($data);
      });
  }

  /**
   * {@inheritdoc}
   */
  public function configureOptions(OptionsResolver $resolver) {
    $resolver->setDefaults([
      'data_class'  => SettingFormModel::class,
      'constraints' => [
        new Callback([
          'callback' => [$this, 'validateFormModel']
        ])
      ]
    ]);
  }

  /**
   * @param SettingFormModel          $object
   * @param ExecutionContextInterface $context
   */
  public function validateFormModel(SettingFormModel $object, ExecutionContextInterface $context): void {
    dump($object);
  }

在离开侦听器方法之前,数据数组具有正确的值(通过转储变量)。

为了以动态方式验证表单,我为数据对象定义了一个回调方法。当数据容器到达方法时,我对 validTo 字段的更改就消失了。如果我将该字段更改为一个简单的文本字段,它可以工作,但不适用于日期字段。

调试了很多时间,发现方法mapFormsToData并没有将变化转化为表单对象。

是我配置错误还是 symfony 中的错误?其他人是否对表单有同样的问题?

【问题讨论】:

标签: php symfony symfony4 symfony-forms


【解决方案1】:

我发现了错误。 SettingFormModel 的设置器不正确。修复监听器后,它应该正常工作。

【讨论】:

    【解决方案2】:

    您可以使用 post_submit 事件

    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder      
          ->add('validTo', DateType::class, [
            'required'           => FALSE
          ])
          ->add('infiniteValidTo', CheckboxType::class, [
            'required'           => FALSE
          ]);
    
        $builder->get('infiniteValidTo')->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) {
            if ($event->getForm()->getData()) {
                $event->getForm->getParent()->getData()->setValidTo(new \DateTime('9999-12-31'));
            }
        });
    }
    

    【讨论】:

    • 我添加了您的建议,但没有任何效果。字段validTo 的值为空。
    • 改变if条件
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-07
    • 1970-01-01
    • 2021-03-05
    • 1970-01-01
    相关资源
    最近更新 更多