Explicitly Rendering ReCaptcha - Onload Function Not Firing - javascript

From the documentation I understood that in order to change the language of the recaptcha I have to render it explicitly.
The problem is, however, that it's not really showing up, and the onload is not even called.
When I try to render it automatically it does work.
Here's the code:
In the HTML head: (I have also tried putting this at the end of the body tag)
<script src="https://www.google.com/recaptcha/api.js?onload=recaptchaCallback&render=explicit&hl=iw" async defer></script>
In the HTML form:
<div id="recaptcha"></div>
Javascript:
var recaptchaCallback = function() {
console.log('recaptcha is ready'); // not showing
grecaptcha.render("recaptcha", {
sitekey: 'My Site Key',
callback: function() {
console.log('recaptcha callback');
}
});
}

I just copied your code, used my own Site Key and it works.
The code I used is:
<html>
<body>
<p>ReCaptcha Test</p>
<div id="recaptcha"></div>
<script src="https://www.google.com/recaptcha/api.js?onload=recaptchaCallback&render=explicit&hl=iw" async defer></script>
<script type="text/javascript">
var recaptchaCallback = function () {
console.log('recaptcha is ready'); // showing
grecaptcha.render("recaptcha", {
sitekey: 'SITE_KEY',
callback: function () {
console.log('recaptcha callback');
}
});
}
</script>
</body>
</html>
Check your code carefully, as just a single character typo can stop things from working.

Make sure that your onload method is defined before the recaptcha script. Otherwise you will have a race condition where the recaptcha script could be attempting to call your method before it is defined (especially if the recaptcha script is cached).
From the documentation for onload https://developers.google.com/recaptcha/docs/display
Note: your onload callback function must be defined before the
reCAPTCHA API loads. To ensure there are no race conditions:
order your scripts with the callback first, and then reCAPTCHA
use the async and defer parameters in the script tags
For example:
<div id="recaptcha"></div>
<script type="text/javascript">
var recaptchaCallback = function () {
console.log('recaptcha is ready'); // not showing
grecaptcha.render("recaptcha", {
sitekey: 'SITE_KEY',
callback: function () {
console.log('recaptcha callback');
}
});
}
</script>
<script src="https://www.google.com/recaptcha/api.js?onload=recaptchaCallback&render=explicit&hl=iw" async defer></script>

My problem was that I did not realise that the second callback is only fired upon submission of the form - whereas the first callback is executed on page load.

HTML
<div id="captcha"></div>
<script src='https://www.google.com/recaptcha/api.js?onload=recaptchaReadycallback&render=explicit' async defer'></script>
JavaScript
// Render captcha and set call back function on api.js load finish
function recaptchaReadycallback(){
grecaptcha.render('captcha', {
'callback' : recaptchaCheckedCallback,
'expired-callback': recaptchaExpiredCallback,
'sitekey': 'YOUR-SITE-KEY'
});
}
// On expiry do stuff. E.g. show error
function recaptchaExpiredCallback(){
grecaptcha.reset();
// Show 'check the bloody box' error
};
// On not a robot confirmation do stuff. E.g. hide error
function recaptchaCheckedCallback(){
// Hide 'check the bloody box' error
}

Related

implementation of global variables in an HTML document with Javascript tags of different types

The situation : I use a script (a) in an HTML document to be able to use a particular SDK. Then I use a second script (b) basic to be able to create a Kendo UI table.
My problem : I try to pass data from script (a) to script (b) via global variables but it doesn't work, what can I do?
Info that might help you:
my document is a form framed by tags
I use Camunda. The first script allows me to use the SDK to retrieve the ID of the instance associated with the form being processed. (but I don't think this is the crux of the problem)
I assume that both scripts are read at the same time by the browser, and that's why script (b) can't read the variable simply because it is not yet created in script (a).
The code :
<script type="text/javascript" src="http://localhost:8080/camunda/app/tasklist/scripts/kendo.all.min.js"></script>
<script cam-script type="text/form-script">
var taskService = camForm.client.resource('task');
var processInstanceId = null;
var result = null;
taskService.get(camForm.taskId, function(err, task) {
//alert(JSON.stringify(task));
debugger;
processInstanceId = task.processInstanceId;
$.get("http://localhost:8080/engine-rest/process-instance/"+processInstanceId+"/variables", function(result) {
debugger;
window.alert("coucou");
console.log(result.JsonWeightSetpoints.value);
});
debugger;
console.log(result.JsonWeightSetpoints.value);
debugger;
});
</script>
<script type="text/javascript">
console.log(result.JsonWeightSetpoints.value);
//this is where I implement the Kendo UI grid
</script>
<div id="grid"></div>
I cannot read the content of the result variable in script (b) because it is not defined.
How do I do this?
Custom events solution:
<script type="text/javascript" src="http://localhost:8080/camunda/app/tasklist/scripts/kendo.all.min.js"></script>
<script cam-script type="text/javascript">
var taskService = camForm.client.resource('task');
var processInstanceId = null;
var result = null;
taskService.get(camForm.taskId, function(err, task) {
//alert(JSON.stringify(task));
debugger;
processInstanceId = task.processInstanceId;
$.get("http://localhost:8080/engine-rest/process-instance/"+processInstanceId+"/variables", function(result) {
debugger;
window.alert("coucou");
console.log(result.JsonWeightSetpoints.value);
// the value is available here, we now can trigger an event and send it
document.dispatchEvent(new CustomEvent("handler", {
detail: { value: result.JsonWeightSetpoints.value }
}));
});
debugger;
console.log(result.JsonWeightSetpoints.value);
debugger;
});
</script>
<script type="text/javascript">
console.log(result.JsonWeightSetpoints.value);
//this is where I implement the Kendo UI grid
// event listener, this would get executed only when we want
document.addEventListener("handler", function(event) {
// write you logic here
console.log(event.detail.value);
});
</script>
<div id="grid"></div>
useful resources:
MDN: Creating and triggering
events
Introducing asynchronous JavaScript

ReCaptcha3: How to call execute when user takes the action?

I managed to get ReCaptcha3 working when including it like this:
<script src="https://www.google.com/recaptcha/api.js?render=mykey"></script>
<script>
grecaptcha.ready(function() {
grecaptcha.execute('mykey', {action: 'homepage'}).then(function(token) {
document.getElementById("googletoken").value= token;
});
</script>
However, in the docs I found the following note:
Note: reCAPTCHA tokens expire after two minutes. If you're protecting an action with reCAPTCHA, make sure to call execute when the user takes the action.
Since I use the reCAPTCHA on a contact form, its likely that a user will take more then two minutes to write something.
Therefore, I tried to execute the key on submit (the alerts are only for testing):
<script src="https://www.google.com/recaptcha/api.js?render=mykey"></script>
<script>
grecaptcha.ready(function() {
document.getElementById('contactform').addEventListener("submit", function(event) {
alert('hi');
grecaptcha.execute('mykey', {action: 'homepage'}).then(function(token) {
alert('Iam invisible');
document.getElementById("googletoken").value= token;
});
}, false);
});
</script>
Now "Hi" is promted, but "Iam invisible" won't show up. Thus, it I get a missing-input-response on the server side. Why is then not fired inside addEventListener?
The problem is that the form is submitted before the async call grecaptcha.execute is complete. To fix the issue, one need to submit it manually:
<script src="https://www.google.com/recaptcha/api.js?render=mykey"></script>
<script>
grecaptcha.ready(function() {
document.getElementById('contactform').addEventListener("submit", function(event) {
event.preventDefault();
grecaptcha.execute('mykey', {action: 'homepage'}).then(function(token) {
document.getElementById("googletoken").value= token;
document.getElementById('contactform').submit();
});
}, false);
});
</script>

Getting error ReferenceError for a function that is defined lower than it's usage

I've read that you should keep your Javascript at the very bottom of your page. However when I do this I get a ReferenceError: showDialog is not defined error since I'm referencing it before it's usage. I have it wrapped in document.ready but still doesn't work.
Add New User
$(function() {
function showDialog() {
$('#dialog-AddUser').show();
}
}
$(function () {
function showDialog() {
$('#dialog-AddUser').show();
}
}
You got scope issues here. Not at all related to document loading. Remember that, whenever you declared/created something inside a function it is local to that function. Move it to outside where the whole document can see it.
Simply write
function showDialog() {
$('#dialog-AddUser').show();
}
Should work.
Even if you write this function inside document ready, your function again localised to that particular ready function and become invisible to outside.
Your function is defined in the context of an anonymous function:
$(function () {
function showDialog() {
$('#dialog-AddUser').show();
}
}
So showDialog cannot be called from outside the context of that anonymous function.
The solution here would be to add the click event handler from inside the function
$(function () {
function showDialog() {
console.log('clicked');
$('#dialog-AddUser').show();
}
$('#my-clickable-link').click(showDialog);
});
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
Add New User
Then ultimately you don't need the showDialog function, just another anonymous function as the click handler.
$(function () {
$('#my-clickable-link').click(function() {
$('#dialog-AddUser').show()
});
});
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
Add New User
<div id="dialog-AddUser" style="display:none;">Hello!</div>

Phantomjs and javascript function calling on target page

If I point phantomjs to this page:
<html>
<body>
<script>
$(document).ready(function () {
atesting();
});
</script>
</body>
</html>
with this phantomjs script
var page = require('webpage').create();
page.open('http://testpage.com', function(status) {
console.log("Status: " + status);
if(status === "success") {
page.render('testpage.png');
}
phantom.exit();
});
will it:
call the “atesting()” function or
will it not call it or
will it “maybe sometimes” call the function because it might stay on it long enough so that the function is called?
After some tests, it seems that the page is rendered before the document is ready. So the atesting() function will not be called.
If you want to render the page after the document is ready, see this answer : How can I wait for the page to be ready in PhantomJS?

Why doesn't function get called on first page load, only after refreshing?

I've searched, but I could not find the solution to this problem. For some reason function doesn't get called when page loads the first time, only after refreshing the page it gets called. Examples:
function init() {
alert("hello");
}
Either calling the function with following method:
$(window).load(function () {
init();
});
Or inside a body tag:
<body onLoad="init()">
Also, this problem doesn't occur when I open page directly, only when I'm being linked to the page from another page.
Solved, mobile options must be set before loading jquery.mobile.
<script language=javascript>
$(document).bind("mobileinit", function () {
$.mobile.ajaxLinksEnabled = false;
$.mobile.ajaxEnabled = false;
});
</script>
<script src="scripts/jquery.mobile-1.2.0.js"></script>
Try something in the lines of:
function init() {
alert('Hello!');
}
window.onload(function() {
init();
}

Categories