grav-plugin-form icon indicating copy to clipboard operation
grav-plugin-form copied to clipboard

AJAX submission returns invalid JSON

Open mstieranka opened this issue 4 years ago • 1 comments

When submitting a form using AJAX (via axios in my case), the JSON response has the action name appended to it, which makes it so that the JSON cannot be parsed (SyntaxError: JSON.parse: unexpected non-whitespace character after JSON data at line 2 column 1 of the JSON data).

I am loading the form on the site using {% include "forms/form.html.twig" with { form: forms('kontakt-ajax') } %}.

Frontmatter with the form:

---
title: Formulár
routable: true
cache_enable: false
visible: false
form:
    name: kontakt-ajax
    template: form-messages
    action: ine/formular
    refresh_prevention: true
    classes: 'contact-form transition-all transition-100 overflow-hidden'
    fields:
        # Here is a list of all fields
    buttons:
        submit:
            type: submit
            classes: 'px-4 py-2 rounded font-display text-primary-700 bg-primary-200 hover:bg-gray-900 hover:text-gray-200 transition-all transition-250 cursor-pointer w-40'
            outerclasses: my-4
            value: 'Odoslať správu'
    process:
        message: 'Ďakujeme, že ste nám napísali! Pokúsime sa Vám odpovedať čo najskôr.'
        email:
            subject: '{{form.value.category|e}} - {{ form.value.subject|e }} (Kontaktný formulár)'
            body: '{% include "forms/data.html.twig" %}'
            from: '{{ form.value.email }}'
---

JS used for sending the request:

axios({
    method: form.method,
    url: '/ine/formular.json',
    data: {
        'name': form.name.value,
        'email': form.email.value,
        'category': form.category.value,
        'subject': form.subject.value,
        'message': form.message.value,
        'gdpr': form['gdpr-'].value,
        '__form-name__': 'kontakt-ajax',
        '__unique_form_id__': form.__unique_form_id__.value,
        'form-nonce': form['form-nonce'].value
    },
    headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        'X-Requested-With': 'XMLHttpRequest'
    }
}).then(response => {
    console.log(response);
    form.style.maxHeight = `${form.scrollHeight}px`;
    // Create message
    if (response.data.status === 'success') {
        // Style message and add content
        text.textContent = response.data.message;
        text.classList.add('bg-green-200', 'border-green-500', 'border-l-4', 'py-2', 'px-4', 'my-4');
    } else {
        switch (response.data.message) {
            case 'PLUGIN_FORM.FORM_ALREADY_SUBMITTED':
                text.textContent = 'Tento formulár ste možno už odoslali. Ak ho chcete skúsiť znovu odoslať, obnovte prosím stránku.';
                break;
            default:
                text.textContent = 'Nastala nejaká chyba, skúste obnoviť stránku.';
        }
        text.classList.add('bg-red-200', 'border-red-500', 'border-l-4', 'py-2', 'px-4', 'my-4');
    }
}).catch(error => {
    console.error(error);
})

The returned data:

{"status":"success","message":"\u010eakujeme, \u017ee ste n\u00e1m nap\u00edsali! Pok\u00fasime sa V\u00e1m odpoveda\u0165 \u010do najsk\u00f4r."}
ine/formular

I managed to hack around it by using JSON.parse(response.data.split("\n")[0]);, but that is less than ideal.

mstieranka avatar Sep 30 '19 16:09 mstieranka

Looks like you have something extra in the response, that likely comes from some echo.

mahagr avatar Oct 01 '19 11:10 mahagr