Dit artikel behandelt een van de methoden voor het maken van een contactformulier in Gatsby.js, waarbij de gegevens uit de WordPress-database worden opgehaald via GraphQl.
Je hebt wel wat vaardigheden nodig op het gebied van coderen in JS, React, PHP en enige kennis van WordPress-functies.
De bibliotheken die hier zullen worden gebruikt zijn:
Reageer Apollo
Formik
Formik Semantische gebruikersinterface Reageren
JEP
Laten we beginnen met het installeren van alle bovengenoemde bibliotheken.
Open in de terminal de hoofdmap van Gatsby instance en dan
npm i react-apollo formik formik-semantic-ui-react yup
Om ons formulier werkend te krijgen, moeten we het ook in Gatsby en WordPress programmeren. Laten we beginnen bij het Gatsby-gedeelte.
Maak in de map root/src een nieuwe submap. Waarom noemen we het niet “mutaties”. Dan maken we een nieuw bestand aan. Om een logica in onze naamgevingsconventie te houden, noemen we het 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;
Nu kunnen we een contactformuliercomponent maken. Om een logica in een bestandsstructuur te houden, laten we een nieuwe map “ContactForm” maken in de map root/componenten. Vervolgens moeten we daar een nieuw bestand maken: ContactForm.js.
We zullen profiteren van de React-status, Yup-validatie en Formik-functionaliteit.
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;
Nu is onze contactformuliercomponent klaar en kunnen we deze importeren in de paginacomponent, voettekstcomponent of waar we maar willen.
Het is tijd om het WordPress-gedeelte aan te pakken.
In het bestand functions.php moeten we onze mutatie in het contactformulier registreren:
<?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' );
En dit is meer minder. Ons contactformulier is klaar.
Veel plezier met coderen!