Hello everyone!

We have been investing plenty of personal time and energy for many years to share our knowledge with you all. However, we now need your help to keep this blog running. All you have to do is just click one of the adverts on the site, otherwise it will sadly be taken down due to hosting etc. costs. Thank you.

Example below shows us how to handle form errors manually with a service class. The problem with this approach is, it won't auto-fill form fields if an error occurs so you need to handle it yourself too.


Service definition


# sport/src/Football/FrontendBundle/Resources/config/services.yml
services:
football_frontend.service.form_error:
class: Football\FrontendBundle\Service\FormErrorService

Error service class


# src/Football/FrontendBundle/Service/FormErrorServiceInterface.php
namespace Football\FrontendBundle\Service;

use Symfony\Component\Form\FormInterface;

interface FormErrorServiceInterface
{
public function getErrors(FormInterface $form);
}

# sport/src/Football/FrontendBundle/Service/FormErrorService.php
namespace Football\FrontendBundle\Service;

use Symfony\Component\Form\FormInterface;

class FormErrorService implements FormErrorServiceInterface
{
public function getErrors(FormInterface $form)
{
$errors = array();

// This part gets global form errors (like csrf token error)
foreach ($form->getErrors() as $error) {
$errors[] = $error->getMessage();
}

// This part gets form field errors
foreach ($form->all() as $child) {
if (! $child->isValid()) {
$options = $child->getConfig()->getOptions();
$field = $options['label'] ? $options['label'] : ucwords($child->getName());
// Implode because there can be more than one field errors
$errors[strtolower($field)] = implode('; ', $this->getErrors($child));
}
}

return $errors;
}
}

Controller part


class CountryController extends Controller
{
public function createAction(Request $request)
{
// .....

if ($form->isValid() !== true) {
$errors = $this->get('football_frontend.service.form_error')->getErrors($form);

return $this->render(
'FootballTeamBundle:Create:country.html.twig',
[
'form' => $form->createView(),
'errors' => $errors
]
);
}

// .....
}
}

Twig template part


{% if errors is defined and errors is iterable %}
<div class="global-form-errors">
<ul>
{% for field, message in errors %}
<li>{{ message }}</li>
{% endfor %}
</ul>
</div>
{% endif %}