Symfony动态形式:在属性路径“ civilite”中给出的“ string”,“ NULL”类型的预期参数

时间:2019-09-03 19:49:38

标签: symfony4 symfony-forms

我尝试编写动态表单来编辑用户。

里面有一个zipCode(codePostal)。如果有人更改邮政编码,则应该更改城市列表(市镇)。 我使用Symfony推荐的动力学形式。这对于我的RegisterForm非常有效,但不适用于此editForm。

我想,我想念一些东西要从用户那里获取信息吗? 因此,每次更改邮政编码时,它都无法获取动态表单并在我的控制台(ajax)中创建此异常:在属性路径“ civilite”中给出的类型为“字符串”,“ NULL”的预期参数。

此异常在$ form-> handleRequest($ request)上生成;控制器,但只是在更改邮政编码时,而不是在第一次加载表单时。

这是我的代码:

> x %>% select(Tr, id2, DeltaTr)
   Tr id2 DeltaTr
1   1  15     214
2   1  15     214
3   1  15     214
4   1  15     214
5   1  15     214
6   1  15     214
7   1  15     214
8   2  16      19
9   2  16      19
10  2  16      19
11  2  16      19
12  1  17     155
13  1  17     155
14  1  17     155
15  1  17     155
16  1  17     155

//Form/EditUserFormType.php

class EditUserFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {

        $user = $options['data'];

        $builder
            ->add('civilite',ChoiceType::class, array(
                'choices' => array('M.' => '1', 'Mme'  => '2'),
                'required' => true,
                'expanded' => true,
                'multiple' => false,
                'data' => $user->getCivilite()
            ))
            ->add('nom')
            ->add('prenom')
            ->add('societe')
            ->add('telephone')
            ->add('adresse')


            ->add("codePostalAutoComplete", TextType::class, [
                "mapped"=>false, 
                'required' => false,
                "label"=>"Code postal",
                ])

            ->add('codePostal', EntityType::class, [
                'class'       => 'App\Entity\CodePostal',
                'placeholder' => ''/

            ])

            ->add('email');

        $formModifier = function (FormInterface $form, CodePostal $codePostal = null) {
            $communes = null === $codePostal ? [] : $codePostal->getCommunes();

            $form->add('commune', EntityType::class, [
                'class' => 'App\Entity\Commune',
                'placeholder' => 'Choisir une commune',
                'choices' => $communes,  
            ]); 
        };




        $builder->addEventListener(
            FormEvents::PRE_SET_DATA,
            function (FormEvent $event) use ($formModifier) {
                // this would be your entity, i.e. SportMeetup
                $data = $event->getData();

                $formModifier($event->getForm(), $data->getCodePostal());
            }
        );




        $builder->get('codePostal')->addEventListener(
            FormEvents::POST_SUBMIT,
            function (FormEvent $event) use ($formModifier) {

                $codePostal = $event->getForm()->getData();


                $formModifier($event->getForm()->getParent(), $codePostal);
            }
        );
} 



    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => User::class,
        ]);
    }
}

//Controller/AccountController.php

public function edit(Request $request): Response
    {

        $em = $this->getDoctrine()->getManager();
        $user = $this->getUser();
        $form = $this->createForm(EditUserFormType::class,$user);



        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {

                $em = $this->getDoctrine()->getManager();       
                $em->persist($user);
                $em->flush();

                $this->addFlash('notice', 'Vos modifications on bien été prises en compte !');

                return $this->redirectToRoute('app_account_dashboard');

        }

        return $this->render('account/edit.html.twig', array(
            'user' => $user,
            'form' => $form->createView(),
        ));
    }

有什么主意吗?谢谢

1 个答案:

答案 0 :(得分:1)

正如@msg在评论中所说,我需要使用其他控制器来获取所需的子窗体;

//AccountController.php


public function editCommunesFieldByCodePostal(Request $request, CodePostalRepository $codePostalRepository)
    {
        $codePostal = $codePostalRepository->find($request->query->get('codePostalId'));

        if (isset($codePostal)){


            $user = new User();
            $user->setCodePostal($codePostal);

            $form = $this->createForm(EditUserFormType::class, $user);

            //dump($form);
            //die();

            if (!$form->has('user')) {
                return new Response(null, 204);
            }
            return $this->render('account/_specific_commune.html.twig', [
                'form' => $form->createView(),
            ]);
        }
    }
//account/edit.html.twig


{% block body %}

    <h1>Modifier mon compte</h1>

    {{ form_start(form) }}

    {{ form_row(form.civilite) }}
    {{ form_row(form.nom) }}
    {{ form_row(form.prenom) }}
    {{ form_row(form.societe) }}
    {{ form_row(form.adresse) }}
    {{ form_row(form.codePostalAutoComplete) }}
    <div style="display:none;">
    {{ form_row(form.codePostal, {
                attr: {
                    'data-specific-location-url': path('app_account_edit_communes_by_codepostal'),
                    'class': 'js-user-form-codePostal'
                }
            }) }}
    </div>

    <div class="js-specific-commune-target">
        {%  if form.commune is defined %}
            {{ form_row(form.commune, {
                attr: {
                    'class': 'js-user-form-commune'
                }
            }) }}
     {% endif %}
    </div>

    {{ form_row(form.telephone) }}
    {{ form_row(form.email) }}
</p>


<button class="btn" type="submit">Valider</button>
{{ form_end(form) }}


{% endblock %}


{% block javascripts %}
{{ parent() }}
 <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script>
$(document).ready(function() {




    $('#edit_user_form_codePostalAutoComplete').on('change', function(e) {


        $newValue = $('#edit_user_form_codePostalAutoComplete').val();
        $('#edit_user_form_codePostal option').filter(function() { 
            return ($(this).text() == $newValue); //To select Blue
        }).prop('selected', true);


        var $codePostalSelect = $('.js-user-form-codePostal');
        var $specificLocationTarget = $('.js-specific-commune-target');


            $.ajax({
                url: $codePostalSelect.data('specific-location-url'),
                data: {
                    codePostalId: $codePostalSelect.val()
                },
                success: function (html) {
                    if (!html) {
                        $specificLocationTarget.find('select').remove();
                        $specificLocationTarget.addClass('d-none');
                        return;
                    }
                    // Replace the current field and show
                    $specificLocationTarget
                        .html(html)
                        .removeClass('d-none')
                }
            });

    });
});
</script>

{% endblock %}