85

I check some validation in my controller. And I want to add error to specific element of my form on failure. My form:

use Symfony\Component\Form\FormError;

// ...

$config = new Config();
$form = $this->createFormBuilder($config)
        ->add('googleMapKey', 'text', array('label' => 'Google Map key'))
        ->add('locationRadius', 'text', array('label' => 'Location radius (km)'))
        ->getForm();

// ...

$form->addError(new FormError('error message'));

addError() method adds error to form, not to element. How can I add an error to locationRadius element?

2 Answers 2

187

You can do

$form->get('locationRadius')->addError(new FormError('error message'));

As form elements are also of FormInterface type.

Sign up to request clarification or add additional context in comments.

6 Comments

@m2mdas, great answer! How would we translate this? because once we create a FormError instance, it won't translate it, am I right? I tried and it doesn't translate it, and I think it makes sense. How would you translate a FormError instance?
Hello @Patt, sorry for late reply. Validator component takes care of translating form constraint violation messages before the error messages are added to the form. For adding custom error you have translate the message same way as you do for other strings e.g, $this->get('translator')->trans('error message')
@m2mdas But how do you print this error in your view? I tried this, but it doesn't go in the form_errors(form) in my twig.
@NatNaydenova I know it's been a while but try form_erros(form.my_field_name)
Please note: to get an error to print using form_errors(form), add your error to the form itself e.g. $form->addError(new FormError('error msg');
|
8

OK guys, I have another way. It is more complex and only for specific cases.

My case:

I have a form and after submit I post data to the API server. And errors I got from the API server as well.

API server error format is:

array(
    'message' => 'Invalid postal code',
    'propertyPath' => 'businessAdress.postalCode',
)

My goal is to get flexible solution. Lets set the error for the corresponding field.

$vm = new ViolationMapper();

// Format should be: children[businessAddress].children[postalCode]
$error['propertyPath'] = 'children['. str_replace('.', '].children[', $error['propertyPath']) .']';

// Convert error to violation.
$constraint = new ConstraintViolation(
    $error['message'], $error['message'], array(), '', $error['propertyPath'], null
);

$vm->mapViolation($constraint, $form);

That's it!

NOTE! addError() method bypasses error_mapping option.


My form (Address form embedded in the Company form):

Company

<?php

namespace Acme\DemoBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Validator\Constraints;

class Company extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('companyName', 'text',
                array(
                    'label' => 'Company name',
                    'constraints' => array(
                        new Constraints\NotBlank()
                    ),
                )
            )
            ->add('businessAddress', new Address(),
                array(
                    'label' => 'Business address',
                )
            )
            ->add('update', 'submit', array(
                    'label' => 'Update',
                )
            )
        ;
    }

    public function getName()
    {
        return null;
    }
}

Address

<?php

namespace Acme\DemoBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Validator\Constraints;

class Address extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            // ...
            ->add('postalCode', 'text',
                array(
                    'label' => 'Postal code',
                    'constraints' => array(
                        new Constraints\NotBlank()
                    ),
                )
            )
            ->add('town', 'text',
                array(
                    'label' => 'Town',
                    'constraints' => array(
                        new Constraints\NotBlank()
                    ),
                )
            )
            ->add('country', 'choice',
                array(
                    'label' => 'Country',
                    'choices' => $this->getCountries(),
                    'empty_value' => 'Select...',
                    'constraints' => array(
                        new Constraints\NotBlank()
                    ),
                )
            )
        ;
    }

    public function getName()
    {
        return null;
    }
}

2 Comments

where do you place these code ? $vm = new ViolationMapper();
@vidyvideni, Controller action where form submit will be handled. Also you could adjust this piece of code and move it to a separate method

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.