Yoan Arnaudov
Yoan Arnaudov

Reputation: 4164

symfony2 dynamic form modification ajax jquery invalid CSRF token

lets say I have products and product can be promo. When the checkbox promo is clicked I want promoPrice field to show up. Here is an example of my AbstractType

//...
//$builder->add(..);
$builder->add('promoProduct', 'checkbox', [
    'required' => false,
]);
$builder->add('promoPrice', 'hidden')
//$builder->add(..);

$formModifier = function (FormInterface $form, $promoProduct = null) {
    if ($promoProduct) {
        $form->add('promoPrice', 'money');
    }
};

$builder->addEventListener(
    FormEvents::PRE_SET_DATA,
    function (FormEvent $event) use ($formModifier) {
        $data = $event->getData();

        $formModifier($event->getForm(), $data->getPromoProduct());
    }
);

$builder->get('promoProduct')->addEventListener(
    FormEvents::POST_SUBMIT,
    function (FormEvent $event) use ($formModifier) {
        $promoProduct = $event->getForm()->getData();

        $formModifier($event->getForm()->getParent(), $promoProduct);
    }
);
//...

here is my javascript

    ...
    var $promoProduct = $('#product_form_promoProduct');

    $promoProduct.change(function() {
        var $form = $(this).closest('form');
        var data = {};

        if ($promoProduct.is(':checked')) {
            data[$promoProduct.attr('name')] = 1;
        } else {
            data[$promoProduct.attr('name')] = 0;
        }

        $.ajax({
            url: $form.attr('action'),
            type: $form.attr('method'),
            data: data,
            success: function(html) {
                $('#product_form_promoPrice').replaceWith(
                    $(html).find('#product_form_promoPrice')
                );
            }
        });
    });
    ...

So here is my problem, when I submit the form with data product_form[promoProduct]:0 the response comes with promoProduct field checked and promoPrice field visible because of the promoProduct field being checked. Also in the response I get 'Invalid CSRF token error'. It seems that the data I'm sending via AJAX is not used in the form, maybe because of the invalid csrf token?

I'm following this guide step by step http://symfony.com/doc/2.8/cookbook/form/dynamic_form_modification.html#cookbook-form-events-submitted-data

Thanks

Upvotes: 3

Views: 1037

Answers (2)

Heah
Heah

Reputation: 2389

Edited

You should also pass the token value in your ajax data :

$data['product_form']['_token'] = $('#product_form__token').val();

Upvotes: 4

LordWeedlle
LordWeedlle

Reputation: 75

Your form render a hidden token input in your page, you need to add it to your javascript data variable like data[$('#product_form_token').name()] = $('#product_form_token').val() so it isn't missing and you don't get CSRF error. Change product_form_token by the token input name if it's not exactly this.

In your controller use $checkbox = filter_var($checkbox, FILTER_VALIDATE_BOOLEAN); where $checkbox is your form field then set it in your form before you validate, persist and flush it. Sometimes 0 values can be considered as true meaning "you got something so it's true" for boolean values.

Upvotes: 0

Related Questions