jQuery remote ajax email validation failed

How to configure client side Email form only allow business email address in Laravel using JQuery validation

Nowadays we can see most of the websites only allowed to register on this site I am using a corporate business email address when we try to Register with any free domain email id example gmail.com, outlook.com or yahoo.com Service registration will restrict First to proceed for registration or a service.

When we see over the internet there are 1000’s of the website which provides the services API calls to validate the form input deny free domain registration. But the charges are based on per API call and we need to buy in bulk which costs around $10 up to $200.

So, I thought to create this post show you how we can easily integrate free email address validation to our project.

Workspace requirements

I am using,

jQuery Validation CDN (Client-Side validation method)

Laravel (Basically PHP backend server-side validation)

Free domain list (Available on GitHub gist created by T. Brian Jones) URL: https://gist.github.com/tbrianjones/5992856

We use raw version https://gist.githubusercontent.com/tbrianjones/5992856/raw/93213efb652749e226e69884d6c048e595c1280a/free_email_provider_domains.txt

But we can use the same in other backend or vanilla JavaScript-based libraries also example (DJANGO, REACT – NODE, etc) but in jQuery validation, we don’t need to reinvent the wheel from error handling in DOM. and Laravel is because of the same code I will use my currently undergoing projects.

Setting Laravel Environment

Same old command on my working system

Laravel new nonfreeemail
Setting up Laravel new command.png

Run command verify the application is working by cd into the directory and run serve command

php artisan serve

To add a basic setting just adding bootstrap boilerplate and one form input file, Just create one controller name FormController and add basic bootstrap boilerplate on the form view. From the get bootstrap website starter template with email form with the submit button.

laravel with bootstap boilerplate
php artisan make:controller FormController

Setting jQuery Validation via CDN

Just searching “JQUERY VALIDATION CDN” we will get a link that needs to include in our bootstrap template after the last script tag in the bottom.

Run the server in browser 

Boorstratp stater template running laravel jquery validation

As this is just a single page template, I will add Script page but for more complex apps better to create separate js file and link after jQuery Validation Script.

The Script will Validate form and then enable the submit button if Validation is a pass.

Client-Side implementation

Basic in Script

This script is very basic on the client-side if we want to restrict 2 or 3 basic domains in the following example try to restrict gmail.com, outlook.com, and yahoo.com

<script>
    $(document).ready(function() {
        $("#submit").prop("disabled", "disabled");
        var $contactform = $("#contactform");

        $("input").on("blur keyup", function() {
            if ($contactform.valid()) {
                $("#submit").prop("disabled", false);
            } else {
                $("#submit").prop("disabled", "disabled");
            }
        });

        // Non free validation
        $.validator.addMethod(
            "nonfreeemail",
            function(value) {
                return /^([\w-.]+@(?!gmail\.com)(?!yahoo\.com)(?!outlook\.com)([\w-]+.)+[\w-]{2,4})?$/.test(
                    value
                );
            },
            "Please use your non-free email."
        );

        // Actual form
        $contactform.validate({
            errorElement: "div",
            rules: {
                email: {
                    required: true,
                    email: true,
                    nonfreeemail: true
                },
            },
            messages: {
                email: {
                    required: "Email is Mandatory",
                    email: "Enter Valid Email",
                    nonfreeemail: "Please use your Business email"
                },
            }
        });
    });
</script>

Note: Form tag has id=’contactform’ for jQuery validation and submit button has id=’submit’ for disable button

Now when using any of the above domain it will show an error.

JQuery Validation fail for gmail

Ajax script validation

We can use https://jqueryvalidation.org/remote-method/ Remote method to fetch data for validation same whey Gmail or outlook verify our email from there database. But the twist will be we will just verify domain name from the gist URL

https://gist.githubusercontent.com/tbrianjones/5992856/raw/93213efb652749e226e69884d6c048e595c1280a/free_email_provider_domains.txt

Used raw URL and yes, it is possible to copy the file but if we go to the gist page of T. Brian Jones and while writing this post the last changes are done 2 days ago so in future if any new domain is added in the list the current request will fetch.

For simplicity, I am using GET a request to show process but real-life example better to use post request more info can be found on the jQuery validation website.

Creating a Laravel web route and controller function.

In web.php added get as following.

Route::get('email/verify', 'FormController@emailverify')->name('email.verify');

In FormController added a public function

public function emailverify(Request $request)
    {
        $emailrequest = $request->get('email');
        $parts = explode('@', $emailrequest);
        $email = $parts[1];
        $url = "https://gist.githubusercontent.com/tbrianjones/5992856/raw/93213efb652749e226e69884d6c048e595c1280a/free_email_provider_domains.txt";
        $json = file_get_contents($url);

        if (preg_match("/{$email}/i", $json)) {
            return response()->json(false);
        } else {
            return response()->json(True);
        }
    }

Explode command to split data from @ into two arrays

$part[1] is to use second array data

file_get_contents command to fetch content from URL.

Response in JSON for jQuery validation true or false in the condition if preg_match found the domain it will execute false and form validation fails.

Now in my script removed “nonfreeemail” method and change the function to “remote” 

Note: replace jQuery slim package from starter template to minified version as ajax is not available in slim.

    <script>
        $(document).ready(function() {
            $("#submit").prop("disabled", "disabled");
            var $contactform = $("#contactform");

            $("input").on("blur keyup", function() {
                if ($contactform.valid()) {
                    $("#submit").prop("disabled", false);
                } else {
                    $("#submit").prop("disabled", "disabled");
                }
            });

            // Actual form
            $contactform.validate({
                errorElement: "div",
                rules: {
                    email: {
                        required: true,
                        email: true,
                        remote: "email/verify"
                    },
                },
                messages: {
                    email: {
                        required: "Email is Mandatory",
                        email: "Enter Valid Email",
                        remote: "Please use your Business email"
                    },
                }
            });
        });
    </script>

Now when we proceed with any free domain the error will show and the submit button will not be highlighted.

jQuery remote ajax email validation failed

And any email domain which is not in a list can enable a button to submit the form.

jQuery remote ajax email validation pass

Source code of Template

FormController code.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class FormController extends Controller
{
    public function index()
    {
        return view('form.index');
    }

    public function emailverify(Request $request)
    {
        $emailrequest = $request->get('email');
        $parts = explode('@', $emailrequest);
        $email = $parts[1];
        $url = "https://gist.githubusercontent.com/tbrianjones/5992856/raw/93213efb652749e226e69884d6c048e595c1280a/free_email_provider_domains.txt";
        $json = file_get_contents($url);

        if (preg_match("/{$email}/i", $json)) {
            return response()->json(false);
        } else {
            return response()->json(True);
        }
    }
}

index.blade.php file

<!doctype html>
<html lang="en">

<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

    <style>
        .error {
            color: red;
        }
    </style>
    <title>Anish Mandal</title>
</head>

<body>
    <div class="container">
        <div class="row">
            <div class="col-md-6 offset-md-3 pt-5">
                <h2>Non Free Email Form Validation</h2>
                <form id='contactform' method="get">
                    @csrf-token
                    <div class="form-group">
                        <label for="exampleInputEmail1">Non Free Email address or Work/School Email</label>
                        <input type="email" class="form-control" name="email" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Enter email">
                        <small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small>
                    </div>
                    <div class="form-group form-check">
                        <input type="checkbox" class="form-check-input" id="exampleCheck1">
                        <label class="form-check-label" for="exampleCheck1">Agree T & C</label>
                    </div>
                    <button type="submit" id="submit" class="btn btn-primary">Submit</button>
                </form>
            </div>
        </div>
    </div>

    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
    <!-- jQuery Validation -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.1/jquery.validate.min.js" integrity="sha256-sPB0F50YUDK0otDnsfNHawYmA5M0pjjUf4TvRJkGFrI=" crossorigin="anonymous"></script>


    <!-- Optional JavaScript -->
    <script>
        $(document).ready(function() {
            $("#submit").prop("disabled", "disabled");
            var $contactform = $("#contactform");

            $("input").on("blur keyup", function() {
                if ($contactform.valid()) {
                    $("#submit").prop("disabled", false);
                } else {
                    $("#submit").prop("disabled", "disabled");
                }
            });

            // Actual form
            $contactform.validate({
                errorElement: "div",
                rules: {
                    email: {
                        required: true,
                        email: true,
                        remote: "email/verify"
                    },
                },
                messages: {
                    email: {
                        required: "Email is Mandatory",
                        email: "Enter Valid Email",
                        remote: "Please use your Business email"
                    },
                }
            });
        });
    </script>

</body>

</html>

Route file web.php

<?php
Route::get('/', 'FormController@index')->name('home');
Route::get('email/verify', 'FormController@emailverify')->name('email.verify');