Agregar error al elemento de formulario de Symfony 2

83

Verifico alguna validación en mi controlador. Y quiero agregar un error a un elemento específico de mi formulario en caso de falla. Mi forma:

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'));

El método addError () agrega error al formulario, no al elemento. ¿Cómo puedo agregar un error al elemento locationRadius?

Alex Pliutau
fuente

Respuestas:

178

Tu puedes hacer

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

Como elementos de forma también son de FormInterfacetipo.

Mun Mun Das
fuente
@ m2mdas, ¡gran respuesta! ¿Cómo traduciríamos esto? porque una vez que creamos una instancia de FormError, no la traducirá, ¿verdad? Lo intenté y no se traduce, y creo que tiene sentido. ¿Cómo traduciría una instancia de FormError?
Mick
2
Hola @ Patt, perdón por la respuesta tardía. El componente Validator se encarga de traducir los mensajes de violación de restricciones de formulario antes de que los mensajes de error se agreguen al formulario. Para la adición de error personalizado que tiene traducir el mensaje misma manera como lo hace para otras cadenas, por ejemplo,$this->get('translator')->trans('error message')
Mun Mun Das
1
@ m2mdas Pero, ¿cómo imprime este error en su vista? Intenté esto, pero no entra form_errors(form)en mi ramita.
Nat Naydenova
1
@NatNaydenova Sé que ha pasado un tiempo, pero inténtaloform_erros(form.my_field_name)
TMichel
3
Tenga en cuenta: para obtener un error al imprimir usando form_errors (formulario), agregue su error al formulario en sí, por ejemplo, $ form-> addError (new FormError ('error msg');
beterthanlife
8

Bien chicos, tengo otra forma. Es más complejo y solo para casos específicos.

Mi caso:

Tengo un formulario y, después de enviarlo, publico datos en el servidor API. Y también obtuve errores del servidor API.

El formato de error del servidor API es:

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

Mi objetivo es obtener una solución flexible. Establezcamos el error para el campo correspondiente.

$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);

¡Eso es!

¡NOTA! addError()el método omite la opción error_mapping .


Mi formulario (formulario de dirección incluido en el formulario de la empresa):

Empresa

<?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;
    }
}

Habla a

<?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;
    }
}
Jekis
fuente
¿Dónde colocas este código? $ vm = nuevo ViolationMapper ();
vidy videni
@vidyvideni, acción del controlador donde se manejará el envío del formulario. También puede ajustar este fragmento de código y moverlo a un método separado
Jekis