动态形式Symfony上的约束违规

时间:2018-10-12 16:26:20

标签: ajax symfony symfony-forms

我在Symfony3.4上工作 我有一个动态表格country-> region-> city(3个不同的实体)。 我可以根据用户选择更改字段,而不会出现任何问题。

但是由于对字段城市(仅此字段)的约束违反,我无法保留在数据库中

我真的不知道为什么,因为我用相同的方式称呼他们(地区和城市)...

任何帮助都将受到欢迎。

这是表格:

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

    $em = $options['entityManager'];

    $builder
        ->add('rue', TextType::class, array(
            'label' => 'votre rue',
            'required' => true,
        ))

        ->add('pays', EntityType::class, array(
            'class' => 'AppBundle\Entity\Pays',
            'placeholder' => '--choisir--',
            'choice_label' => 'nom',
            'required' => true
        ))
    ;

    $addRegion = function (FormInterface $form, Pays $pays = null) {
        $regions = null === $pays ? array() : $pays->getRegions();

        $form->add('region', EntityType::class, array(
            'class' => 'AppBundle\Entity\Region',
            'placeholder' => '--choisir une région--',
            'choices' => $regions,
            'choice_label' => 'nom',
            'required' => true
        ));

    };

    $addVille = function (FormInterface $form, Region $region = null) {
        $villes = null === $region ? array() : $region->getVilles();

        $form->add('ville', EntityType::class, array(
            'class' => 'AppBundle\Entity\Ville',
            'placeholder' => '--choisir une ville--',
            'choices' => $villes,
            'choice_label' => 'nom',
            'required' => true
        ));


        $form->add('submit', SubmitType::class
        );

    };

    $builder->addEventListener(
        FormEvents::PRE_SET_DATA,
        function (FormEvent $event) use ($addRegion, $addVille){
            $form = $event->getForm();
            $addVille($form, null);
            $addRegion($form, null);
        }
    );

    $builder->addEventListener(
        FormEvents::PRE_SUBMIT,
        function (FormEvent $event) use ($addRegion, $addVille, $em) {
            $form = $event->getForm();
            $data = $event->getData();
            if(isset($data['pays'])){
                $paysId = $data['pays'];

                $repo = $em->getRepository('AppBundle\Entity\Pays');
                $pays = $repo->find($paysId);

                $addRegion($form, $pays);
                $addVille($form, null);
            }
            else if(isset($data['region'])){
                $regionId = $data['region'];

                $repo = $em->getRepository('AppBundle\Entity\Region');
                $region = $repo->find($regionId);

                $addVille($form, $region);
            }
        }
    );
}

这是模板:

{% block body %}

{% form_theme form 'bootstrap_4_layout.html.twig' %}

{% for message in app.flashes('notice') %}
    <div style="color:green;">
        {{ message }}
    </div>
{% endfor %}

{{ form_start(form) }}
{{ form_errors(form) }}
{{ form_end(form) }}

{%endblock%}

{%block javascripts%}

<script>
    var $pays = $('#adresse_pays');
    var $region = $('#adresse_region');
    var $ville = $('#adresse_ville');

    $pays.change(function() {
        var $form = $(this).closest('form');
        var data = {};
        data[$pays.attr('name')] = $pays.val();
        // Submit data via AJAX to the form's action path.
        $.ajax({
            url : $form.attr('action'),
            type: $form.attr('method'),
            data : data,
            success: function(html) {
                $ville.empty()
                var select = $(html).find('#adresse_ville > option')
                $ville.append(select)

                $region.empty()
                var select = $(html).find('#adresse_region > option')
                $region.append(select)
                $region.val($("#adresse_region option:first").val());
                console.log('regions')
                console.log(select)
            }
        });
    });


    $region.change(function() {
        var $form = $(this).closest('form');
        var data = {};
        data[$region.attr('name')] = $region.val();
        // Submit data via AJAX to the form's action path.
        $.ajax({
            url : $form.attr('action'),
            type: $form.attr('method'),
            data : data,
            success: function(html) {
                $ville.empty()
                var select = $(html).find('#adresse_ville > option')
                $ville.append(select)
                $ville.val($("#adresse_ville option:first").val());
                console.log('villes')
                console.log(select)
            }
        });
    });


</script>

{%endblock%}

这是表格上的提醒(城市字段旁边): 错误此值无效

由于调试栏,我走得更远,看来这个字段不是发送对象,而是发送整数。

我发现与另一个领域的区别在于城市领域:

Normalized Format submitted is null

在另一个区域(例如region)时

Normalized Format   

Region {#6035 ▼
  -id: 3
  -nom: "Catalogne"
  -villes: PersistentCollection {#6039 …}
  -pays: Pays {#5802 ▶}
  -adresses: PersistentCollection {#6041 …}

}

1 个答案:

答案 0 :(得分:0)

有效!

我拆分了功能

$ builder-> addEventListener(         FormEvents :: PRE_SUBMIT,...减半=>我删除了else if,并在更改“区域”时做了另一个类似的功能来监听。

困扰我的是我不明白为什么它会以这种方式起作用,而不是相反...

$builder->addEventListener(
    FormEvents::PRE_SUBMIT,
    function (FormEvent $event) use ($addRegion, $addVille, $em) {
        $form = $event->getForm();
        $data = $event->getData();
        if(isset($data['pays'])){
            $paysId = $data['pays'];
            $repo = $em->getRepository('AppBundle\Entity\Pays');
            $pays = $repo->find($paysId);
            $addRegion($form, $pays);
            $addVille($form, null); 
        }
    }        
);

$builder->addEventListener(
    FormEvents::PRE_SUBMIT,
    function(FormEvent $event) use ($addVille, $em) {
        $form = $event->getForm();
        $data = $event->getData();
        if(isset($data['region'])){
            $regionId = $data['region'];
            $repo = $em->getRepository('AppBundle\Entity\Region');
            $region = $repo->find($regionId);
            $addVille($form, $region); 
        }           
    }
);