jQuery Function results in NaN value - javascript

I have an error checking function that is just running me in circles.
function emailValUReq(v, noRet) {
var textReg = /[a-zA-Z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+\/=?^_`{|}~-]+)*#(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?/;
if (!v.val()) {
if (noRet == null) {
v.nextAll('.errText').html('<br>! Required Field');
}
return 1;
} else if (!textReg.test(v.val())) {
if (noRet == null) {
v.nextAll('.errText').html('<br>! Invalid Entry');
}
return 1;
} else {
$data = new Object;
$data['email'] = v.val();
$data['id'] = v.data('cur');
$.ajax({
type: "POST",
url: "/modules/data/dup_check.php",
data: $data,
success: function (r) {
if (r == 'ok') {
v.nextAll('.errText').empty();
return 0;
} else {
if (noRet == null) {
v.nextAll('.errText').html('<br>! An account already exists for this email');
}
return 1;
}
}
});
}
}
This function works perfectly overall. It returns 1 on an error, 0 when a value is correctly formatted and unique. The problem comes in when I try to 'add up' the errors from multiple functions.
(area and noRet are passed in)
var vErr=0;
area.find('.emailvalureq:visible').each(function () {
vErr += emailValUReq($(this), noRet);
});
When the input field is empty, or when it is incorrectly formatted, this works properly. As soon as the $.ajax call is fired within the validation script, it seems that the delay messes everything up and vErr ends up being a NaN value.
I have tried doing this as follows, with the same result:
var vErr=0;
area.find('.emailvalureq:visible').each(function () {
var ve1 = emailValUReq($(this), noRet);setTimeout(function(){vErr+=ve1;},1000);
});
I'm going to be at a family wedding for a couple hours, so I won't be able to respond to any questions / suggestions until later tonight - but any help is appreciated!

I tried using a when / done statement as follows:
$.when(emailValUReq($(this),noRet)).done(function(r){vErr+=r;});
but the problem with this was that 'r' was undefined (I was hoping it would pull the returned value from the emailValUReq function).
For me, the solution was to rework the emailValUReq function to simply update the error variable directly, as follows:
function emailValUReq(v, noRet) {
var textReg = /[a-zA-Z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+\/=?^_`{|}~-]+)*#(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?/;
if (!v.val()) {
if (noRet == null) {
v.nextAll('.errText').html('<br>! Required Field');
}
$err++;
} else if (!textReg.test(v.val())) {
if (noRet == null) {
v.nextAll('.errText').html('<br>! Invalid Entry');
}
$err++;
} else {
$data = new Object;
$data['email'] = v.val();
$data['id'] = v.data('cur');
$.ajax({
type: "POST",
url: "/modules/data/dup_check.php",
data: $data,
success: function (r) {
if (r == 'ok') {
v.nextAll('.errText').empty();
} else {
if (noRet == null) {
v.nextAll('.errText').html('<br>! An account already exists for this email');
}
$err++;
}
}
});
}
}
$err=0;
area.find('.emailvalureq:visible').each(function () {
emailValUReq($(this), noRet);
});
All that I need to then do is delay checking the value of $err for roughly 1 second, which gives the ajax call enough time to run and return the response.
setTimeout(function(){return $err;},1128);
I'm not sure if this was the best response, or the most elegant, but it worked!

Related

javascript function with if else statements ignore return true/false

So I have a PHP form which is being submitted with isset($_POST[]). I wrote a js function which runs some code with if-else which should return true/false but it's not and the form is getting submitted regardless.
I've tried using e.preventDefault() but that hasn't worked for me either. I also tried putting the true/false in a var as so out = true/false (Of course I put them in different var as for if and else), and then tried returning them as return out.
Code for true/false in var -
function submitFunc(a, b) {
if (a >= b) {
alert("*Duration cannot be greater than Quoted Hours");
out = false;
}
else {
out = true;
}
window.location = "add_working_details.php";
return out;
}
Original Code -
function submitFunc(a, b) {
if (a >= b) {
alert("*Duration cannot be greater than Quoted Hours");
// event.preventDefault();
//out = false;
return false;
window.location = "add_working_details.php";
}
else {
// out = true;
return true;
}
//return out;
// window.location = "add_working_details.php";
}
The AJAX function-
$("#submit").click(function(){//comparing the total quoted hours with duration of time selected
ticket_id = $('#ticket_no').val();
total_hours = $('#total_hours').val();
var user_dur, ud, th;
$.ajax({
url: 'comp_time.php',
type: 'GET',
data: {ticket_id: ticket_id, total_hours: total_hours} ,
success: function (response) {
// console.log("response", response);
var resp = response;
user_dur = $('#time_duration').text();
ud = compare_time(user_dur); //user duration
th = Number(resp); //total quoted hours
submitFunc(ud, th);
}
});
});
So I believe that returning false should stop the form from submitting and then with the window.location it should redirect to the page I want but it's not doing so.
Please correct me if my logic is wrong. Thanks for your time.
First your function should prevent the submit regardless of the event outcome
$("#submit").click(function(e){
e.preventDefault();
second you need to remove the returns from your function, they don't affect you click event
function submitFunc(a, b) {
if (a >= b) {
alert("*Duration cannot be greater than Quoted Hours");
} else {
window.location = "add_working_details.php";
}
}
$('#form').submit(function(e) {
if (submitFunc(1, 2)) {
$.ajax({});
} else {
e.preventDefault();
}
})

If condition not working if (str == "1") while data is returning 1

If condition not working while data is returning 1 and 0 but it always execute the else code, i am unable to find error, code is working fine on localhot but not on server
$('#by_head_name').on('blur', function() {
var headsubt = document.getElementById('by_head_name').value;
if (headsubt !== "") {
//alert('hi');
$.post('verify-head-or-subhead-name.php', {
headsub: headsubt
},
function(data, status) {
var str = data;
if (str == "1") {
var headd = "ok";
alert('ok');
} else if (str == "0") {
alert("No Head Exist, Please choose valid Head or create one before selecting it");
} else {
alert(data);
this.value == '';
}
});
}
Please check what "data" of the success function returns in your alert message.
If it returns string directly, then your condition should work.
If it shows object in the alert screen, please verify your object and accordingly choose a variable which satisfy your condition like data.value.

Matching exactly 10 digits in JavaScript and making Ajax Call

I want to create this function:
If ID is 10 digits it should make ajax call to file number 1
If ID is 18 digits it should make ajax call to another file
Here is the code:
function get_invoice_info(expressid,expressno,div_id)
{
document.getElementById("retData")
.innerHTML="<center>Please wait fetching tracking details for you...</center>";
var expressno = '{$order.invoice_no}';
var matches = expressno.match(/^\d{12}$/);
Ajax.call('plugins/track/tracking.php?CN='+ expressno,
'showtest=showtest',
function(data){
document.getElementById("retData").innerHTML=data;
},
'GET',
'TEXT'
);
} else {
Ajax.call('plugins/track/tracking.php?CN='+ expressno,
'showtest=showtest',
function(data) {
document.getElementById("retData").innerHTML=data;
},
'GET',
'TEXT'
);
}
This code is working exactly as i wanted it to be
function get_invoice_info(expressid,expressno,div_id)
{
var waitMsg = "Please wait fetching tracking details for you...";
document.getElementById("retData").innerHTML= waitMsg;
var expressno = '{$order.invoice_no}';
if(expressno.length === 12) {
filePath='tracking';
} else if(expressno.length === 18) {
filePath='track';
} else {
//Not in range, so exit
return;
}
Ajax.call('plugins/track/'+filePath+'.php?CN='+ expressno, 'showtest=showtest', function(data){document.getElementById("retData").innerHTML=data;}, 'GET', 'TEXT');
}
Am I missing something, seems like you can just check length (or does it need to only be numeric, in which case you can add another if statement to the beginning that checks for non numeric characters).
function get_invoice_info(expressid,expressno,div_id) {
var waitMsg = "Please wait fetching tracking details for you...";
var expressno = '{$order.invoice_no}';
var filePath = null;
document.getElementById("retData").innerHTML= waitMsg;
if(expressno.length === 10) {
filePath='file1';
} else if(expressno.length === 16) {
filePath='file2';
} else {
//Not in range, so exit
return;
}
var onSuccess = function(data){
document.getElementById("retData").innerHTML=data;
};
Ajax.call('plugins/track/'+filePath+'.php?CN='+ expressno,
'showtest=showtest',
onSuccess,
'GET',
'TEXT'
);

jQuery each with ajax call will continue before it's finished

I have some jQuery which uses an each loop to go through values entered in a repeated form field on a Symfony 3 CRM. There is a $.post which sends the entered value to a function that checks for duplicates in the database, and if it's a duplicate it adds something to an array, otherwise it adds a blank value to indicate it's not a dupe. Once these have been done, it then checks the final array and adds any errors to the error block to display to the user.
However, it seems that the array is ALWAYS blank and I belivee it's because it's running the code that displays the errors BEFORE it's actually finished getting the response.
Here is my code:
$('#puppy_form').on('submit', function() {
var bitch_errors = [];
var dog_errors = [];
// NOTE: Bitch and dog names need to be checked differently so we know which error is assigned to which input
$('.check_bitch_name').each( function(i, obj) {
// need to check each name for validity and duplication.
var entered_bitch_name = obj.value;
var pattern = /^[a-zA-Z,.]+\s[a-zA-Z,.]+(\s[a-zA-Z,.]+){0,}$/;
if(!pattern.test(entered_bitch_name)) {
bitch_errors[i+1] = "invalid";
} else {
// now to check for duplicates
$.post('/check-puppy-name', { name: entered_bitch_name }
).done(function (response) {
if(response == 'duplicate') {
bitch_errors[i+1] = "duplicate";
} else {
bitch_errors[i+1] = "";
}
});
}
});
$('.check_dog_name').each( function(i, obj) {
// need to check each name for validity and duplication.
var entered_dog_name = obj.value;
var pattern = /^[a-zA-Z,.]+\s[a-zA-Z,.]+(\s[a-zA-Z,.]+){0,}$/;
if(!pattern.test(entered_dog_name)) {
dog_errors[i+1] = "invalid";
} else {
// now to check for duplicates
$.post('/check-puppy-name', { name: entered_dog_name }
).done(function (response) {
if(response == 'duplicate') {
dog_errors[i+1] = "duplicate";
} else {
dog_errors[i+1] = "";
}
});
}
});
if(count(bitch_errors) == 0 && count(dog_errors) == 0) {
return true;
}
// loop through the errors and assign them to the correct input
$.each( bitch_errors, function( key, value ) {
if (value == "invalid") {
$('input[name="bitch_name['+key+']"]').parent().addClass('has-error');
$('input[name="bitch_name['+key+']"]').next('.error-message').html('Names must be at least two words, and only contain letters');
return false;
} else if(value == "duplicate") {
$('input[name="bitch_name['+key+']"]').parent().addClass('has-error');
$('input[name="bitch_name['+key+']"]').next('.error-message').html('Sorry, this name has already been taken');
return false;
}
});
$.each( dog_errors, function( key, value ) {
if(value != "") {
if (value == "invalid") {
$('input[name="dog_name['+key+']"]').parent().addClass('has-error');
$('input[name="dog_name['+key+']"]').next('.error-message').html('Names must be at least two words, and only contain letters');
return false;
} else if(value == "duplicate") {
$('input[name="dog_name['+key+']"]').parent().addClass('has-error');
$('input[name="dog_name['+key+']"]').next('.error-message').html('Sorry, this name has already been taken');
return false;
}
}
});
return false;
});
Basically, it first checks that the inputted name is valid, then posts off and checks for dupes. The issue is, even though it does the validity check (and prints errors accordingly) it seems to ignore the dupe check and carry on before it's even called back the first response.
How can I make sure it's finished it's checking before going on and adding the errors to the form? I've tried other solutions including attempting to implement the $.when functionality in jQuery but I don't really understand how to make it work. Any help appreciated.
First, write a function that returns an asynchronous promise to give you a value for one dog:
function checkDog(name) {
var pattern = /^[a-zA-Z,.]+\s[a-zA-Z,.]+(\s[a-zA-Z,.]+){0,}$/;
if(!pattern.test(name)) {
return $.Deferred().resolve("invalid");
} else {
return $.post('/check-puppy-name', { name: name } )
.then(function (response) {
if (response === 'duplicate') {
return 'duplicate';
} else {
return '';
}
});
}
}
Then you can write one that handles multiple dogs, also returning a promise (which won't itself be resolved until every dog has been checked):
function checkDogs(array) {
return $.when.apply($, array.map(checkDog));
}
Note that there's no DOM-related code yet. You can now write a function that gets the values from a bunch of DOM inputs and returns them in an array:
function getInputValues($selector) {
return $selector.get().map(function(el) {
return el.value;
});
}
So now (on submit) you can check your two sets of inputs and then finally when both of these are available, you can examine the results and update the DOM:
$('#puppy_form').on('submit', function() {
var bitch_names = getInputValues($('.check_bitch_name'));
var dog_names = getInputValues($('.check_dog_name'));
var bitch_promises = checkDogs(bitch_names);
var dog_promises = checkDogs(dog_names);
$.when(bitch_promises, dog_promises).then(function(bitch_errors, dog_errors) {
// update the DOM based on the passed arrays
...
});
});
You are right, ajax calls are like their name says asynchronous. Therefor you can only rely on the .done function. A simple solution would be to initialize a counter variable at the beginning for bitches and dogs and in the according done function you decrement it until it reaches zero. Then, also in the done function, you put an if that calls validation of the error arrays. Here is UNTESTED code to show what I mean:
$('#puppy_form').on('submit', function() {
/*
here you get the initial count for bitches and dogs
*/
var bitch_count = $('.check_bitch_name').length;
var dog_count = $('.check_dog_name').length;
var bitch_errors = [];
var dog_errors = [];
// NOTE: Bitch and dog names need to be checked differently so we know which error is assigned to which input
$('.check_bitch_name').each( function(i, obj) {
// need to check each name for validity and duplication.
var entered_bitch_name = obj.value;
var pattern = /^[a-zA-Z,.]+\s[a-zA-Z,.]+(\s[a-zA-Z,.]+){0,}$/;
if(!pattern.test(entered_bitch_name)) {
bitch_errors[i+1] = "invalid";
} else {
// now to check for duplicates
$.post('/check-puppy-name', { name: entered_bitch_name }
).done(function (response) {
if(response == 'duplicate') {
bitch_errors[i+1] = "duplicate";
} else {
bitch_errors[i+1] = "";
}
/*
now on every checked name you decrement the counter
and if both counters reach zero you can be sure you
checked all and only now you call your validation
*/
bitch_count--;
if(bitch_count === 0 && dog_count === 0) {
return validateErrors();
}
});
}
});
$('.check_dog_name').each( function(i, obj) {
// need to check each name for validity and duplication.
var entered_dog_name = obj.value;
var pattern = /^[a-zA-Z,.]+\s[a-zA-Z,.]+(\s[a-zA-Z,.]+){0,}$/;
if(!pattern.test(entered_dog_name)) {
dog_errors[i+1] = "invalid";
} else {
// now to check for duplicates
$.post('/check-puppy-name', { name: entered_dog_name }
).done(function (response) {
if(response == 'duplicate') {
dog_errors[i+1] = "duplicate";
} else {
dog_errors[i+1] = "";
}
/*
same here
*/
dog_count--;
if(bitch_count === 0 && dog_count === 0) {
return validateErrors();
}
});
}
});
}
/*
...and finally all code that should be processed after the ajax calls
*/
function validateErrors() {
if(count(bitch_errors) == 0 && count(dog_errors) == 0) {
return true;
}
// loop through the errors and assign them to the correct input
$.each( bitch_errors, function( key, value ) {
if (value == "invalid") {
$('input[name="bitch_name['+key+']"]').parent().addClass('has-error');
$('input[name="bitch_name['+key+']"]').next('.error-message').html('Names must be at least two words, and only contain letters');
return false;
} else if(value == "duplicate") {
$('input[name="bitch_name['+key+']"]').parent().addClass('has-error');
$('input[name="bitch_name['+key+']"]').next('.error-message').html('Sorry, this name has already been taken');
return false;
}
});
$.each( dog_errors, function( key, value ) {
if(value != "") {
if (value == "invalid") {
$('input[name="dog_name['+key+']"]').parent().addClass('has-error');
$('input[name="dog_name['+key+']"]').next('.error-message').html('Names must be at least two words, and only contain letters');
return false;
} else if(value == "duplicate") {
$('input[name="dog_name['+key+']"]').parent().addClass('has-error');
$('input[name="dog_name['+key+']"]').next('.error-message').html('Sorry, this name has already been taken');
return false;
}
}
});
return false;
});
You could use the async lib to manage these requests and collect the results which will then be passed into the final callback where you can process them.
I haven't tried to run this code but hopefully it will get you close enough if not already there.
async.parallel({
bitch_errors: function(callback) {
var bitch_errors = [];
async.forEachOf($('.check_bitch_name'), function(obj, i, cb) {
// need to check each name for validity and duplication.
var entered_bitch_name = obj.value;
var pattern = /^[a-zA-Z,.]+\s[a-zA-Z,.]+(\s[a-zA-Z,.]+){0,}$/;
if(!pattern.test(entered_bitch_name)) {
bitch_errors[i+1] = "invalid";
cb();
} else {
// now to check for duplicates
$.post('/check-puppy-name', { name: entered_bitch_name }
).done(function (response) {
if(response == 'duplicate') {
bitch_errors[i+1] = "duplicate";
} else {
bitch_errors[i+1] = "";
}
cb();
});
}
}, function () {
callback(null, bitch_errors);
});
},
dog_errors: function(callback) {
var dog_errors = [];
async.forEachOf($('.check_dog_name'), function(obj, i, cb) {
// need to check each name for validity and duplication.
var entered_dog_name = obj.value;
var pattern = /^[a-zA-Z,.]+\s[a-zA-Z,.]+(\s[a-zA-Z,.]+){0,}$/;
if(!pattern.test(entered_dog_name)) {
dog_errors[i+1] = "invalid";
cb();
} else {
// now to check for duplicates
$.post('/check-puppy-name', { name: entered_dog_name }
).done(function (response) {
if(response == 'duplicate') {
dog_errors[i+1] = "duplicate";
} else {
dog_errors[i+1] = "";
}
cb();
});
}
}, function () {
callback(null, dog_errors);
});
}
}, function(err, results) {
// you can now access your results like so
if(count(results.bitch_errors) == 0 && count(results.dog_errors) == 0) {
// ... rest of your code
});

Getting UnreadmessagesCount

The question I have here is for some reason when the getInboxUnreadMessagesCount js function is ran then it comes up with a different number then what is there to begin with and keep in mind there is no new message being sent. When I run the php dashboard functions they both are returning the correct numbers but I think the issue lies with the last line of code with the messageTimer
Anybody even have any thoughts onto what it might be? I'm hoping someone can figure it out.
var $messageCountJSON;
var messageTimer = '';
var messageInterval = 5;
//assumed JSON response is {"count":"20"} for example sake.
function getInboxUnreadMessagesCount(displayElementID) {
$.get('dashboard/getInboxUnreadMessagesCount', function (data) {
$messageCountJSON = data;
}, 'json');
if (displayElementID != null && displayElementID != undefined && displayElementID != '') {
//$('#'+displayElementID).html($messageCountJSON);
if (parseInt($('#' + displayElementID).text()) < parseInt($messageCountJSON)) {
$.jGrowl("You have received a new private message!", { theme: 'information' });
$('#' + displayElementID).html($messageCountJSON).css({ "display": "block" });
}
if (parseInt($messageCountJSON) == 0) {
$('#' + displayElementID).html($messageCountJSON).css({ "display": "none" });
}
}
}
function getInboxMessagesCount(displayElementID) {
$.get('dashboard/getInboxMessagesCount', function (data) {
$messageCountJSON = data;
}, 'json');
if (displayElementID != null && displayElementID != undefined && displayElementID != '') {
//$('#'+displayElementID).html($messageCountJSON);
if (parseInt($('#' + displayElementID).text()) < parseInt($messageCountJSON)) {
$('#' + displayElementID).html($messageCountJSON);
}
if (parseInt($messageCountJSON) == 0) {
$('#' + displayElementID).html($messageCountJSON);
}
}
}
$(document).ready(function () {
messageTimer = setInterval(function () { getInboxUnreadMessagesCount('notifications'); getInboxMessagesCount('inboxCount'); }, messageInterval * 1000);
});
//you can optionally kill the timed interval with something like
//$('#pmMessagesIcon').click(function(){clearInterval(messageTimer);})
You are trying to access the message count before it's received:
// Here you create an asynchronous request to the server.
$.get('dashboard/getInboxUnreadMessagesCount', function (data) {
// This section of your code will only run after you get the JSON response
$messageCountJSON = data;
}, 'json');
// Code here will run immediately after the request is fired,
// and probably before the JSON response arrives
You have to move your big if statements to inside each $.get() callback function.

Categories

Resources