imorente / gatsby-netlify-form-example

Example site integrating Netlify's form handing in Gatsby's starter template
MIT License
138 stars 32 forks source link

Form (with Formik) is listed on netlify but doesn't receive ajax requests #19

Closed fsgreco closed 5 years ago

fsgreco commented 5 years ago

I managed to configure everything as expected with Formik, and the ajax requests shows me the success message, but the netlify form section is still empty (even if the form is listed and aknowledged by netlify).

This is my contact component:

import React from 'react'
import { Formik, Form, Field, ErrorMessage } from 'formik'
import Layout from "../components/layout"
import SEO from "../components/seo"

const ContactForm = () => (
<Layout>
    <SEO title="Form with Formik" />
    <main class="page-contact-form">
    <h1>Do your booking</h1>
    <Formik
        initialValues={{ email: '', name: '', start: '', end: '', message: '' }}
        validate={values => {
            let errors = {};
            if (!values.email) {
                errors.email = 'Required';
            } else if (
                !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(values.email)
            ) {
                errors.email = 'Invalid email address';
            }
            return errors;
        }}

    onSubmit={(values) => {
        fetch("/", {
            method: "POST",
            headers: { "Content-Type": "application/x-www-form-urlencoded" },
            body: ({
                "form-name": "contact",
                ...values
            })
        }).then(() => alert("Thank you!"))

        }}
    >
        {({ isSubmitting }) => (
        <Form name="contact" data-netlify="true" action="/grazie">
                <input type="hidden" name="form-name" value="contact" />
            <label>Name and Surname: <br />
                    <Field type="text" name="name" placeholder="Nome Cognome" />
                    <ErrorMessage name="name" component="div" />
            </label>
            <br />
            <label>Email: <br />
            <Field type="email" name="email" placeholder="Richiesto" />
            <ErrorMessage name="email" component="div" />
            </label>
            <br />

            <label>Start and End <br />

            <Field type="date" name="start" />
            <ErrorMessage name="start" />
            &nbsp;
            <Field type="date" name="end" />
            <ErrorMessage name="end" />
            </label>
                <br />
            <label>
                Message: <br />
                <Field type="text" name="message" />
                <ErrorMessage name="message" />
            </label>
            <br />
            <button type="submit" disabled={isSubmitting}>
                Submit
            </button>
        </Form>
        )}
    </Formik>
    </main>
</Layout>
)

export default ContactForm
fsgreco commented 5 years ago

I manage to get it working with some help from stackoverflow. This is the final result (I was lacking an encode function to pass the values as a string through the netlify API), so the only changes are to place a function encode at the top and the encode the values on the submit data that you send to netlify:


[...]

import SEO from "../components/seo"

function encode(data) {
    return Object.keys(data)
        .map(key => encodeURIComponent(key) + "=" + encodeURIComponent(data[key]))
        .join("&");
}

const ContactForm = () => (

[...]

    fetch("/", {
        method: "POST",
        headers: { "Content-Type": "application/x-www-form-urlencoded" },
        body: encode({
            "form-name": "formik",
            ...values
        })

[...]
yansusanto commented 5 years ago

@anonimoconiglio

I'm doing the same but for some reasons, I'm not able to post to Netlify. I've checked your code and pretty much the same as mine.

I'm struggling to debug the problem. Maybe you can point me in the right direction?

import React from 'react';
import { Formik, Form, Field, ErrorMessage } from 'formik';
import * as Yup from 'yup';
import { navigate } from 'gatsby';

const schema = Yup.object().shape({
    name: Yup.string()
        .min(3, 'Too Short!')
        .max(50, 'Too Long!')
        .required('Name is required'),
    email: Yup.string()
        .email('Invalid email')
        .required('Email is required'),
});

function encode(data) {
    return Object.keys(data)
        .map(
            key => encodeURIComponent(key) + '=' + encodeURIComponent(data[key])
        )
        .join('&');
}

const FirstExample = () => (
    <Formik
        initialValues={{ name: '', email: '', message: '' }}
        validationSchema={schema}
        onSubmit={values => {
            fetch('/contact', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                },
                body: encode({
                    'form-name': 'contact',
                    ...values,
                }),
            })
                .then(navigate('/thanks'))
                .catch(error => alert(error));
        }}
    >
        {({ isSubmitting }) => (
            <Form name="contact" data-netlify="true" action="/thanks">
                <input type="hidden" name="form-name" value="contact" />
                <div className="form-control">
                    <label htmlFor="name">Name</label>
                    <Field type="text" name="name" />
                    <ErrorMessage name="name" />
                </div>
                <div className="form-control">
                    <label htmlFor="email">Email</label>
                    <Field type="email" name="email" />
                    <ErrorMessage name="email" />
                </div>
                <div className="form-control">
                    <label htmlFor="message">Message</label>
                    <Field component="textarea" rows="8" name="message" />
                </div>
                <button className="button inverse" type="submit">
                    Submit
                </button>
            </Form>
        )}
    </Formik>
);

export default FirstExample;