symfony: [DX] [Form] Ability to reset form validation errors (or prevent them from rendering)
I’ve implemented the cookbook solution for dynamic generation of submitted forms across several projects. Sometimes these forms need to add/update/remove several fields, so my JavaScript replaces the entire form - not just a single, hard-coded element like in the example. My controllers typically look something like this:
public function testAction(Request $request)
{
$entity = new Entity();
$form = $this->createForm('foo', $entity);
$form->handleRequest($request);
if ($form->isValid() && !$request->isXmlHttpRequest()) {
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush($entity);
return $this->redirectToRoute('controller_index');
}
return ['form' => $form->createView()];
}
The problem
This works pretty well, but there’s one major annoyance - AJAX submissions of incomplete forms result in lots of red errors everywhere. This occurs because Symfony validates the form by default during $form->handleRequest($request)
.
The cookbook recommends supressing form validation by stopping propagation of the POST_SUBMIT
event. However, I have other services listening for that event, so this approach isn’t feasible.
I’m currently restoring to re-building the form just prior to the return
:
// ...
// Don't show any errors on partial AJAX submissions
if ($request->isXmlHttpRequest()) {
$form = $this->createForm('foo', $entity);
}
return ['form' => $form->createView()];
This works, but it seems kinda kludgy and not like an ideal solution, which is why I’ve tagged this [DX]
. It would be great if Symfony could provide a built-in method to prevent this common problem without weird workarounds.
Proposed solutions
Would it be possible to add a clearErrors()
method to FormInterface
? Ideally this would remove any previously-set validation errors (as if the form were never validated).
Alternatively, perhaps we could have some way of easily hiding/removing errors from the view? Maybe a boolean flag on the createView
method, a FormView::clearErrors
method, a setting on the FormRenderer
, or something to that effect?
About this issue
- Original URL
- State: closed
- Created 9 years ago
- Reactions: 5
- Comments: 29 (13 by maintainers)
@fabpot Could we please reopen this? Or go forward with #23838?
The implementation for this is already done in #14233 and all that is required is the political will to merge it into some version.
The proposed workaround doesn’t work with FormTypes for entities also containing unmapped fields.
I have a case when I want to know if a form is valid or not and still not show the errors. So supressing the validation or setting an option in the FormType is not an option.
Could this be reconsidered?
As an alternative to #14233/#27571, I have implemented #27580 which adds a new
ClearableFormInterface
instead of modifying an existing interface. Not only does this avoid the BC-break, it also avoids us adding the method to things likeButton
which don’t support errors anyway.@ouassini that is not the same. I have had occasions where I want the validation to be done as normal, but then for other reasons (depending on circumstances) want to clear all errors and present the form to the user again. This is a real need, and it would not cost much to add this flexibilty to the Symfony framework.
I finally found a solution with this documentation: http://symfony.com/doc/current/form/dynamic_form_modification.html#suppressing-form-validation
Create a form type extension especially for this event:
Then, on you controller:
And voilà! 😄
But I think it would be great to just have an option for that. Or maybe on form handling process?
Maybe there is a bundle for that, but I didn’t find it.
And BTW, I’m not sure this is the “proper” solution because this method deactivate all
FormEvents::POST_SUBMIT
callbacks, not only validation.If you have custom process based on this event, I think they will not be called.
+1 Unfortunately, I use the same trick… A way to bypass the assertions in the request handling process would be great (or even a clearErrors method).
Yes, you can pass it in as an option to the form, but then you lose the validation. Sometimes you want the validation to happen, but then depending on other if statements clear the errors and present the form again clear of errors. This is a feature for us power users, that wants flexibility in how we handle forms.
+1
+1