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



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

里面有一个邮政编码(代码邮政(。如果有人更改邮政编码,则应更改城市列表(公社(。 我使用Symfony推荐的动态形式。这适用于我的注册表单,但不适用于此编辑表单。

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

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

这是我的代码:


//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'       => 'AppEntityCodePostal',
'placeholder' => ''/
])
->add('email');
$formModifier = function (FormInterface $form, CodePostal $codePostal = null) {
$communes = null === $codePostal ? [] : $codePostal->getCommunes();
$form->add('commune', EntityType::class, [
'class' => 'AppEntityCommune',
'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(),
));
}

//templates/account/edit.html.twig
{% extends 'base.html.twig' %}

{% block stylesheets %}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script>
$(document).ready(function () {
var $codePostalAutoComplete = $('#edit_user_form_codePostalAutoComplete');
var $codePostal = $('#edit_user_form_codePostal');
$codePostalAutoComplete.change(function () {
$newValue = $codePostalAutoComplete.val();
$('#edit_user_form_codePostal option').filter(function () {
return($(this).text() == $newValue); // To select Blue
}).prop('selected', true);
// ... retrieve the corresponding form.
var $form = $(this).closest('form');
// Simulate form data, but only include the selected codepostal value.
console.log($form); 
var data = {};
data[$codePostal.attr('name')] = $codePostal.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) { // Replace current position field ...
$('#edit_user_form_commune').replaceWith(
// ... with the returned one from the AJAX response.
$(html).find('#edit_user_form_commune')
);
// Position field now displays the appropriate positions.
}
});
})

});
</script>
{% endblock %}
{% block title %}Modifier mon compte
{% endblock %}
{% 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="none;">{{ form_row(form.codePostal) }}</div>
{{ form_row(form.commune) }}
{{ form_row(form.telephone) }}
{{ form_row(form.email) }}
</p>

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

知道吗?谢谢

正如@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 %}

相关内容

  • 没有找到相关文章

最新更新