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?

3 Answers 3

6

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>
Sign up to request clarification or add additional context in comments.

9 Comments

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 did you tried both solutions: error_bubbling removed + add error to specific field?
@goldlife and what's the result?
as i say, the error message will disappear at the top of my form, but not showing up at the specific field position.
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.
|
0

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

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

Comments

0

As suggested by @daniel, use a POST_SUBMIT event. Here is the issue with PRE_SUBMIT.

Personally I would not use a form event listener but attach a data_class on the form and then use a custom class constraint validator on that data_class. The validator can then add a violation on the specific field. See the documentation.

Comments

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.