Gatsby – WordPress: contact form

This article covers one of the method how to create a contact form in Gatsby.js, getting the data from WordPress database through GraphQl.
You well need some skills of coding in JS, React, PHP, and some knowledge of WordPress functions.
The libraries which will be used here are:
- React Apollo
- Formik
- Formik Semantic UI React
- Yup
Let’s start from installing all above mentioned libraries.
In the terminal open the root folder of Gatsby instance and then
npm i react-apollo formik formik-semantic-ui-react yup
To get our form working we will have to program it in Gatsby and WordPress, as well. Let’s start from Gatsby part.
In root/src folder create new subfolder. Why don’t we name it “mutations”. Then we create new file. Too keep a logic in our naming convention, we name it ContactFormMutation.js.
import { gql } from '@apollo/client';
const CONTACT = gql`
mutation CONTACT ($clientMutationId: String!, $name: String!, $phone: String!, $company: String!, $email: String! $message: String!) {
createContact(
input: {
clientMutationId: $clientMutationId,
name: $name,
phone: $phone,
company: $company,
email: $email,
message: $message,
}
) {
success
data
}
}
`;
export default CONTACT;
Now we can create contact form component. Too keep a logic in a file structure, let’s create a new folder “ContactForm” in root/components folder. Then, we need to create a new file there: ContactForm.js.
We will take advantage of React state, Yup validation, and Formik functionality.
import React from 'react';
import PropTypes from 'prop-types';
import { Mutation } from 'react-apollo';
import {
Form, Input, SubmitButton, TextArea,
} from 'formik-semantic-ui-react';
import { Formik } from 'formik';
import * as Yup from 'yup';
import CONTACT from '../../mutations/ContactFormMutation';
const initialValues = {
email: 'a@a.com',
};
const validationSchema = Yup.object({
name: Yup.string().required(),
email: Yup.string().email('Incorrect email address').required('Required'),
phone: Yup.string().matches(new RegExp('[0-9]{7}'), 'Incorrect phone number').required('Required),
});
class ContactForm extends React.Component {
constructor(props) {
super(props);
this.state = {
formStatus: 'unsubmitted',
email: '',
name: '',
company: '',
phone: '',
message: '',
errorList: [],
};
this.handleInputChange = this.handleInputChange.bind(this);
}
handleInputChange(event) {
const { target } = event;
let value = '';
let name = '';
value = target.value;
name = target.name;
this.setState({
[name]: value,
});
}
form() {
const formState = this.state;
const emailState = formState.email;
const nameState = formState.name;
const phoneState = formState.phone;
const messageState = formState.message;
const companyState = formState.company;
return (
<div className="contact__form-container">
<Mutation
mutation={CONTACT}
onCompleted={(response) => {
if (response.createContact.success === true) {
this.setState({ formStatus: 'submitted' });
} else {
this.setState({ formStatus: 'error' });
const errors = JSON.parse(response.createContact.data);
this.setState({ errorList: errors });
}
}}
onError={() => {
this.setState({ formStatus: 'error' });
}}
>
{(addContact) => (
<Formik
initialValues={initialValues}
enableReinitialize
validationSchema={validationSchema}
onSubmit={(async_, { setSubmitting }) => {
setTimeout(() => {
this.setState({ formStatus: 'loading' });
addContact({
variables: {
clientMutationId: 'createContact',
email: emailState,
name: nameState,
phone: phoneState,
company: companyState,
message: messageState,
},
});
setSubmitting(false);
}, 1000);
}}
>
{({ isValid, dirty }) => (
<Form size={formSize}>
<div className="row">
<div className="col">
<Input
id="name"
name="name"
placeholder="Name"
focus
errorPrompt
value={nameState}
onChange={this.handleInputChange}
/>
</div>
<div className="col">
<Input
id="email"
name="email"
placeholder="Email"
focus
errorPrompt
value={emailState}
onChange={this.handleInputChange}
/>
</div>
</div>
<div className="row">
<div className="col">
<Input
id="phone"
name="phone"
placeholder="Phone"
focus
errorPrompt
value={phoneState}
onChange={this.handleInputChange}
/>
</div>
<div className="col">
<Input
id="Company"
name="company"
placeholder="Company"
focus
errorPrompt
value={companyState}
onChange={this.handleInputChange}
/>
</div>
</div>
<div className="row">
<div className="col">
<TextArea
id="message"
name="message"
placeholder="Message"
focus={true.toString()}
errorPrompt
style={{ minHeight: 60 }}
value={messageState}
onChange={this.handleInputChange}
/>
</div>
</div>
<div className="row">
<div className="col" />
<div className="col">
<SubmitButton
className="wc-button-submit"
name="submit"
type="submit"
disabled={!(isValid && dirty)}
>
<span>Indienen</span>
</SubmitButton>
</div>
</div>
</Form>
)}
</Formik>
)}
</Mutation>
</div>
);
}
render() {
const formState = this.state;
const { errorList } = this.state;
switch (formState.formStatus) {
case 'submitted':
return (
<div className="form-alert alert-success">
Thank you for your Message.
<p>We will reply ASAP.</p>
</div>
);
case 'loading':
return <div className="form-alert alert-info">Please wait</div>;
case 'error':
return (
<div className="form-alert alert-error">
An error has occurred.
{
errorList.map((error, index) => <p key={index}>{error}</p>)
}
</div>
);
default:
return this.form();
}
}
}
export default ContactForm;
Now our contact form component is ready, and we can import it to page component, footer component or wherever else we need.
It’s time to deal with WordPress part.
In functions.php file we need to register our contact form mutation:
<?php function create_contact_form_mutation() { register_graphql_mutation( 'createContact', array( 'description' => 'Custom mutation creating new contact form submission',
'inputFields' => array(
'email' => array(
'type' => 'String',
'description' => 'User email',
),
'name' => array(
'type' => 'String',
'description' => 'User name',
),
'phone' => array(
'type' => 'String',
'description' => 'User phone',
),
'company' => array(
'type' => 'String',
'description' => 'User company',
),
'message' => array(
'type' => 'String',
'description' => 'User message',
),
),
'outputFields' => array(
'success' => array(
'type' => 'Boolean',
'description' => 'Whether or not data was stored successfully',
'resolve' => function( $payload, $args, $context, $info ) {
return isset( $payload['success'] ) ? $payload['success'] : null;
},
),
'data' => array(
'type' => 'String',
'description' => 'Payload of submitted fields',
'resolve' => function( $payload, $args, $context, $info ) {
return isset( $payload['data'] ) ? $payload['data'] : null;
},
),
),
'mutateAndGetPayload' => function( $input, $context, $info ) {
$sanitized_data = array();
$errors = array();
$success_data = array();
$acceptable_fields = array(
'name',
'email',
'phone',
'company',
'message',
);
foreach ( $acceptable_fields as $field_key ) {
if ( ! empty( $input[ $field_key ] ) ) {
$sanitized_data[ $field_key ] = sanitize_text_field( $input[ $field_key ] );
} else {
$errors[] = $field_key . ' was not filled out.';
}
}
// ... Here we code what we want to do with the data we got.
// Either we want to send an email to admin,
// or create new custom post and save a message to database.
$output = '';
if ( ! empty( $errors ) ) {
$output = array(
'success' => false,
'data' => wp_json_encode( $errors ),
);
} else {
$output = array(
'success' => true,
'data' => wp_json_encode( $success_data ),
);
}
return $output;
},
)
);
}
add_action( 'graphql_register_types', 'create_contact_form_mutation' );
And this is more less it. Our contact form is ready.
Happy Coding!
Related articles
Ways to Make More Sales with Your Webshop
In today’s competitive online marketplace, making more sales with your webshop requires a strategic approach that combines effective marketing techniques, customer engagement, and user-friendly design. Whether you’re just starting out or looking to boost your existing sales, these proven strategies can help you maximize your webshop’s potential and drive revenue growth. Introduction Running a successful
Read more: Ways to Make More Sales with Your WebshopOnline marketingLandingspage: Crafting Effective Landing Pages that Convert
In the digital age, where attention is the currency and every click holds potential, the importance of a strategically designed landing page cannot be overstated. Acting as the digital handshake between your brand and potential customers, a landing page sets the tone for the online experience, making it crucial in not just attracting visitors but
Read more: Landingspage: Crafting Effective Landing Pages that ConvertOnline marketingOnline Branding: Building Your Digital Identity
In the bustling digital age, carving out a strong online branding strategy is not just beneficial; it’s essential for any business aiming for success. As the majority of consumers flock online for their informational and shopping needs, the presence and perception of your brand on the internet can significantly influence your business’s fate. This comprehensive
Read more: Online Branding: Building Your Digital IdentityReady to get started?
Tell us briefly what you need. We respond within one working day with a proposal for the next steps.