如何根据所选值进行验证?

时间:2018-08-02 07:10:08

标签: php symfony symfony3.x

我有一个简单的表格:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('name', null, ['required' => true])
        ->add('doYouWant', ChoiceType::class, ['choices' => ['no' => 'no', 'yes' => 'yes']])
        ->add('type')
    ;
}

我希望用户在选择doYouWant后选择“是”以具有强制性的“类型”选项,所以我正在尝试:

   $builder->addEventListener(
        FormEvents::PRE_SUBMIT,
        function (FormEvent $event) use ($builder) {
            $data = $event->getForm()->getData();

            if ($data['doYouWant'] == 'yes') {
                $builder->add('type', null, ['required' => true]);
            }

        }
    );

但这没关系...

2 个答案:

答案 0 :(得分:0)

您可以使用验证组并将您的断言放在您的实体中。

然后您可以根据提交的数据选择验证组,如下所示:

https://symfony.com/doc/current/form/data_based_validation.html

如何在实体上添加断言:

class MyEntity {

    /**
     * @Assert\NotBlank(groups={"YourGroup"})
     */
    protected $type;

}

然后在您的表单上

public function configureOptions(OptionsResolver $resolver)
{
  $resolver->setDefaults(array(
      'validation_groups' => function (FormInterface $form) {
              $data = $form->getData();

              $want = $data->getDoYouWant();

              if ($want) {
                  return ['YourGroup'];                   
              }

              return ['Default'];  
            },
    ));
}

答案 1 :(得分:0)

我认为最简单的方法是将constraints添加到您类型的每个字段中,然后在模板中,通过使用jquery,您可以基于下拉列表中的选定值来切换类型字段的可见性

# AppBundle/Form/ExampleType.php
$builder
    ->add('name', null, [
        'constraints' => [
             new NotBlank(['message' => 'This cannot be empty']),
        ]
    ])
    ->add('doYouWant', ChoiceType::class, [
        'placeholder' => 'Select',
        'choices' => ['no' => 'No', 'yes' => 'Yes'],
        'constraints' => [
            new NotBlank(['message' => 'This cannot be empty']),
        ]
    ])
    ->add('type', EmailType::class, [
        'constraints' => [
            new NotBlank(['message' => 'This cannot be empty']),
            new Email([
                'message' => "The email '{{ value }}' is not a valid email",
            ])
        ]
    ])
;

我已将type字段添加为电子邮件类型,仅用于测试目的。

# Controller/DefaultController.php
/**
 * @param Request $request
 * @Route("/test", name="test")
 * @return Response
 */
public function testAction(Request $request) : Response
{
    $form = $this->createForm(ExampleType::class);
    $form->handleRequest($request);
    if ($form->isSubmitted() && $form->isValid()) {
        dump($form->getData());die;
    }

    return $this->render('default/test.html.twig', [
        'form' => $form->createView(),
    ]);
}


# default/test.html.twig (assuming you are using bootstrap and jquery)
{% block body %}
<div class="container">
    <div class="row">
        <div class="col-xs-12">
            {{ form_start(form, { attr: { 'novalidate': 'novalidate' } }) }}
                <div class="form-group">
                    {{ form_label(form.name) }}
                    {{ form_widget(form.name,{ attr:{ class:'form-control' } }) }}
                    {{ form_errors(form.name) }}
                </div>
                <div class="form-group">
                    {{ form_label(form.doYouWant) }}
                    {{ form_widget(form.doYouWant,{ attr:{ class:'form-control' } }) }}
                    {{ form_errors(form.doYouWant) }}
                </div>
                <div class="form-group type hidden">
                    {{ form_label(form.type) }}
                    {{ form_widget(form.type,{ attr:{ class:'form-control' } }) }}
                    {{ form_errors(form.type) }}
                </div>
                <div class="form-group">
                    <button type="submit" class="btn btn-primary">Send</button>
                </div>
            {{ form_end(form) }}
        </div>
    </div>
</div>
{% endblock %}

{% block javascripts %}
<script>
    $(document).ready(function(){
        $('#appbundle_example_doYouWant').change(function(){
            var choice = $(this).val();
            if (choice == 'Yes') {
                $('.type').removeClass('hidden');
            } else {
                $('.type').addClass('hidden');
            }
        });
    });
</script>
{% endblock %}