3

My scenario is the following:

If the user choose true from "maxRedemptionForDiscount" and type "0" into the "maxRedemptionForDiscountValue" there should be an error message rendering to the specific field (at the position of the TextType field)

This is the form with an eventListener:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add(
        'maxRedemptionForDiscount',
        ChoiceType::class,
        [
            'placeholder'        => false,
            'multiple'           => false,
            'choices'            => [
                true  => 'discount.form_fields.set_max_redemptions',
                false => 'discount.form_fields.unlimited',
            ],
            'label'              => 'discount.form_fields.max_redemption_for_discount',
            'translation_domain' => 'entities',
            'required'           => false,
            'error_bubbling'     => true,
            'attr'               => [
                'class' => 'maxRedemptionForDiscountSelect',
            ],
        ]
    )->add(
        'maxRedemptionForDiscountValue',
        TextType::class,
        [
            'label'              => 'discount.form_fields.set_max_redemptions',
            'translation_domain' => 'entities',
            'required'           => false,
        ]
    )->addEventListener(
        FormEvents::PRE_SUBMIT,
        [$this, 'onPreSubmit']
    );
}

and this is the onPreSubmit function:

/**
 * @param FormEvent $event
 */
public function onPreSubmit(FormEvent $event)
{
    $data = $event->getData();
    $form = $event->getForm();

    if ($data['maxRedemptionForDiscount'] == 1) {
        if ($data['maxRedemptionForDiscountValue'] == 0) {
            $form->addError(new FormError('error message'));
        }
    }
    $event->setData($data);
}

Here is the twig code:

{{ form_row(form.maxRedemptionForDiscount) }}

<div id="maxRedemptionForDiscountValue">
    {{ form_row(form.maxRedemptionForDiscountValue) }}
</div>

This render a error message above the form. But what I want i to render a error message to the specific field.

This does not work:

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

If I try this the error message will disappear at the top of my form, but not showing up at the specific field position.

What I am doing wrong here?

goldlife
  • 1,949
  • 3
  • 29
  • 48

2 Answers2

4

First, you should set error_bubbling to false (or remove it as it's default behavior).

As documentation states

If true, any errors for this field will be passed to the parent field or form. For example, if set to true on a normal field, any errors for that field will be attached to the main form, not to the specific field.

Particularly for ChoiceType

Set that error on this field must be attached to the field instead of the parent field (the form in most cases).

Second, you should add error to specific form field

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

Third, you should edit your template

<div id="maxRedemptionForDiscountValue">
    {{ form_errors(form.maxRedemptionForDiscountValue) }}
    {{ form_row(form.maxRedemptionForDiscountValue) }}
</div>
DonCallisto
  • 29,419
  • 9
  • 72
  • 100
  • Ok, thanks I remove the error_bubling. As I write in my question I had try your solution "$form ->get('maxRedemptionForDiscountValue') ->addError(new FormError('error message'));" but this does not work for me. If I use this the error will only remove from the top of the form and not showing at the specific field. – goldlife Feb 08 '17 at 09:39
  • 1
    @goldlife did you tried both solutions: error_bubbling removed + add error to specific field? – DonCallisto Feb 08 '17 at 09:40
  • @goldlife and what's the result? – DonCallisto Feb 08 '17 at 09:44
  • as i say, the error message will disappear at the top of my form, but not showing up at the specific field position. – goldlife Feb 08 '17 at 09:45
  • It will only disappear. It is nowhere displayed. – goldlife Feb 08 '17 at 09:47
  • 1
    that sadly does not work to. If I try this - the form is valid although I choose true and and type 0. If I remove ->get('maxRedemptionForDiscountValue') and use only $form->addError an error message will display above the form. – goldlife Feb 08 '17 at 09:54
  • @goldlife I'm pretty sure that my solution should work, I suspect issue is elsewhere. BTW if you add error directly to form object, of course, you'll not have error messages displayed at field level – DonCallisto Feb 08 '17 at 09:59
  • yes I think this is the problem.. somewhere in the code there is a {% block %} where the error_message is overwritten... – goldlife Feb 08 '17 at 10:03
  • I am having a similar problem. If I add error to the specific form field, that error is somehow overwritten in the form processing, and form is valid... If I count errors in the form `isValid` method, there are no errors... – Matko Đipalo May 31 '17 at 11:11
0

remplace the pre-submit events for the post-submit events

->addEventListener(
    FormEvents::POST_SUBMIT,
    [$this, 'onPostSubmit']
);
daniel
  • 1