Dodaj błąd do elementu formularza Symfony 2

83

Sprawdzam walidację w moim kontrolerze. I chcę dodać błąd do konkretnego elementu mojego formularza w przypadku niepowodzenia. Mój formularz:

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 () dodaje błąd do formularza, a nie do elementu. Jak mogę dodać błąd do elementu locationRadius?

Alex Pliutau
źródło

Odpowiedzi:

178

Możesz to zrobić

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

Ponieważ elementy formularzy są również FormInterfacetypu.

Mun Mun Das
źródło
@ m2mdas, świetna odpowiedź! Jak byśmy to przetłumaczyli? ponieważ po utworzeniu instancji FormError nie zostanie ona przetłumaczona, prawda? Próbowałem i to nie tłumaczy tego, i myślę, że to ma sens. Jak przetłumaczyć instancję FormError?
Mick
2
Witaj @Patt, przepraszam za spóźnioną odpowiedź. Komponent Validator zajmuje się tłumaczeniem komunikatów o naruszeniu ograniczeń formularza, zanim komunikaty o błędach zostaną dodane do formularza. Aby dodać niestandardowy błąd, przetłumaczyłeś wiadomość w taki sam sposób, jak w przypadku innych ciągów, np.$this->get('translator')->trans('error message')
Mun Mun Das
1
@ m2mdas Ale jak Twoim zdaniem drukujesz ten błąd? Próbowałem tego, ale to nie wchodzi form_errors(form)w moją gałązkę.
Nat Naydenova
1
@NatNaydenova Wiem, że minęło trochę czasu, ale spróbujform_erros(form.my_field_name)
TMichel
3
Uwaga: aby otrzymać błąd podczas drukowania przy użyciu form_errors (formularz), dodaj swój błąd do samego formularza, np. $ Form-> addError (new FormError ('error msg');
beterthanlife
8

OK, mam inny sposób. Jest to bardziej złożone i tylko w określonych przypadkach.

Mój przypadek:

Mam formularz i po przesłaniu przesyłam dane na serwer API. Oraz błędy, które otrzymałem z serwera API.

Format błędu serwera API to:

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

Moim celem jest uzyskanie elastycznego rozwiązania. Pozwala ustawić błąd dla odpowiedniego pola.

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

Otóż ​​to!

UWAGA! addError()metoda pomija opcję error_mapping .


Mój formularz (formularz adresowy osadzony w formularzu firmy):

Firma

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

Adres

<?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
źródło
gdzie umieszczasz ten kod? $ vm = new ViolationMapper ();
vidy videni
@vidyvideni, akcja kontrolera, w której zostanie przesłany formularz. Możesz także dostosować ten fragment kodu i przenieść go do innej metody
Jekis,