在 PRE_SUBMIT 上向 Symfony 表单添加动态元素

Adding dynamic elements to Symfony form on PRE_SUBMIT

我现在正在尝试将 Symfony 表单组件与 Silex 框架一起使用。我在表单类型 class 的 buildForm 方法中添加了一些字段。用户还可以单击按钮并在前端使用 javascript 添加无限的 textarea 元素。现在在 PRE_SUBMIT 事件中,我执行以下操作将这些字段添加到表单

        $data = $event->getData();
    $form = $event->getForm();
    foreach ($data as $key => $value) {
        if (stristr($key, '_tb_') !== false) {
            $id = str_ireplace('_tb_', '', $key);
            $form->add('_tb_' . $id, 'hidden');
            $form->add('_title_' . $id, 'text', [
                'required'    => false,
                'label'       => 'Title',
                'constraints' => [
                    new Length(['min' => 6]),
                ]
            ]);
            $form->add('_img_url_' . $id, 'text', [
                'required'    => false,
                'label'       => 'Image Url',
                'constraints' => [
                    new Url(),
                ]
            ]);
            $form->add('_img_alt_' . $id, 'text', [
                'required'    => false,
                'label'       => 'Image Alt',
                'constraints' => []
            ]);
            $form->add('_content_' . $id, 'textarea', [
                'required'    => true,
                'attr'        => [
                    'data-role' => '_richeditor'
                ],
                'constraints' => [
                    new Length(['min' => 100]),
                ]
            ]);
        }
    }

我可以看到这些字段已添加到表单并在表单首次提交后填充,但出于某种原因,所有约束仅针对这些新添加的字段被忽略。有没有办法强制 Form 遵守新添加元素的约束?

表单组件和验证可能很棘手。一个容易产生的误解是表单类型选项 "required" 将 暗示 NotBlank 验证约束 。事实并非如此,the docs explain that option "superficial and independent from validation" 只关心表单元素渲染(HTML5 需要属性、标签等)。

为了使事情变得更棘手,您指定了最小长度约束,人们可能会认为没有(或零)长度将被视为无效。事实并非如此。长度验证器只关心 non-null / non-empty values。 :-/

所以!修改文本区域字段以包含 NotBlank() 应该可以解决问题:

$form->add('_content_' . $id, 'textarea', [
    'required'    => true,
    'attr'        => [
        'data-role' => '_richeditor'
    ],
    'constraints' => [
        new NotBlank(),
        new Length(['min' => 100]),
    ]
]);