Bootstrap 4 Contact Form with Google reCaptcha

I’ve just started building a site using Bootstrap 4 which is different enough to Bootstrap 3 that I’m having to relearn a few things. One of those is form validation as previously I used bootstrap-validator though this doesn’t yet work with version 4. Version 4 does have it’s own inbuilt validation and although I haven’t yet created any custom validators for it, it’s not too tricky to get it working on a contact form which also uses Google Invisible reCaptcha which I’ve blogged about previously.

The below code is used for this contact page which uses the SendGrid API to send the message. Once the reCaptcha has validated that the sender is human it calls the “submitForm” function which validates the form using the Bootstrap validator and then posts the data to the relevant method in my controller which calls the API. The full code can be found here.


<div class="row">
    <div class="col-lg-12">
        <h2>@ViewData["Title"].</h2>
        @if (string.IsNullOrEmpty(contactMessage))
        {
        <form asp-controller="Home" asp-action="Contact" method="post" id="contact-form" role="form" class="needs-validation" novalidate>
                <div class="col-lg-6 col-md-8 col-sm-10">
                    <fieldset>
                        <div class="form-row">
                            <div class="col-md-6">
                                <label asp-for="FromEmail" class="control-label"></label>
                                <input asp-for="FromEmail" class="form-control" type="email" required />
                                <div class="invalid-feedback">
                                    A valid email address is required.
                                </div>
                            </div>
                            <div class="col-md-6">
                                <label asp-for="FromName" class="control-label"></label>
                                <input asp-for="FromName" class="form-control" required />
                                <div class="invalid-feedback">
                                    Name is required.
                                </div>
                            </div>
                        </div>
                        <div class="form-row">
                            <div class="col-md-12">
                                <label asp-for="Message" class="control-label"></label>
                                <textarea asp-for="Message" class="form-control" rows="5" required></textarea>
                                <div class="invalid-feedback">
                                    Message is required.
                                </div>
                            </div>
                        </div>
                        <div class="form-row mt-3">
                            <div class="col-md-12">
                                <button type="button" class="g-recaptcha btn btn-primary" id="submit" data-sitekey="6LeFHhkUAAAAAAByVoICH_Ff3sTUsVECHjomT4b7" data-callback="submitForm">Send</button>
                            </div>
                        </div>
                    </fieldset>
            </div>
        </form>
        }
        else
        {
            if (contactMessage == "Message sent :)")
            {
                <div class="alert alert-success" role="alert">Message sent :)</div>
            }
            else
            {
                <div class="alert alert-danger" role="alert">contactMessage</div>
            }
        }
    </div>
</div>

@section scripts {
    <script type="text/javascript">
        function submitForm() {
            var form = document.getElementById('contact-form');

            if (form.checkValidity() === false) {
                grecaptcha.reset();
            }
            else {
                var formdata = new FormData($('#contact-form').get(0));

                $.ajax({
                    url: '@Url.Action("Contact", "Home")',
                    type: 'POST',
                    data: formdata,
                    processData: false,
                    contentType: false,
                    success: function(data) {
                        $("body").html(data);
                        }
                });
            }

            form.classList.add('was-validated');
        }
    </script>
}

Leave a Reply

Your email address will not be published. Required fields are marked *