AJAX Request Running Twice on Validation - javascript

I am doing a Validation for email input
$("#email").on("input",function()
{
email = $(this).val();
const regex_1 = /^([a-zA-Z0-9_\-\.]+)#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/;
const regex_2 = /^\w+([\.-]?\w+)*#\w+([\.-]?\w+)*(\.\w{2,10})+$/;
var re1 = new RegExp(regex_1);
var re2 = new RegExp(regex_2);
if(re1.test(email)===true && re2.test(email)===true)
{
e.preventDefault();
$.ajax({
url:"Validate.php",
method:"POST",
data:'type=check_email&email='+email,
success:function(data)
{
if(data == 'FAIL')
{
$("#email").addClass("is-invalid");
$("#email").removeClass("is-valid");
$("#email").focus();
}
else
{
$("#email").addClass("is-valid");
$("#email").removeClass("is-invalid");
}
}
});
}
else
{
$("#email").addClass("is-invalid");
$("#email").removeClass("is-valid");
$("#email").focus();
}
$("#email").removeClass("is-invalid");
$("#email").removeClass("is-valid");
});
So my issue is that when the validation through RegEx passes , the AJAX Call is made twice whereas the result from the first success:function(data) itself returns SUCCESS.
Two successive queries for the same instance will increase load on the server unnecessarily.
I personally think my bind is wrong here or that I haven't used e.preventDefault();
But I tried using input focus change keyup (individually as well as multiple binds) but nothing worked, the query still runs twice.
The concept here is that only when the RegEx test returns true then only the ajax is required to run (just once). Why is it running twice here ?
Required : The email(string) should pass both the RegEx tests

The event parameter e in the code is missing.
$("#email").on("input",function(e)
...
...
e.preventDefault();
Edit:
To prevent multiple event firing from the handler, you can return false; From JQuery docs:
Returning false from an event handler will automatically call
event.stopPropagation() and event.preventDefault().
In cases where the event is bound more than once, ensure only one handler is available by using off(). e.g.
$("#email").off('input').on("input",function(e) {
...

Related

Run tracking code after validation but before submit

There is form. Validation function is attached to submit event and it returns true/false ($(form).submit(...)).
<form name="f" class="form">
<input type=text name=ff>
</form>
$(".form").submit(function() {
if ($("[name='ff']").val()==="") {
return false
}
return true;
})
We want to run some tracking script that must be executed in case if validation return true but without changing original validation function (We have possibility to enable/disable tracking script from interface)
var _this = this;
ga('send', 'pageview', 'la-la-la', {
'hitCallback': function() {
jQuery(_this).parents('form').first().submit();
}
})
return !window.ga;
How would I do that properly?
So far I want to unbind current submit/validation function and bind my function and inside of it execute validation logic and then run my tracking code. In such way I can easy disable/enable tracking code without interrupting original behavior of logic.
However I have issues in doing this. Please advise. I want to do something like that
var fn = $(.form).submit // get attached logic - and that's does not work
$(.form).unbind('submit') // unbind it from submit
$(.form).submit(function() { // attach my code and reuse old code inside
my code...
if (fn()===true) {
my code...
}
my code...
})
You should use the following code $(form).on("submit", function(f){
//your function here. lets say you add a counter that starts from 0 and your validation functon returns its count. then you would say
if (counter != 0){ f.preventDefault(); } //this would stop the form from submitting until a condition on your function is met
});
I've made solution using hitCallback event
jQuery(".register-form").on("valid", function(f) {
var event = "/signup";
var _this = this;
ga('send', 'pageview', event, {
'hitCallback': function() {
_this.submit();
}
})
return !(ga.hasOwnProperty('loaded') && ga.loaded === true);
})

Using Blur and Submit events on the same form

I am still confused about this. Started learning JQuery about a week now and this is what I have:
var IsValidUserName = false;
$(document).ready(function () {
$('#txtUserName').blur(function () {
if ($('#txtUserName').val().match(isNumberLetter) &&
($('#txtUserName').val().length >= 8)) {
$('#userNameError').removeClass("error").addClass("default");
$('#txtUserName').removeClass("alert");
$('#txtUserName + label').removeAttr("id", "lblUserName");
IsValidUserName = true;
}
else {
$('#userNameError').removeClass("default").addClass("error");
$('#txtUserName').addClass("alert");
$('#txtUserName + label').attr("id", "lblUserName");
}
});
});
Lets say I have another function like above, lets say FirstName:
How do I call this on the submit event? The code works as I need it to when the user leaves a field. Not sure how I can also call this code and also use the variable above to prevent submit if the data entered is invalid.
I need to call the validation above if the user clicks the submit button and stop the submission if the IsValidUserName variable is false.
Somethings just need a little push.
Thanks my friends.
Guy
You could always extract it into a function instead of an anonymous function and pass the reference to the object you want to check. This would give you the added benefit of reusing it for other elements.
function validate(ele) {
var valid;
if (ele.val().match(isNumberLetter)) && (ele.val().length >= 8)) {
valid = true;
// update user here.
} else {
valid = false;
// update user here.
}
return valid;
}
$(function(){
$('#firstName').blur(function(){ validate($(this)); });
$('#lastName').blur(function(){ validate($(this)); });
$("yourFrom").submit(function(){
var firstNameIsValid = validate($('#firstName'));
var lastNameIsValid = validate($('#lastName'));
if (!nameIsValid) && (!lastNameIsValid) {
return false;
// User has already been updated
}
});
});
Also, since you are already heavily using javascript for your validation (hope this is convenience and not the only security), you can also disable the submit button entirely until the form meets the proper requirements.

keypress enter in jquery not firing after content change using ajax

i have jquery code to send request using ajax,.but after success function keypress not firing again this is my code
$(".id_sort").bind('keypress',function(e){
if (e.which == 13){
var index_fix = [];
var index_ori = [];
for (i=0;i < $("tbody tr").length; i++){
index_ori.push(i);
}
$(".id_sort").each(function(){
index_fix.push(Number($(this).val())-1);
});
if (JSON.stringify(index_fix) !== JSON.stringify(index_ori)){
data = { key : 'sort', index : JSON.stringify(index_fix)};
$.ajax({
url : "/ajax/",
data : data,
type : "POST",
cache : false,
success : function (resp){
$(".data").html(resp);
// what should i do here..keypress enter doesn't work in second time
}
});
}
else {
alert("data sama coy");
}
}
});
Check your browser console for JavaScript errors. I suspect that maybe the JavaScript is throwing an error and not running this code anymore after the first keypress.
Is it a problem that if any of the fields of class .id_sort have anything in them besides blank that you'll get NaN when you convert to a number and when you pass the value to the server will it accept NaN for a value?
It sounds to me like the dom node you're binding to may be getting replaced/overwritten by your $(".data").html(resp); call. Binding to events only work on nodes that are already in the dom.
So if that's the case, then you either need to rebind in your success callback after replacing the dom, or you can bind the click event to a higher node. For example: $(".data").on("keypress", ".id_sort", function() { ... });

why "return false;" or "event.preDefualt();" doesn't work after $.post();?

why "return false;" or "event.preDefualt();" doesn't work after $.post();
Firstly,I simply written a return false after
$(#id).submit(function(e){ return false;}// it works properly.But
when i call something via $.post('check-email.php',{parameter},function{data}) and i try to write return false after that $.post call.It doesn't works and directly goes to next page.
here is my code:-
$(document).ready(function () { //newly added
$('#mysignupform').submit(function (event) {
return false;
or event.preDfault(); // only work here
var emailVal = $('#inputEmail').val(); // assuming this is a input text field
//alert(emailVal);
$.post('check-email.php', {
'email': emailVal
}, function (data) {
alert(data);
if (data == 'false') {
$("#mysignupform").submit(function (event) {
return false;
or event.preventDefault(); //both doesnt work here..why??
;
});
} else {
$("#mysingupform").submit(function () {
return false;
}); //retrun false doesnt work here..why??
}
});
});
});
I dont want to allow them to submit but still its happening. Please help me..!
Thanks in advance..
This should work:
$(document).ready(function () { //newly added
$('#mysignupform').submit(function (event) {
// your $.post call
$.post('check-email.php', {email: emailVal}, function (data) {
// ...
// having a return false means returning false to the success callback
// of your .post call. it is not the same as returning false to the
// submit() callback
});
// return false to submit()
return false;
});
});
Ajax works asynchronous. The easy solution is bind a click event handler on the submit button.
$('#your_submit_button').click(function (event) {
event.preventDefault();
var emailVal = $('#inputEmail').val(); // assuming this is a input text field
$.post('check-email.php', {
'email': emailVal
}, function (data) {
if (data !== 'false') {
// submit the form here
$("#mysingupform").submit();
}
});
});
Because $.post is asynchronous. Execution continues at the statement following the call to $.post immediately. Since there isn't a statement following it, the submit event handler function will simply return undefined and the browser will happily continue with the submit as if nothing happened.
The callback to asynchronous methods will only be executed some time later. In your case, that will be when the server returns a response. Since the outer function has already returned, there is nowhere for that callback function to return to.
You will need to always prevent the default action in a click event handler on the form submit button, and then re-submit the form programatically upon success in the $.post callback:
$('#mysignupform :submit').click(function (event) {
var form = this.closest("form"); // Get a reference to the containing form
event.preventDefault(); // Prevent the default action (form submission)
$.post('check-email.php', { /* data */ }, function (data) {
// If the data is good...
form.submit(); // Submit the containing form
});
});
Obviously you can't really do this if you're binding to the form submit event, since the re-submission of the form will trigger the event handler again and you'll be stuck in an infinite loop.
$.post(...) is asynchronous. Try $.ajax(async: false, ...) instead.
This is because the function that is executed after the post completes is executed asynchronously, i.e. you are no longer in the event handler.
This answer has a technique you can use - basically click the submit button again, after setting a Boolean flag to prevent your post logic from being executed twice.

Determining which submit button was clicked from jQuery/JavaScript [duplicate]

This question already has answers here:
How can I get the button that caused the submit from the form submit event?
(22 answers)
Closed 9 years ago.
I'm ajaxifying some forms from a PHP application I didn't write. To do this, I came up with this clever solution:
jQuery("form").submit(function(event) {
// get some values from elements on the page:
var the_form = jQuery(this);
var data = the_form.serialize();
var url = the_form.attr( 'action' );
var button = event.originalEvent.explicitOriginalTarget;
data = data + "&" + button.name + "=" + button.value;
// Send the data using post and put the results in a div
jQuery.post( url, data, function() {
//Do something crazy
});
// stop form from submitting normally
if (event.preventDefault)
{
event.preventDefault();
}
else
{
event.returnValue = false;
}
});
Which works perfectly. I went away rejoicing. The problem is, I inadvertently used a Mozilla/Gecko only property to determine which button was clicked. (event.originalEvent.explicitOriginalTarget) Which means this only works in Firefox. :-(
All of this is necessary because the web app I'm augmenting relies on the button name/value being in the post data to process the form correctly. So, my question in simple terms would be:
What is the best, cross-browser way to determine which button was clicked in jQuery's submit event?
Edit:
And here is my solution.
jQuery("some selector that targets your form").find(":submit").click(function(event) {
// get some values from elements on the page:
var the_form = jQuery(this).parents("form");
var data = the_form.serialize();
var url = the_form.attr( 'action' );
var button = event.target;
data = data + "&" + button.name + "=" + button.value;
// Send the data using post and put the results in a div
jQuery.post( url, data, function() {
//Do something crazy
});
// stop form from submitting normally
if (event.preventDefault)
{
event.preventDefault();
}
else
{
event.returnValue = false;
}
});
See this question: Crossbrowser equivalent of explicitOriginalTarget event parameter
You're going to have to attach the event listeners to the buttons instead of the form to get a good reliable way of determining which one fired the submit.
http://api.jquery.com/event.target/
jquery.event.target should work because it is normalised for most browsers.
jquery.event.currentTarget can be used to retrieve the current item in the event bubbling chain.
Edit--
After some reflection and #greg's suggestion:
I've posted a code snippet on jsfiddle.
Using click handlers to submit the form is problematic beacuse you cannot use submit event handlers for validation (which is the way pretty much any validator plugin does it). Also, when you are not using AJAX to post, disabling submit buttons can have weird effects in some browsers if done in the click event and not the submit event.
The way jQuery.Form solves this is to set up a click handler which stores the clicked button (and then clears it with a small timeout), and use the submit handler to actually send the form contents via AJAX.
Here is a function I used to "ajaxify" my forms with jQuery.
function ajaxifyForm(form, callback)
{
var clicked
form.find("button").click(function()
{
if (clicked != null) clicked.removeAttr("data-clicked")
clicked = $(this)
$(this).attr("data-clicked", 1)
})
form.submit(function(event)
{
var data = {}
var name = ""
form.find(":input").each(function()
{
var input = $(this)
if (!(name = input.attr("name"))) return
switch (input.attr("type"))
{
case "radio":
case "checkbox":
if (input.attr("checked")) data[name] = input.val()
break
case "submit":
if (input.attr("data-clicked")) data[name] = input.val()
break
default:
data[name] = input.val()
}
})
$.ajax({
url: form.attr("action"),
success: function(data)
{
if (typeof callback == "function") callback("success")
},
error: function()
{
if (typeof callback == "function") callback("error")
},
data: data,
type: form.attr("method")
})
return false
})
return form
}

Categories