Languages

Form validation before submit for recaptcha v3

12 points
Asked by:
ErikRobles
1180

I am trying to have form validation before recaptcha sends the form but it is allowing the form to be submitted empty or partially filled. It is ignoring my validation rules but I am not sure I am doing this right. Any help would be greatly appreciated. Thank you in advance.

Here is my code.

scripts - 

before closing head tag in index.html

<script src="https://www.google.com/recaptcha/api.js" async defer></script>

In my validation.js (which I am calling before the closing body tag in a script tag) - 

const clientName = document.getElementById('name');
const subject = document.getElementById('subject');
const email = document.getElementById('email');
const clientMessage = document.getElementById('message');
const form = document.getElementById('zitalk-contact');
const errorElement = document.getElementById('error');

function onSubmit(token) {
  // alert('Thanks ' + document.getElementById('name').value);
  document.getElementById('zitalk-contact').submit();
}

function validate(event) {
  event.preventDefault();
  if (clientName.value === '' || clientName.value === null) {
    alert('Name field cannot be blank');
  }
  if (email.value === '' || email.value === null) {
    alert('Email field cannot be blank');
  }
  if (subject.value === '' || subject.value === null) {
    alert('Subject field cannot be blank');
  }
  if (clientMessage.value === '' || clientMessage.value === null) {
    alert('Message field cannot be blank');
  }
  grecaptcha.execute();
}

function onload() {
  var element = document.getElementById('send');
  element.onclick = validate;
}

And finally my form code - 

Edit: showing entire form

 <form action="contact.php" id="zitalk-contact" method="post" class="wpcf7-form" novalidate="novalidate">
              <div class="form-group">
                <span class="wpcf7-form-control-wrap your-name">
                  <div class="input-wrapper">
                  <input type="text" id="name" name="your-name" value="" size="40"
                    class="wpcf7-form-control wpcf7-text wpcf7-validates-as-required" aria-required="true"
                    aria-invalid="false" placeholder="Your Name"></span>
                    <i class="fa fa-exclamation-circle"></i>
                    <i class="fa fa-check-circle"></i>
                    <small></small>
                  </div>
              </div>
              <div class="form-group">
                <span class="wpcf7-form-control-wrap your-e-mail">
                  <div class="input-wrapper">
                  <input type="email" name="your-e-mail" value="" id="email"
                    size="40"
                    class="wpcf7-form-control wpcf7-text wpcf7-email wpcf7-validates-as-required wpcf7-validates-as-email"
                    aria-required="true" aria-invalid="false" placeholder="Your E-mail"></span>
                    <i class="fa fa-check-circle"></i>
                    <i class="fa fa-exclamation-circle"></i>
                    <small></small>
                  </div>
              </div>
              <div class="form-group">
                <span class="wpcf7-form-control-wrap subject">
                  <div class="input-wrapper">
                    <div class="input-wrapper">
                    <input id="subject" type="text" name="subject" value="" size="40"
                    class="wpcf7-form-control wpcf7-text wpcf7-validates-as-required" aria-required="true"
                    aria-invalid="false" placeholder="Subject"></span>
                    <i class="fa fa-check-circle"></i>
                    <i class="fa fa-exclamation-circle"></i>
                    <small></small>
                    </div>
                  </div>
              </div>
              <div class="form-group">
                <span class="wpcf7-form-control-wrap your-message">
                  <textarea id="message" name="your-message" cols="40" rows="10"
                    class="wpcf7-form-control wpcf7-textarea wpcf7-validates-as-required" aria-required="true"
                    aria-invalid="false" placeholder="Message"></textarea></span>
              </div>
              <!-- <div class="form-group">
                <input type="submit" value="SEND NOW" class="wpcf7-form-control wpcf7-submit"><span
                  class="ajax-loader"></span>
              </div> -->
              <div class="form-group recaptcha-disclaimer text-center">
                This site is protected by reCAPTCHA and the Google
    <a href="https://policies.google.com/privacy">Privacy Policy</a> and
    <a href="https://policies.google.com/terms">Terms of Service</a> apply.
              </div>
              <div class="form-group">
              <div class="form-group">
  <button class="g-recaptcha"
    id="send" 
    type="submit"
    class="wpcf7-form-control wpcf7-submit"
    data-sitekey="My Site Key Bla Bla Bla" 
    data-callback='onSubmit' 
    data-action='submit'
  >
    SEND NOW
  </button>
  <span class="ajax-loader"></span>
</div><span
              class="ajax-loader"></span>
            </div>
            </form>
<div class="form-group">
  <button class="g-recaptcha"
    id="send" 
    type="submit"
    class="wpcf7-form-control wpcf7-submit"
    data-sitekey="My Site Key Bla Bla Bla" 
    data-callback='onSubmit' 
    data-action='submit'
  >
    SEND NOW
  </button>
  <span class="ajax-loader"></span>
</div>

I have a feeling I am missing something. If you spot anything, please let me know and I will be happy to edit my quesiton. Thanks again in advance for your help on this.

Moderator: I allowed myself to edit the source code part to make post more readable.

 

2 answers
8 points
Answered by:
ErikRobles
1180

At first be sure that you have proper keys:

to get reCAPTCHA_site_key go to:
    https://www.google.com/recaptcha/admin#list

click + button to add domain:
    use `localhost` for development

Example keys:

 

Be sure that you run your code on some domain or on localhost. 

Note: read this article to see full example with spring boot.

Screenshot:

Example solution:

// ONLINE-RUNNER:browser;

<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <!-- 
     	to get reCAPTCHA_site_key go to:
        	https://www.google.com/recaptcha/admin#list

        click + button to add domain:
 			use `localhost` for development
  	-->
    <!--
  	<script src="https://www.google.com/recaptcha/api.js?render=My%20Site%20Key%20Bla%20Bla%20Bla" async defer></script>
  	-->
  	<script src="https://www.google.com/recaptcha/api.js?render=reCAPTCHA_site_key" async defer></script>
  </head>
  <body>
    <form id="contact-form" method="POST" onsubmit="onSubmit(event)">
      <div class="form-group">
        <input name="name" type="text" placeholder="Your name" /><br />
        <input name="email" type="text" placeholder="Contact e-mail" /><br />
        <input name="subject" type="text" placeholder="Request subject" /><br />
        <input name="message" type="text" placeholder="Request message" /><br />
        <!-- add more fields here ... -->
        <button type="submit" class="wpcf7-form-control wpcf7-submit">
          SEND NOW
        </button>
        <span class="ajax-loader"></span>
      </div>
    </form>
    <script>

      const clientNameElement = document.querySelector('input[name="name"]');
      const clientEmailElement = document.querySelector('input[name="email"]');
      const requestSubjectElement = document.querySelector('input[name="subject"]');
      const requestMessageElement = document.querySelector('input[name="message"]');
      //const errorElement = document.getElementById('error');

      function validate() {
          // `.value` will be never null so `=== ''` is enought
          if (clientNameElement.value === '') {
              alert('Name field cannot be blank');
              return false; // if there is some error
          }
          if (clientEmailElement.value === '') {
              alert('Email field cannot be blank');
              return false; // if there is some error
          }
          if (requestSubjectElement.value === '') {
              alert('Subject field cannot be blank');
              return false; // if there is some error
          }
          if (requestMessageElement.value === '') {
              alert('Message field cannot be blank');
              return false; // if there is some error
          }
          return true;  // if everythink is valid
      }

      // Read the section to know how to use with JavaScript:
      //   Programmatically invoke the challenge
      //   https://developers.google.com/recaptcha/docs/v3#programmatically_invoke_the_challenge

      function sendData(token){
          console.log('token=' + token);
          const requestData = {
              token: token,
              clientName: clientNameElement.value,
              clientEmail: clientEmailElement.value,
              requestSubject: requestSubjectElement.value,
              requestMessage: requestMessageElement.value,
              // add here more fields here ...
          };
          const requestJson = JSON.stringify(requestData);
//        fetch('contact.php', {
          fetch('/path/to/endpoint', {
              method: 'POST',
              body: requestJson,
          })
              .then(function(response) {
                  return response.text();
              })
              .then(function(responseText) {
                  console.log('response: ' + responseText);
          	  })
              // or:
              //.then(function(response) {
              //	return response.json();
              //})
              //.then(function(responseData) {
              //	console.log('response: ' + responseData); // responseData is object
              //})
              .catch(function(error) {
                  console.error("POST error!");
                  //errorElement.innerText = 'Submit error!';
              });
      }

      function onSubmit(e) {
          e.preventDefault();
          if (validate()) {
              grecaptcha.ready(function() {
                  var config = { action: 'submit' }; // change submit to something other if you want
//                grecaptcha.execute('My Site Key Bla Bla Bla', config)
                  grecaptcha.execute('reCAPTCHA_site_key', config)
                      .then(function(token) {
                          sendData(token);
                  	  });
              });
          }
      }

    </script>
  </body>
</html>

 

1 comments
ErikRobles
Thank you &#64;Root-ssh. That was very helpfull. Additionally, I had a no validate rule that I had forgotten about in the html which was preventing some validation.
Add comment
6 points
Answered by:
ErikRobles
1180

One thing the Recaptcha documentation fails to tell you is that if you attach the recaptcha to the submit button, it will ignore all html5 validation. Therefore, the following code worked well:

script before closing head tag - 

<script src="https://www.google.com/recaptcha/api.js" async defer></script>

 Form including recaptcha -

<form action="contact.php" id="zitalk-contact" method="post" class="wpcf7-form">
              <div class="form-group">
                <span class="wpcf7-form-control-wrap your-name">
                  <div class="input-wrapper">
                  <input type="text" id="name" name="your-name" value="" size="40"
                    class="wpcf7-form-control wpcf7-text wpcf7-validates-as-required" aria-required="true"
                    aria-invalid="false" placeholder="Your Name" required></span>
                    <i class="fa fa-exclamation-circle"></i>
                    <i class="fa fa-check-circle"></i>
                    <small></small>
                  </div>
              </div>
              <div class="form-group">
                <span class="wpcf7-form-control-wrap your-e-mail">
                  <div class="input-wrapper">
                  <input type="email" name="your-e-mail" value="" id="email"
                    size="40"
                    class="wpcf7-form-control wpcf7-text wpcf7-email wpcf7-validates-as-required wpcf7-validates-as-email"
                    aria-required="true" aria-invalid="false" placeholder="Your E-mail" required></span>
                    <i class="fa fa-check-circle"></i>
                    <i class="fa fa-exclamation-circle"></i>
                    <small></small>
                  </div>
              </div>
              <div class="form-group">
                <span class="wpcf7-form-control-wrap subject">
                  <div class="input-wrapper">
                    <div class="input-wrapper">
                    <input id="subject" type="text" name="subject" value="" size="40"
                    class="wpcf7-form-control wpcf7-text wpcf7-validates-as-required" aria-required="true"
                    aria-invalid="false" placeholder="Subject" required></span>
                    <i class="fa fa-check-circle"></i>
                    <i class="fa fa-exclamation-circle"></i>
                    <small></small>
                    </div>
                  </div>
              </div>
              <div class="form-group">
                <span class="wpcf7-form-control-wrap your-message">
                  <textarea id="message" name="your-message" cols="40" rows="10"
                    class="wpcf7-form-control wpcf7-textarea wpcf7-validates-as-required" aria-required="true"
                    aria-invalid="false" placeholder="Message" required></textarea></span>
              </div>
              <!-- <div class="form-group">
                <input type="submit" value="SEND NOW" class="wpcf7-form-control wpcf7-submit"><span
                  class="ajax-loader"></span>
              </div> -->
              <div class="form-group recaptcha-disclaimer text-center">
                This site is protected by reCAPTCHA and the Google
    <a href="https://policies.google.com/privacy">Privacy Policy</a> and
    <a href="https://policies.google.com/terms">Terms of Service</a> apply.
              </div>
              <div class="form-group">
                <div class="g-recaptcha"
                   id="recaptcha" 
                   data-sitekey="My_Site_key" 
                   data-callback='onCompleted'
                   data-size='invisible'></div>
                   <button  type="submit" id="send" class="wpcf7-form-control wpcf7-submit">SEND NOW</button><span
                   class="ajax-loader"></span>
                 </div>
            </form>

And finally, my script before the closing body tag - 

<script>
  $('#zitalk-contact').submit(function(event) {
    console.log('Validation Completed');
    if(!grecaptcha.getResponse()) {
      console.log('Captcha Not Yet Complete.');
      event.preventDefault();
      grecaptcha.execute();
    } else {
      console.log('form Really submitted.');
    }
  });
  onCompleted = function() {
    console.log('Captcha Completed');
    $('#zitalk-contact').submit();
  }
</script>

I hope this helps anyone struggling with this who wants to have html5 validation before the form is verified by recaptcha v3

Source of solution.

0 comments Add comment
Native Advertising
ūüöÄ
Get your tech brand or product in front of software developers.
For more information Contact us
Dirask - we help you to
solve coding problems.
Ask question.

‚̧ԳŹūüíĽ ūüôā

Join