我尝试编写动态表单来编辑用户。
里面有一个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(),
));
}
有什么主意吗?谢谢
答案 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 %}