Programming a custom WordPress Plugin for sending mails: Part 2

This post is the second part of the two part series of creating a custom WordPress plugin for sending emails. In the first part, we took care of the backend part by registering a new endpoint in the WordPress REST-API and took care that the email would be be sent from there.

In this second part, we are going to cover the frontend side of things. We are going to create a form and a javascript file that will send the data from the form to the API.

Prerequisites

In order for the code to work, you must have implemented the API endpoint that we created in part one of the series. You can find it here.

Creating the form

Our first task will be to create a HTML form-element that will collect the name, e-mail address and message from the user that we can then send to the API:

<section id="kontakt" class="contact">
        <div class="container">
            <form>
                <div class="row">
                    <div class="col-sm-12 col-lg-6">
                        <label for="name">Name</label>
                        <input type="text" name="name" placeholder="John Doe" value="">
                    </div>
                    <div class="col-sm-12 col-lg-6">
                        <label for="email">E-Mail</label>
                        <input type="text" name="email" placeholder="john.doe@email.com" value="">
                    </div>
                    <div class="col-12">
                        <label for="nachricht">Message</label>
                        <textarea value="" placeholder="Write something..." name="message" cols="30" rows="10"></textarea>
                    </div>
                    <div class="col-12">

                        <button type="submit" class="btn btn-primary"><i class="fas fa-paper-plane"></i> SENDEN</button>
                    </div>
                </div>
            </form>
        </div>
    </section>

 

As you can see here I am using the Bootstrap Grid and the Font Awesome icon library. You can of course do the same. But this series should not be about styling. The important part is the form element, the two input fields and the textarea. They are named „name“, „email“ and „message“ with initial values set to empty strings. These values will change whenever the user types something in these inputs.

Including axios

We are done with the HTML and can now focus on the Javascript side of things. First of all, we need to include a third-party package named axios in order to facilitate our HTTP-requests. It’s a lightweight Javascript library that wipes a bunch of pain points that these requests normally bring. You can find further documentation here.

In the functions.php file of your template, add:

<?php

function test_include_scripts(){
    wp_enqueue_script('axios', 'https://unpkg.com/axios/dist/axios.min.js');
};

add_action("wp_enqueue_scripts", "test_include_scripts");

The function „test_include_axios“ will load the axios script. It is good convention to put the name of your theme at the beginning of a function. We chose the name „test“ for our theme in the first part of the series. The „add_action“ function takes two arguments. The second one defines which function should be fired, the first argument defines when it should be fired. WordPress uses actions in so called „hooks“ that launch at execution or when a specific events occurs. In this example, the action is enqueuing the scripts. We as developers can take advantage of that and add additional actions to these hooks. By calling „add_action“ this is exactly what we are doing.

Creating the JS file

Next up we have to create and include a new Javascript file which will bring all the magic. I usually create a separate folder for my JS files, like so:

wp-content
   themes
       test
           ...other files
           js
             mail.js

As you can see, using all my creativity I came up with the name „mail.js“. You can of course call yours whatever you like.

We now also have to make sure that our file is included in our HTML files. Therefore, we will go back to our functions.php file and modify the function that we created earlier:

<?php

function test_include_scripts(){
    wp_enqueue_script('axios', 'https://unpkg.com/axios/dist/axios.min.js');

    //ADDED:
    wp_enqueue_script("mail_sender", get_template_directory_uri() . "/js/mail.js", array(), false, true);
};

add_action("wp_enqueue_scripts", "test_include_scripts");

The second callback in the „test_include_scripts“ function will load our mail.js file.

Kicking things of in mail.js

Everything is set up. We can now get our hands dirty in the mail.js file and actually send a request to the API.

To do that, we must first grab the submit button of the HTML file and store it in a variable:

const submitButton = document.querySelector(".contact button");

Creating the main function

Next, we want to collect the input data from the user when he or she clicks the submit button. We do this by adding an event listener to our submitButton:

submitButton.addEventListener("click", async e => {
    e.preventDefault();
})

As HTTP-requests are asynchronous actions, our function is marked as „async“. Also, we are passing the event object „e“ to the function. Whenever something happens in the DOM, an event object is created that can be accessed via Javascript. It incorporates a bunch of properties and methods that have many use cases. You can find a list of all the properties and methods here. As you can see we use the preventDefault() method. Normally, when submitting a form, the page would reload or redirect us, depending on what action we define in the HTML form-element. However, we don’t want this to happen. Thee preventDefault() method prevents us from that default action.

Grabbing the form inputs

The next task is to store the input fields of interest in variables:

submitButton.addEventListener("click", async e => {
  e.preventDefault();

  //ADDED:
  const name = document.querySelector("input[name='name']");
  const email = document.querySelector("input[name='email']");
  const msg = document.querySelector("textarea");
  const regEx = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/; // regEx for Email verification:
})

We grabbed the input fields using query selectors and stored them in variables. We also put a so called regular expression in a variable. I am not an expert on regExs myself, but this one will allow us to test if a string meets the criteria of a valid email address.

Validate input and send data to the API

The next part of the code is the largest one. However, it doesn’t really make sense to split it up into different parts, which is why I’ll paste the whole snippet and then explain it in detail below:

submitButton.addEventListener("click", async e => {
  e.preventDefault();

  const name = document.querySelector("input[name='name']");
  const email = document.querySelector("input[name='email']");
  const msg = document.querySelector("textarea");
  const regEx = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/; // regEx for Email verification:


  //ADDED:
  try {
    if (
      name.value !== "" &&
      msg.value !== "" &&
      regEx.test(email.value) //check if email address matches the regEx 
    ) {
      const res = await axios.post("/wp-json/mail/send", {
        name: name.value,
        email: email.value,
        msg: msg.value
      });
      if (res.status === 200) {
        // ----SHOW SUCCESS MESSAGE----
      } else {
        // ----SHOW ERROR MESSAGE----
      }
    } else {
        // ----TELL USER TO ENTER VALID VALUES----
    }
  } catch (e) {
    console.log("Something went wrong");
  }
})

The first thing to notice is that I added a try-catch block. So when something with the request goes wrong, the whole application won’t break and „Something went wrong“ will be logged to the console.

Validate inputs

In the try block, we first check the values of the input fields. You might remember that we did this already in part one of the series. It’s always good, however to do both client side and server side input validation. The values of name and email should not be empty. Plus, we test the email address against the regular expression that we defined above.

Send the request

Only if all inputs are valid, we will send a request to the API endpoint that we created in the first part of our series. We do this by using axios, which we already included at the top of this post. The axios object brings us a lot of methods, one of them being „post“. It defines that we are making a post request. The method takes two arguments. First, the route to the API endpoint. We defined it to be „/wp-json/mail/send“ in part one of the series. The second argument is the data we want to send. We want to send an object with name, email and message and axios will automatically convert it into json. As this is an asynchronous function we throw the „await“ keyword up front. Finally, we store the response of the API in the variable „res“.

Handle the response

If everything goes well, the response of our API endpoint will have a status code of 200. Only in that case, we want to display an error message. This is why I included the if(res.status===200) statement. I leave it up to you what you want to do in that case. You might want to create a modal or an alert message, for example. If the response status code is not 200, you should create some kind of error message, that I again leave up to you.

Conclusion

It was quite some work to get everything done. However, we now have a pretty cool custom WordPress plugin for sending emails. No other plugins needed, fully customizable. I hope you enjoyed it!