I just try to get Google Invisible ReCaptcha to work after submitting a form.
My problem is, the ReCaptcha is NOT invisible, it looks like the "old" recaptcha is popping up. I don't understand why. My site-key is for invisible recaptcha. Please help me.
First of all i'm loading the API:
<script src='https://www.google.com/recaptcha/api.js?render=explicit&onload=onScriptLoad' async defer></script>
My form looks like this:
<form method="post" id="contact-form-face" class="clearfix" onsubmit="return false">
<input type="text" required name="name" value="name" onFocus="if (this.value == 'name') this.value = '';" onBlur="if (this.value == '') this.value = 'name';" />
<button type="submit" id="sendButton" data-size="invisible" class="g-recaptcha contact_btn" onclick="onSubmitBtnClick()" value="send" >send</button>
</form>
JS:
window.onScriptLoad = function () {
// this callback will be called by recapcha/api.js once its loaded. If we used
// render=explicit as param in script src, then we can explicitly render reCaptcha at this point
// element to "render" invisible captcha in
var htmlEl = document.querySelector('.g-recaptcha');
// option to captcha
var captchaOptions = {
sitekey: 'XXXXXXX',
size: 'invisible',
// tell reCaptcha which callback to notify when user is successfully verified.
// if this value is string, then it must be name of function accessible via window['nameOfFunc'],
// and passing string is equivalent to specifying data-callback='nameOfFunc', but it can be
// reference to an actual function
callback: window.onUserVerified
};
// Only for "invisible" type. if true, will read value from html-element's data-* attribute if its not passed via captchaOptions
var inheritFromDataAttr = true;
console.log("render now!");
// now render
recaptchaId = window.grecaptcha.render(htmlEl, captchaOptions, inheritFromDataAttr);
};
// this is assigned from "data-callback" or render()'s "options.callback"
window.onUserVerified = function (token) {
alert('User Is verified');
console.log('token=', token);
};
// click handler for form's submit button
function onSubmitBtnClick () {
var token = window.grecaptcha.getResponse(recaptchaId);
// if no token, mean user is not validated yet
if (!token) {
// trigger validation
window.grecaptcha.execute(recaptchaId);
return;
}
var xhrData = {
'g-recaptcha-response': token
// more ajax body/data here
};
};
To make things clearer: This reCaptcha works fine, the callback loads, the verification works fine as well.... The only problem is, that this recaptcha must be invisibile, while it's not :/
I think your problem is that you are explicitly calling the render() method
recaptchaId = window.grecaptcha.render(htmlEl, captchaOptions, inheritFromDataAttr);
};
if you want it to be invisible, you have to include this custom DIV
<div class="g-recaptcha"
data-sitekey="your_site_key"
data-callback="onSubmit"
data-size="invisible">
</div>
https://developers.google.com/recaptcha/docs/invisible
the recaptcha script will look for the div class element and bind it there, then execute the call back when the recaptcha verification is invoked.
to invoke the recaptcha verification use grecaptcha.execute();
follow the example in the googledev page, is pretty straight forward.
I hope that helped =)
I think you are missing the badge parameter in your "captchaOptions".
there are 3 possible values : bottomright (default), bottomleft and inline (which lets you customize the css of the recaptcha).
Looking at the JavaScript API docs,
https://developers.google.com/recaptcha/docs/invisible#js_api
You need to add a div with an id to render to, the class and data attributes are not required on the button element when you render the captchas with JavaScript.
Your HTML should be:
<form method="post" id="contact-form-face" class="clearfix"
onsubmit="return false">
<input type="text" required name="name" value="name" onFocus="if
(this.value == 'name') this.value = '';" onBlur="if (this.value ==
'') this.value = 'name';" />
<div id="recaptcha"></div>
<button type="submit" id="sendButton" class="contact_btn"
onclick="onSubmitBtnClick()"value="send">send</button>
</form>
And Your JS should be updated to:
// element to "render" invisible captcha in
var htmlEl = 'recaptcha'
Related
I wrote the code for a form validation.
Should work like this:
It checks (allLetter (uName)) and if it's true, then validate the next input.
If any validation is false then it should return false.
My problem is that if both validations are true, then everything is exactly false and the form is not sent.
If I set true in formValidation (), if at least one check false, the form should not be sent.
<form name='registration' method="POST" onSubmit="return formValidation();">
<label for="userName">Name:</label>
<input type="text" name="userName" size="20" />
<label for="userPhone">Phone:</label>
<input type="text" name="userPhone" size="20" />
<input type="submit" name="submit" value="Submit" />
</form>
function formValidation() {
var uName = document.registration.userName;
var uPhone = document.registration.userPhone;
if(allLetter(uName)) {
if(phone(uPhone)) {}
}
return false;
}
function phone(uPhone){
var digts = /^[0-9]+$/;
if(uPhone.value.match(digts)){
return true;
} else {
alert('Phone must have only digits');
uPhone.focus();
return false;
}
}
function allLetter(uName) {
var letters = /^[A-Za-z]+$/;
if(uName.value.match(letters)) {
return true;
}else{
alert('Username must have alphabet characters only');
uName.focus();
return false;
}
}
First, you are using a 20+ year old way to gain references to your elements (document.form.formElementNameAttributeValue) and, while this still works for legacy reasons, it doesn't follow the standard Document Object Model (DOM) API.
Next, you've broken up your validation tests into different methods (and that's certainly not a bad idea for reusability), but in this case is is adding a ton of code that you just don't need. I've always found it's best to start simple and get the code working, then refactor it.
You're also not using the <label> elements correctly.
One other point, your form is set to send its data via a POST request. POST should only be used when you are changing the state of the server (i.e. you are adding, editing or deleting some data on the server). If that's what your form does, you'r fine. But, if not, you should be using a GET request.
Lastly, you are also using a 20+ year old technique for setting up event handlers using inline HTML event attributes (onsubmit), which should no longer be used for many reasons. Additionally, when using this technique, you have to use return false from your validation function and then return in front of the validation function name in the attribute to cancel the event instead of just using event.preventDefault().
So, here is a modern, standards-based approach to your validation:
// Get references to the elements you'll be working with using the DOM API
var frm = document.querySelector("form[name='registration']");
var user = document.getElementById("userName");
var phone = document.getElementById("userPhone");
// Set up event handlers in JavaScript, not with HTML attributes
frm.addEventListener("submit", formValidation);
// Validation function will automatically be passed a reference
// the to event it's associated with (the submit event in this case).
// As you can see, the function is prepared to recieve that argument
// with the "event" parameter.
function formValidation(event) {
var letters = /^[A-Za-z]+$/;
var digts = /^[0-9]+$/;
// This will not only be used to show any errors, but we'll also use
// it to know if there were any errors.
var errorMessage = "";
// Validate the user name
if(user.value.match(letters)) {
// We've already validated the user name, so all we need to
// know now is if the phone is NOT valid. By prepending a !
// to the test, we reverse the logic and are now testing to
// see if the phone does NOT match the regular expression
if(!phone.value.match(digts)) {
// Invalid phone number
errorMessage = "Phone must have only digits";
phone.focus();
}
} else {
// Invalid user name
errorMessage = "Username must have alphabet characters only";
user.focus();
}
// If there is an error message, we've got a validation issue
if(errorMessage !== ""){
alert(errorMessage);
event.preventDefault(); // Stop the form submission
}
}
<!-- 20 is the default size for input elements, but if you do
want to change it do it via CSS, not HTML attributes -->
<form name='registration' method="POST">
<!-- The for attribute of a label must be equal to the id
attribute of some other element, not the name attribute -->
<label for="userName">Name:</label>
<input type="text" name="userName" id="userName">
<label for="userPhone">Phone:</label>
<input type="text" name="userPhone" id="userPhone">
<input type="submit" name="submit" value="Submit">
</form>
I wanna make easy way of page with password.
in javascript when i use any code with "location"(i tried everything.. replace, asign...etc), it didn't work anything!!!!
but instead of location.href, when i used window.open(), it is perfectly working.
but i wanna stay same window... not new tab or new window...
help me...
In Html
<form action="" method="post" name="Please enter the password to continue.">
<div class="WorkPassword">
<input type="password" class="button" id="WorkInputPassword"
name="password" placeholder="Please enter the password"/>
<input type="submit" class="button" id="submit" value="Enter" onClick="goLogin();">
</div>
and in javascript.
var input = document.getElementById( 'WorkInputPassword' );
var goLogin = function () {
var password = input.value;
if (password === '1234') {
location.href="google.com";
return false;
} else {
alert( 'check again' );
input.value = '';
return false;
}
};
If you want to redirect to a new domain you should use the complete address (including the http:// or https://).
location.href="http://google.com";
However in your case it's not enough, since you are inside a submit event of your form, and if you want to cancel that submit event you must use event.preventDefault() inside the function.
So, it should be something like that:
if (password === '1234') {
event.preventDefault();
location.href="http://google.com";
return false;
}
I have this email subscribe form for newsletter which gets delivered to me by email using PHP. It is located in footer which means that it is available on all pages across the website.
JSFIDDLE DEMO
Form works ok now but the problem is that it is interfering with other parts of website where forms are included - it messes those up and causes error to show on other fields as well.
My question is how do I isolate this form and script only for this part of the code so it will be defined only for this part of the webpage? What am I doing wrong?
As noted in the comments above,, you need to replace the "id" attributes in the html with "class" attributes. Then, modify your jQuery finders to search by class, constrained within the #subscribe form.
The HTML
<form id="subscribe" name="subscribe" action="#" method="post">
<input name="email" type="email" class="email" placeholder="Your e-mail adresss">
<span><button class="send" type="button">Subscribe</button></span>
</form>
And the Javascript
$(document).ready(function () {
$("#subscribe").submit(function () {
return false;
});
$("#subscribe .send").on("click", function () {
$('#subscribe input.error').removeClass('error');
var emailval = $("#subscribe .email").val();
var mailvalid = validateEmail(emailval);
if (mailvalid == false) {
$("#subscribe .email").addClass("error");
}
var minlen = $('#subscribe input[minlength]').filter(function(){
return this.value.length < +$(this).attr('minlength')
}).addClass('error').length;
if (mailvalid == true && minlen == 0) {
// if both validate we attempt to send the e-mail
// first we hide the submit btn so the user doesnt click twice
$("#send").replaceWith("<p><strong>Sending, please wait...</strong></p>");
$.ajax({
//you shouldn't need to change what you had here in the Fiddle; I didn't
//copy it for brevity's sake
});
}
});
});
Now that I can utilize the search function for reddit's API, I want the user to input their own query. I'm new to javascript and I think the problem with my code is that the API search function is being ran before the user even inputs the query.
HTML:
<div id="site-content">
<form name="RedditSearch">
Enter your query:
<input type="text" name="query" onkeydown="if (event.keyCode == 13) document.getElementById('search').click()"/>
<input type="button" id="search" value="Search" onclick="searchquery();" />
</form>
</div>
Javascript:
var container = $('#site-content')
function searchquery()
{
var query = document.RedditSearch.query.value;
}
$.getJSON("http://www.reddit.com/search.json?q=" + query, function(data) {
$.each(data.data.children, function(i,item){
var title = item.data.title
var post = '<div>'+title+'</div>'
container.append(post)
});
});
Indeed, it appears that your getJSON query is executed when the page loads. At that time, the user hasn't input anything yet, so it is executed too early.
You need to add an event listener which will detect user input, and then perform the AJAX call to the reddit API.
Assuming your user inputs his keywords in a text area, you could use .change().
You can fine more informations here : http://api.jquery.com/category/events/ or here http://www.w3schools.com/jquery/event_change.asp
Example in your case : http://jsfiddle.net/2ECG6/1/
Please could you advise on the following:
I have a registration form, and within that a text area
<form id="register" name="register" method="post" action="register.php">
<textarea rows="5" id="bio" name="bio" method="post">Biographical information</textarea>
</form>
Using java script i have been trying to create an event handler for the onfocus and onblur events so the default text is removed on focus and restored on blur, as follows:
var bioField = document.getElementById("bio");
bioField.onfocus = function() {
if (bioField.value == "Biographical information") {
bioField.value = "";
}
};
bioField.onblur = function() {
if (bioField.value == "") {
bioField.value = "Biographical information";
}
};
i thought by getting the element by id would work, but it doesn't seem to be. no other duplication of names/id exist.
Any help much appreciated.
Thanks guys
Use the placeholder attribute:
<textarea rows="5" id="bio" name="bio" method="post" placeholder="Biographical information"></textarea>
It's working fine, perhaps the issue is that the placeholder default is "Biographical Information" and the script is testing for "All about you". The change that you made as I was posting this is exactly what you needed.
var bioField = document.getElementById("bio");
bioField.onfocus = function() {
if (bioField.value == "Biographical information") {
bioField.value = "";
}
};
bioField.onblur = function() {
if (bioField.value == "") {
bioField.value = "Biographical information";
}
};
http://jsfiddle.net/YeaTQ/1/
My educated guess is that you've placed your code as is right into a <script> tag inside <head> so when the script runs the form has not loaded yet.
Move your <script> below the form or wrap everything with window.onload:
window.onload = function(){
// Code goes here
};
You have two solutions:
In order to not use the javascript code you wrote, Use the following code:
<textarea cols="30" rows="5" id="bio" name="bio" onfocus="this.value = '' " onblur="this.value = 'All about you'">Biographical information</textarea>
I think the javascript code is located before control (in the header I guess), Because of this, the onfocus and onblur properties are not initialized. You'll have to put the script at the end of the document (before the tag).
Also, you script is searching for another text ("All about you") and not the current text that's inside ("Biographical information"). Even if you insert the javascript code at the of the document, the code it will work.