Reputation: 1850
I have a little worries about a form on Symfony 4! In fact I have a page where I display groups. Among these groups there is one which is the default group. I have the right to delete groups. But if I decide to delete the default group, I have a modal window that will ask me to choose a new default group at the same time. That's the context is placed. Now I will state the problem ^^ So I created my form which will contain the list of all the groups besides the default group necessarily
form (DeleteDefaultGroupeType) :
class DeleteDefaultGroupeType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('defaultGroupeValidateurs', ChoiceType::class, [
'label' => "Service par défaut",
'placeholder' => "Sélectionnez un service",
'choices' => $options['groupeValidateursService']->getNotDefaultGroups(),
'choice_label' => function ($choice, $key, $value) {
return $choice->getNom();
}
]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => ParametresAdmin::class,
'groupeValidateursService' => GroupeValidateursService::class,
]);
}
}
In my index () function of my controller, I initialize this form and send as parameter to my view. Then in my view, I boot a modal window in case I want to delete the default group. So that's good I have my modal window with the form that allows me to choose a new group by default!
Controller (index function) :
$formDeleteDefaultGroupe = $this->createForm(DeleteDefaultGroupeType::class, $parametresAdmin, [
"groupeValidateursService" => $this->groupeValidateursService
]);
$formDeleteDefaultGroupe->handleRequest($request);
In my Twig view, I insert the modal :
<button class="btn close" data-target="#deleteModal{{groupe.id}}" data-toggle="modal" type="button">
<span aria-hidden="true">×</span>
</button>
{% if groupe == parametresAdmin.defaultGroupeValidateurs %}
{{ macro.replace_default_group(
'deleteModal'~groupe.id,
'Delete group ?',
formDeleteDefaultGroupe,
path('admin_validation_delete',{'id': groupe.id}))
}}
{% else %}
And the modale :
{%- macro replace_default_group(id, body, form, deleteLink) -%}
{% filter spaceless %}
<div id="{{ id }}" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
{{form_start(form)}}
<div class="modal-header">
<h4 class="modal-title">Supprimer?</h4>
<button class="close" data-dismiss="modal" type="button">×</button>
</div>
<div class="modal-body">
<p>{{ body }}</p>
{{form_widget(form)}}
</div>
<div class="modal-footer">
<a href="{{ deleteLink }}" class="btn btn-primary">Supprimer</a>
<button class="btn btn-secondary" data-dismiss="modal" type="button">Annuler</button>
</div>
{{form_end(form)}}
</div>
</div>
</div>
{% endfilter %}
{%- endmacro -%}
And so the action of my form will be on the function deleteGroupe () of my controller. He will sway him as a parameter the group he will have to delete. This variable is the groupValidators $ groupValidators in the function. And so in my controller, I re-initialize the form allowing me to choose a new group. And if it is submitted, it means that I tried to delete the default group, so we'll have to apply the changes. So I have to recover what was submitted in the form, namely the new group which will be the default one
/**
* Suppression d'un groupe de validateurs et transfert des demandes
* en attentes des utilisateurs vers le groupe par défaut
*
* @Route("/admin/validation/delete/{id}", name="admin_validation_delete")
*
* @param GroupeValidateurs $groupeValidateurs
* @return void
*/
public function deleteGroupe(Request $request, GroupeValidateurs $groupeValidateurs)
{
$form = $this->createForm(DeleteDefaultGroupeType::class, new ParametresAdmin(), [
"groupeValidateursService" => $this->groupeValidateursService,
]);
$form->handleRequest($request);
dump($form->getData());
if ($form->isSubmitted() && $form->isValid()) {
$newDefaultGroupe = $form->getData();
dd($newDefaultGroupe);
//Et là je modifie le groupe par défaut
}
dd('fin');
//Et ici je supprime le groupe que je veux supprimer
$this->groupeValidateursService->removeGroup($groupeValidateurs);
return $this->redirectToRoute("admin_validation_index");
}
Except that oddly, well it does not go into the isSubmitted && isValid. And if I make a $ form-> getData () outside the condition to see, then I happen to get the ParametresAdmin () object but in null. What was submitted was not taken into account
Upvotes: 0
Views: 234
Reputation: 8374
unless stated differently, the form component expects the form data to be submitted via a POST request. the form_start(form)
call will create that. However, it will create that with the route of the page that created it. Somehow you figured, you had to provide the form with the correct url, but you just put it in a link.
Links on the other hand are - generally speaking - by default GET requests (unless you steal the activation event and create a POST request instead somehow). So your request to the deletion page is just a GET request, hence no data.
There are a number of things that are possible at this point:
I'm not entirely sure, if this can be done in the template, but it probably can:
{{form_start(form, {action: deleteLink})}}
Otherwise, or in my opinion better (!!!), since the delete form should probably be handled by the right controller always:
$formDeleteDefaultGroupe = $this->createForm(
DeleteDefaultGroupeType::class, $parametresAdmin, [
"groupeValidateursService" => $this->groupeValidateursService,
"action" => $this->generateUrl('admin_validation_delete', [
"id" => $defaultGroupe->getId(), // <-- change to proper $var/func()
]),
]);
A note here: Why is there an {id}
in the path? The controller function certainly doesn't need it as far as I can tell.
Then all you'd have to do is change your delete button to an actual button
<button type="submit" class="btn btn-primary">Supprimer</button>
theoretically, you can change the method of the form to GET (in your deleteGroupe
function - nice mix of languages btw), which will lead to the form triggering on a GET request then. I don't like this much, tbh. But it works in pretty much the exact same way as 1. but instead of assigning the path to action
you assign 'GET'
to method
.
You still have to change your deletion <a>
to be a <button>
though. (or capture the click to submit the form to the different url)
Upvotes: 1