1

So I have a single page which has two language translations, one in Romanian and the other in English. The 2 translations are activated/served in the page using a jQuery button of adding an 'active' class to the translation's respective divs (without refreshing the page).

I am using jQuery Form Validation plugin to validate the forms. The form validation works perfectly fine on the Romanian translation (default view when a user lands on the page). The main problem is that when a user clicks on the translation button to activate the English version, then supplies the form, grecaptcha.getResponse() returns empty, causing my English form validation to not submit.

Below are my codes:

Romanian Form:

    <form action="forms/contact-form-handler.php" method="POST" UTF-8 id="ro-form">
      <div class="columns is-variable is-2 is-multiline">
        <div class="column is-half">
          <input class="input" type="text" name="name" placeholder="Nume si prenume" id="ro-name">
        </div>
        <div class="column is-half">
          <input class="input" type="email" name="email" placeholder="Email" id="ro-email">
        </div>
        <div class="column is-half">
          <input class="input" type="text" name="phone" placeholder="Telefon" id="ro-phone">
        </div>
        <div class="column is-half">
          <input class="input" type="text" name="budget" placeholder="Buget">
        </div>
        <div class="column is-full">
          <textarea class="textarea" name="message" placeholder="Message" id="ro-message"></textarea>
        </div>
        <div class="column is-half">
          <div class="g-recaptcha" data-sitekey="my_key_here"></div>
          <input type="hidden" class="hiddenRecaptcha required" name="hiddenRecaptcha" id="hiddenRecaptcha">
          <button type="submit" class="button is-warning"><span class="send-btn">Send message</span></button>
        </div>  
      </div>
    </form>

English Form:

    <form action="forms/contact-form-handler.php" method="POST" UTF-8 id="en-form">
      <div class="columns is-variable is-2 is-multiline">
        <div class="column is-half">
          <input class="input" type="text" name="name" placeholder="Name">
        </div>
        <div class="column is-half">
          <input class="input" type="email" name="email" placeholder="Email" id="en-email">
        </div>
        <div class="column is-half">
          <input class="input" type="text" name="phone" placeholder="Phone">
        </div>
        <div class="column is-half">
          <input class="input" type="text" name="budget" placeholder="Budget">
        </div>
        <div class="column is-full">
          <textarea class="textarea" name="message" placeholder="Message"></textarea>
        </div>
        <div class="column is-half">
          <div class="g-recaptcha" data-sitekey="my_key_here"></div>
          <input type="hidden" class="hiddenRecaptcha required" name="hiddenRecaptcha" id="hiddenRecaptcha">
          <button type="submit" class="button is-warning"><span class="send-btn">Send message</span></button>
        </div>  
      </div>
    </form>

jQuery Validation Instance:

$(function() {
  // Validate Romanian Form
  $("#ro-form").validate({
    ignore: ".ignore",
    rules: {
      name: "required",
      phone: "required",
      email: {
        required: true,
        email: true
      },hiddenRecaptcha: {
          required: function () {
              if (grecaptcha.getResponse() == '') {
                  return true;
              } else {
                  return false;
              }
          }
      }
    },
    messages: {
      name: "Please enter your name",
      phone: "Please enter your phone number",
      email: "Please enter a valid email address"
    },
    submitHandler: function(form) {
      form.submit();
    }
  });

  // Validate Romanian Form
  $("#en-form").validate({
    ignore: ".ignore",
    rules: {
      name: "required",
      phone: "required",
      email: {
        required: true,
        email: true
      },hiddenRecaptcha: {
          required: function () {
              if (grecaptcha.getResponse() == '') {
                  return true;
              } else {
                  return false;
              }
          }
      }
    },
    messages: {
      name: "Please enter your name",
      phone: "Please enter your phone number",
      email: "Please enter a valid email address"
    },

    submitHandler: function(form) {
      form.submit();
    }
  });
});

Thank you for the help.

algen
  • 11
  • 3
  • why you use two form?? you can do this with one – daryosh setorg Feb 29 '20 at 04:41
  • 1
    You using same id and name as 'hiddenRecaptcha' for both the forms. It should be unique. – Devang Feb 29 '20 at 04:41
  • @daryoshsetorg because of translation, I can do this with 1 form but that would require another logic when the page is translated. – algen Feb 29 '20 at 05:34
  • @Devang Hi, tried changing the id and name on the English form to be unique, I'm still getting an empty value of the grecaptcha.getResponse(). – algen Feb 29 '20 at 06:43

2 Answers2

0
<form action="forms/contact-form-handler.php" method="POST" UTF-8 id="form">
 <input type="text" class="hidden" id="language" value="1" />
  <div class="columns is-variable is-2 is-multiline">
    <div class="column is-half">
      <input class="input" type="text" name="name" placeholder="Name">
    </div>
    <div class="column is-half">
      <input class="input" type="email" name="email" placeholder="Email" >
    </div>
    <div class="column is-half">
      <input class="input" type="text" name="phone" placeholder="Phone">
    </div>
    <div class="column is-half">
      <input class="input" type="text" name="budget" placeholder="Budget">
    </div>
    <div class="column is-full">
      <textarea class="textarea" name="message" placeholder="Message"></textarea>
    </div>
    <div class="column is-half">
      <div class="g-recaptcha" data-sitekey="my_key_here"></div>
      <input type="hidden" class="hiddenRecaptcha required" name="hiddenRecaptcha" id="hiddenRecaptcha">
      <button type="submit" class="button is-warning"><span class="send-btn">Send message</span></button>
    </div>  
  </div>
</form>

then you can check the input that has id='language' if value=1 change place holder to English else if value =0 change placeholder to Romanian.

$(function() {
       $("your change button").onClick(()=>{
           $("#language").val('0') // or 1
            //write function to change all input to Romanian or English language
            //sample : $('#en-email').attr("placeholder", "Email"); 
         })
     });
daryosh setorg
  • 120
  • 1
  • 9
  • Thank you for giving an answer, but would this require me to separate the 2 translations on separate files right? The 2 translations are inside a single html file on separate Divs. The other div is hidden when one is active and vise-versa, so using 1 form would require me to separate them and then Include the Form? I just need to figure out why the grecaptcha.getResponse() is returning empty when the 2nd translation is active. Thank you. – algen Feb 29 '20 at 07:54
  • I think `grecaptcha.getResponse()` can just one time fire in your form did you test that fire several time? – daryosh setorg Feb 29 '20 at 08:51
  • Thank you for your last comment, it guided me to search on how I can get the value of the 2nd recaptcha instance. :) – algen Feb 29 '20 at 13:18
0

Ok, so here's what I did after getting the pieces of information together, I stumbled upon Gene Kelly discussing on how you can reference each recaptcha instance with grecaptcha.getResponse(0), grecaptcha.getResponse(2) and so on. So I searched on how I can create multiple instance and stumble upon turboLoop's answer, where you could create the recaptcha with explicit render.

So here's my new code structure:

My new recaptcha field on the 2 translation:

<div class="column is-half">
  <div class="g-recaptcha"></div>
  <input type="hidden" class="hiddenRecaptcha required" name="hiddenRecaptcha">
  <button type="submit" class="button is-warning"><span class="send-btn">Send message</span></button>
</div>

Script to create the renders from turboLoop's answer:

var CaptchaCallback = function() {
  var captchas = document.getElementsByClassName("g-recaptcha");
  for(var i = 0; i < captchas.length; i++) {
    grecaptcha.render(captchas[i], {'sitekey' : 'my_site_key'});
  }
};

Load Script with explicit render:

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

jQuery Form Validation plugin:

Romanian div:

...
},hiddenRecaptcha: {
    required: function () {
      if (grecaptcha.getResponse(0) == '') {
        return true;
      } else {
        return false;
      }
    }
}
...

English div:

...
},hiddenRecaptcha: {
    required: function () {
      if (grecaptcha.getResponse(1) == '') {
        return true;
      } else {
        return false;
      }
    }
}
...

So now when the 2nd translation is active, grecaptcha.getResponse() returns a value since it is referenced to the 2nd instance/render.

algen
  • 11
  • 3