My Blog

Not a fan of writing but why not give it a try

Generalise reCaptcha Addition to Forms by Just Adding a Class

I this post we’ll add reCaptcha filed to each form by just adding a class. In addition in my example I wanted to retrieve my public key from a server to place in the script. Let’s begin by adding a form markup

1
2
3
4
5
6
7
8
9
<div class="form-group row">
    <div class="col-sm-12">
        <!-- id field does not matter as long as it is unique but assign an id -->
        <div id="g-recaptcha" class="g-recaptcha"></div>
    </div>
    <div class="col-sm-12 text-left">
        <a href="" class="captcha-reset">Reset captcha</a>
    </div>
</div>

Here is the precidure to add reCaptcha to all .g-recaptcha div tags

  • Add an onLoad function to Google’s reCaptcha api
  • Render a reCaptcha for every .g-recaptcha tag
  • Attach a listener to .captcha-reset to reset the captcha

Add onLoad function to Google’s reCaptcha api

First thing is to load the recaptcha api library from google with keywords async defer

1
<script src="https://www.google.com/recaptcha/api.js?onload=onCaptchaLoad&render=explicit" async defer></script>

Notice onload=onCaptchaLoad and render=explicit. These attributes pretty much stop recaptcha from rendering automatically. You can indeed render them with just html but in my case I would like to retrieve my public key from elsewhere after the page has loaded. So let’s implement the onload function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 /*******************************************************************************
 * Captcha rendered javascript, it will render a captcha for every
 * div with class name g-recaptch
 * Dependencies: jQuery, googleCaptchaApi
 *******************************************************************************/

 // Global variables
 var onCaptchaLoad;
 var resetCaptcha;

(function renderCaptchas(onCaptchaLoad, resetCaptcha, document) {
    onCaptchaLoad = function () {
        $.get('url/to/your/recaptcha/public/key/', function success(data) {
            $('.g-recaptcha').each(function addCaptcha() {
                var captcha = this;
                var id = grecaptcha.render($(captcha).attr('id'), {
                    'sitekey': data,
                });

                // Set the grecaptcha widget id in the form
                $(this).parents('form').data('grecaptcha', id);
            });
        });
    };

    resetCaptchaButton = function () {
        // Must be called with an item inside the form as context
        var form = $(this).parents('form');
        grecaptcha.reset(form.data('grecaptcha'));
    };

    $(document).on('ready', function onReady() {
        $('.captcha-reset').on('click', function resetCaptcha(e) {
            resetCaptchaButton.call(this);
            e.preventDefault();
        });
    });
})(window, document);

That single snippet pretty much achieves all three points required. Only note that the above script should be included before google’s script.