Google reCaptcha reset doesn't work - javascript

I want to reset Google reCaptcha widget when I submit my form via AJAX and have some input errors or form is sent. I'm using multiple widgets on the same page so I render these widgets explicitly.
My HTML code:
<div class="g-recaptcha" id="recaptcha-1"></div>
<div class="g-recaptcha" id="recaptcha-2"></div>
...
<div class="g-recaptcha" id="recaptcha-20"></div>
Loading widget
<script src="https://www.google.com/recaptcha/api.js?onload=reCaptchaCallback&render=explicit&hl=en" async defer></script>
<script>
var reCaptchaCallback = function() {
var elements = document.getElementsByClassName('g-recaptcha');
for (var i = 0; i < elements.length; i++) {
var id = elements[i].getAttribute('id');
grecaptcha.render(id, {
'sitekey' : 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
});
}
};
</script>
After submit form:
var id = $('.g-recaptcha', form).attr('id');
grecaptcha.reset(id);
Form is the instance of the submitted form.
Everything works fine when form is fill correctly. But reCaptcha doesn't reset or reload.
It try this grecaptcha.reset() but no results.
Any idea?

The grecaptcha.reset() method accepts an optional widget_id parameter, and defaults to the first widget created if unspecified. A widget_id is returned from the grecaptcha.render() method for each widget created. So you need to store this id, and use it to reset that specific widget:
var widgetId = grecaptcha.render(container);
grecaptcha.reset(widgetId);
See here.

You are passing the wrong id.
$('.g-recaptcha', form).attr('id');
Your selector will capture all 20 reCaptcha widget, but only return a single DOM id (the first reCaptcha). So your code is actually resetting the first recaptcha.

Just edited your code to create a dynamic widget.
<script>
var reCaptchaCallback = function() {
var elements = document.getElementsByClassName('g-recaptcha');
for (var i = 0; i < elements.length; i++) {
widgetId+i = grecaptcha.render('recaptcha-'+i, {
'sitekey' : 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
});
}
};
</script>
And after you have successfully completed the above task, change in the AJAX success: response
grecaptcha.reset(widgetId+id);
Here the id would be the same that is generated from the below for Loop.

I have two google captcha in same page, two different form
<form id="form1">
<input type="text" name="form1-input">
<div class="g-recaptcha" data-sitekey="XXXXXXXXXXXXXXXXX"></div>
</form>
and
<form id="form2">
<input type="text" name="form2-input">
<div class="g-recaptcha" data-sitekey="XXXXXXXXXXXXXXXXX"></div>
</form>
You can reset first captcha by
grecaptcha.reset(); or grecaptcha.reset(0);
And Second Captcha by index (1)
grecaptcha.reset(1);

I had an issue where there were multiple recaptchas on the page, some were hidden. In this case I had to loop through all of them and reset them like this:
var count = 0;
$(".g-recaptcha").each(function () {
grecaptcha.reset(count);
count++;
});

Related

How to remember form data that has not been submitted?

How can you make the browser remember what the user typed in the form, which has not yet been submitted and make the page refreshing not affect the data entered?
I have a form in which the user enters a number. Initially the form has 0 by default. I am storing the data in localStorage, so the browser can remember the data. However, when the page is refreshed, the user-entered data disappears and 0 is displayed by default. (still the localStorage data exists for it)
I tried to use jQuery's
$(".formClassName").val(localStorage.getItem(key));
but it does not work. Can anyone give me a piece of advice on this?Thank you in advance.
Edited: My form looks like this:
<form>
<!--There are multiple forms, and the only difference among them is the "name" attribute -->
Enter a number <input type="text" value="0" class"dataEntered" name="****">
<!--The button below saves the data entered in the above form -->
<input type="button" class="savedata" value="Save Value" name="****">
</form>
And I am adding the data to localStorage like below:
//JavaScript
<script>
//Using on because the website retrieves the above form dynamically
$(document).on("click", ".saveData", function(e){
//retrieve the number entered in the form
var userNum = $(this).siblings(".dataEntered").val();
//retrieve the value in name attribute
var thisFormName = $(this).attr("name");
//store the data
localStorage.setItem(thisFormName, userNum);
//Now that the save button has been pressed (not submitted to the
//server yet), and the data is stored in localStorage, I want to
//the page to show the number in userNum even after you refresh the page
//but this does not work.
$(".dataEntered").val(localStorage.setItem(thisFormName));
});
</script>
use cookie:
function addCookie(sName,sValue,day) {
var expireDate = new Date();
expireDate.setDate(expireDate.getDate()+day);
document.cookie = escape(sName) + '=' + escape(sValue) +';expires=' + expireDate.toGMTString();
}
function getCookies() {
var showAllCookie = '';
if(!document.cookie == ''){
var arrCookie = document.cookie.split('; ');
var arrLength = arrCookie.length;
var targetcookie ={};
for(var i=0; i<arrLength; i++) {
targetcookie[unescape(arrCookie[i].split('=')[0])]= unescape(arrCookie[i].split('=')[1]);
}
return targetcookie;
}
addCookie('type','1',1024);
var cookiesample = getCookies();
$(".formClassName").val(cookiesample.type);
cookiesample.type could be remembered unless the cookie is deleted.
Checkout this codepen I have it shows a functional solution to the problem. Also you need to make sure jQuery script checks if the DOM is ready, you can do that by using $(function() { }) a short hand for .ready().
$(function() {
var input = $("[type=text]");
var thisFormName = input.attr("name");
if (localStorage.getItem(thisFormName)) {
var value = parseInt(localStorage.getItem(thisFormName));
input.val(value);
}
$(document).on("click", ".savedata", function(e) {
var userNum = input.val();
localStorage.setItem(thisFormName, userNum);
input.val(localStorage.getItem(thisFormName));
});
});

Stop all form submit in my page

My need is to interrupt all form submit of my webpage and need to add a extra input field to it. I need to do it with js/Jquery.
I can do this for single form (using name/ID). But I need to do it for all 100s of form submit in my website. (In my case all forms are submitted using the form element's submit() method [not jQuery's submit()].)
Is there any way I can do it? Like overriding actual form.submit() method?
In my case all forms are submitted using javascript submit() method
In that case, you can wrap that method. Which is important, because when you call the DOM's HTMLFormElement#submit method, submit event handlers are not triggered. (If you use jQuery's submit method instead, it does trigger handlers before submitting the form.)
Here's how you wrap that function without using any libraries:
Array.prototype.forEach.call(document.querySelectorAll("form"), function(form) {
var realSubmit = form.submit;
form.submit = function() {
// Do your stuff
// ...
// Submit the form
realSubmit.call(form);
};
});
...or as you've tagged your question jquery, with jQuery:
$("form").each(function() {
var form = this;
var realSubmit = form.submit;
form.submit = function() {
// Do your stuff
// ...
// Submit the form
realSubmit.call(form);
};
});
You'll need to check that your target browsers allow it. Modern ones do.
Here's a complete example: Live Copy
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
<meta charset="utf-8">
<title>Example</title>
</head>
<body>
<p>This page adds the q field to a form it submits to Google</p>
<form method="GET" action="http://google.com/search" target="_blank">
<input id="sendDOM" type="button" value="Send with DOM's submit">
<input id="sendjQuery" type="button" value="Send with jQuery's submit">
</form>
<script>
$("#sendDOM").click(function() {
$("form")[0].submit();
});
$("#sendjQuery").click(function() {
$("form").submit();
});
// Wrap submit on the forms
$("form").each(function() {
var form = this;
var realSubmit = form.submit;
form.submit = function() {
// Do your stuff
var el = document.createElement("input");
el.type = "hidden";
el.name = "q";
el.value = "kittens";
form.appendChild(el);
// Submit the form
realSubmit.call(form);
};
});
</script>
</body>
</html>
You select and find the form in your page using $('form') selector.
it returns all the forms inside your page.
then bind the submit event.
var ajaxFormSubmit = function(){
//write what you need to do
return false;
};
$('form').submit(ajaxFormSubmit);

Javascript: display an alert when a form is checked?

I have created a simple web app that has 2 form selections, when the user makes their selection from each I want an alert to display showing them the choices they made.
I have attempted this below but when both forms are checked the alert is not displayed. What am I missing? Note see the comment:
//BELOW IS NOT BEING DISPLAYED BUT SHOULD BE
Current code:
<!DOCTYPE html>
<html>
<body>
<h1>Calculator</h1>
<p>Select the importance of this:</p>
<form method="get">
<input type="checkbox" name="Severity" value="negligible"> Negligible<br>
<input type="checkbox" name="Severity" value="minor"> Minor<br>
</form>
<p>Select the Probability of this:</p>
<form method="get">
<input type="checkbox" name="Probability" value="improbable"> Improbable<br>
<input type="checkbox" name="Probability" value="remote"> Remote<br>
<input type="checkbox" name="Probability" value="occasional"> Occasional<br>
<button onclick= "analyseThis()"> Analyse this </button> <br>
<script>
function analyseThis(){
var severities = document.getElementsByName('Severity');
var probs = document.getElementsByName('Probability');
var severity = undefined;
for(var i = 0; i < ages.length; i++)
{
if(severities[i].checked)
{
age = severities[i].value;
}
}
var probability = undefined;
for(var i = 0; i < probs.length; i++)
{
if(probs[i].checked)
{
probability = probs[i].value;
}
}
//BELOW IS NOT BEING DISPLAYED BUT SHOULD BE
alert("Severity is: " + age + "Probability is: " + probability);
}
</script>
</body>
</html>
I would use JQuery and use the click function of the button to submit.
Here is an example:
$(document).ready(function () {
$("{form id/class button id/class OR button id/class}").click(function(e) {
e.preventDefault();
//perform validation
//if everything is good...
$("{form id/class}").submit();
});
});
Something funny is happening:
Your function analyseThis() does get called, but there is an
error when it is being evaluated.
The form on the page is being "submitted", so the page reloads
and you never see the error.
To prevent the page from reloading (so you can see your error) do this:
Pass in the event object to your analyseThis() function from the onclick hander:
<button onclick= "analyseThis(event)"> Analyse this </button>
Make your analyseThis() accept the event object, and call .preventDefault() on it so that the page doesn't reload:
function analyseThis(e){
e.preventDefault()
// the rest of your function body here....
}
After you do that, you will see the underlying error output in the console:
ReferenceError: ages is not defined (line 33, col 17)
for(var i = 0; i < ages.length; i++)
If you do want the form to be submitted, just remember to remove the e.preventDefault() call after debugging the code.
You have an error in your code - you are checking ages.length in your loop which is probably undefined (no ages variable in your code) in the first loop and your code execution should stop there.
Working JSBin code here:
http://jsbin.com/yelihugune/1/
You have a bug in your code.
for(var i = 0; i < ages.length; i++)
{
if(severities[i].checked)
{
age = severities[i].value;
}
}
'ages' is not yet defined in your code, nor is 'age'. This will be throwing an error, stopping your code from running. This is why the alert is not going.
Declare the ages array.

Response from AJAX request is only displayed once

I've got some code that sends an ajax request when a form is being submitted. This works the first time the form is submitted (it's a search module), but only once. I've added an effect to highlight the table when data is returned, and you can only see it once (the data changes only once as well).
When I look at the response in the chrome dev tools, I can see it contains the data of the new search query but this isn't shown. Why can I only display results once?
JS:
$(function () {
// Creates an ajax request upon search form submit
var ajaxFormSubmit = function () {
var $form = $(this);
var options = {
url: $form.attr("action"),
type: $form.attr("method"),
data: $form.serialize()
};
$.ajax(options).done(function (data) {
var $target = $($form.attr("data-nn-target"));
var $newHtml = $(data);
$target.replaceWith($newHtml);
$newHtml.effect("highlight");
});
// Prevent default action
return false;
};
$("form[data-nn-ajax='true']").submit(ajaxFormSubmit);
});
HTML:
<form method="GET" action="#Url.Action("Index", "Show")" data-nn-ajax="true" data-nn-target="#contentlist" class="form-search">
<div class="input-append mysearch">
<input type="search" class="span5 search-query" name="query" data-nn-autocomplete="#Url.Action("AutoComplete")" />
<input type="submit" class="btn" value="Search" />
</div>
</form>
<div id="contentlist">
#Html.Partial("_Shows", Model)
</div>
I think you should use html() instead of replaceWith() method:
$target.html($newHtml);
just an idea... try
$target.html(data);
instead of
$target.replaceWith($newHtml);
By replaceWith, you might actually remove the div that you want to fill your content in. Then, the second time, it doesnt find the div to insert the content into.

Emptying A Select Form Element With JavaScript

I am creating a small app and on one part of the app, i am creating a drop down select menu, that is populated with values from an array.
The problem i have is that when the form is loaded, it successfully loads and populates the select options with array values, but the problem is that when i add another element to an array and call the form again, it will still only load the values from when the form was first called.
How would i have the select option clear its values when i press the submit button. Here is the code the is called:
<div class="popupForm" id="newRelate_Form" style="display:none">
<form name="relationFormOne">
<script type="text/javascript" language="javascript">
var $selectFrom = $('<select id="mySelect">');
$($selectFrom).attr('id', 'objFrom');
for (var i = 0; i < objectArray.length; i++)
{
var value = objectArray[i].Name;
$('<option>').val(value).text(value).appendTo($selectFrom);
}
$selectFrom.appendTo($("#from_Object"));
var fromVal = document.getElementById("objFrom");
</script>
<button class="closeDOMWindow" onclick="createObj(fromVal.options[fromVal.selectedIndex].text)">Create</button>
</form>
The value is then passed to the function createObj():
function createObj()
{
/*
DO THE WORK NEEDED
*/
}
Now what javascript code would clear the select option so that when it is called again it can be repopulated with any new objects placed into the array?
Thanks for any feedback.
BTW the popup form refers to the fact that im using the following jquery plugin: DOM Window
Thanks for any feedback.
Plain JavaScript:
var ob = document.getElementById('selectID');
while (ob.hasChildNodes())
ob.removeChild(ob.firstChild);
jQuery:
$('#mySelect').children().remove()
Don't forget to delete the previously created select tag using $('#mySelect').remove() and then run the function.
First of all, the best way to add a piece of html is to write it from string:
<form id="relationFormOne">
<script type="text/javascript" language="javascript">
$(function(){
var objectArray = [{Name:'1'},{Name:'2'},{Name:'3'}];
var selectHtml = [];
$('#relationFormOne').append($('<select name="mySelect">'));
$(objectArray).each(function(ix, val){
selectHtml.push('<option>'+val.Name+'</option>');
});
$('select[name=mySelect]').html(selectHtml.join(''));
});
</script>
<input type="button" value="clear" onclick="$('select[name=mySelect]>option').remove()" />
</form>
When you want to clear your select just use the code like the following:
$('#mySelect>option').remove();

Categories