jQuery Validator -- custom method does not hide error when valid - javascript

I have a custom validator checking a value against a database of acceptable values via an ajax request. I thought at first it wasn't hiding the error message because the request was being done asynchronously, so then it could perhaps fail to return true or false in time for the validator to recognize this.
I turned async off and the error message still remains shown. How can I get this to go away?
Through console logging it does return true, yet the error message still remains. I tried to explicitly hide the message, but the validator still assumes false and fails to submit.
jQuery.validator.addMethod("validZip", function(value, element){
var _id = $(element).attr("id");
$.ajax({
url: '/xpress/wp-admin/admin-ajax.php',
data: {action:"test_checkZip", zip:value},
type:"POST",
asyc: false,
success: function(response){
if (response== 0){
return false;
} else {
//$("label[for="+_id+"][class=error]").hide();
return true;
}
}
});
}, '*');

As Nicola pointed out, there's a typo in your callback.
Apart from that it's the callback function that is returning true/false, so actually your validZip function is still returning 'undefined'.
Try this:
jQuery.validator.addMethod("validZip", function(value, element){
var _id = $(element).attr("id");
var isValid = false;
$.ajax({
url: '/xpress/wp-admin/admin-ajax.php',
data: {action:"test_checkZip", zip:value},
type:"POST",
asyc: false,
success: function(response){
isValid = response!= 0;
}
});
return isValid;
}, '*');

Well i think you are checking against result shouldn't you check against response?
success: function(response){
if (response == false){
return false;
} else {
//$("label[for="+_id+"][class=error]").hide();
return true;
}
}

Could it be because you have:
asyc: false,
as opposed to:
async: false,

You used an incorrect answer's code from your previous question, See my answer in that question to see what's wrong. Anyway you should do like this:
jQuery.validator.addMethod("validZip", function(value, element){
var _id = $(element).attr("id");
var return_value;
$.ajax({
url: '/xpress/wp-admin/admin-ajax.php',
data: {action:"test_checkZip", zip:value},
type:"POST",
async: false,
success: function(response){
if (result == 0){
return_value = false;
} else {
//$("label[for="+_id+"][class=error]").hide();
return_value = true;
}
}
return return_value; //HERE you have to return
});
}, '*');
The problem is that you were returning you values inside a nested function, not your validator function.
Hope this helps. Cheers

Related

Ajax JSON malfunction

EDIT:
So I ended up with this code here, but as always, can't get it to work properly.
Basically it has to check that all input fields are filled, once this check is true, it calls the JSON url to check validity of the VAT number. If the VAT number check returns true, submits the form, else it inform the customer that there is an error and let the customer choose if to ignore the exception (then submits) or cancel submission and stay on the page.
Here is the JS code, and below is the JSON returned from the call.
$(document).ready(function() {
$('#create_customer').submit(function(){
var canSubmt = true;
$("form#create_customer :input").each(function(){
var input = $(this);
if($(input).val() == '') {
$(input).css("border",'1px solid red');
canSubmt = false;
}else{
$(input).css("border",'1px solid #000');
}
});
if(!canSubmt){ $("#errMsg").text("Errors detected! Please check your form and try again.").show().fadeOut(7000); return canSubmt; }
var vatNum = document.getElementById('VatNum').value;
var validVat;
var vatConfirm;
$.getJSON("http://apilayer.net/api/validate?&access_key=<api-key>&vat_number="+vatNum, function(response) {
validVat = response.valid;
})
.fail(function(){
console.log("failed");
});
if (!validVat) { vatConfirm = confirm("Your VAT number doesn't seem to be valid or in a correct format!\nDo you wish to continue anyway?"); }
if (!vatConfirm) { canSubmt = false; }
return canSubmt;
});
});
and the JSON data, from which I only need the "valid" key:
{ "valid": true, "format_valid": true, "query": "LU26375245", "country_code": "LU", "vat_number": "26375245", "company_name": "AMAZON EUROPE CORE S.A R.L.", "company_address": "5, RUE PLAETIS L-2338 LUXEMBOURG" }
any idea on how to get this working?
Ther're two issues:
Ajax is asynchronous, so before it returns the value of validVat execution probably has already reached the return statement
validVat's scope is inside the ajax function so it will undefined on the line "return ..."
The simplest thing you could do, is to make the ajax request synchronous, see following please:
var validVat = false;
$.ajax({
var vatNumber = document.getElementById("VatNum").value;
url: 'http://apilayer.net/api/validate?access_key=6ab1579cc9e968a65429d7f351375f35&vat_number='+vatNumber,
dataType: 'jsonp',
async: false,
success: function(json) {
// Access and use your preferred validation result objects
if (!json.valid) {
var r = confirm("Your VAT number doesn't seem to be valid or in a correct format!\nDo you wish to continue anyway?");
if (r == true) {
validVat = true;
} else {
validVat = true;
}
}
}
});
return validVat;
The best thing instead, should to use the callback function in order to submit the form or do anything you need after the response of ajax request.
Here's a complete example with a mock of ajax request, please see following:
var validated = false;
$("form").submit(function( event ) {
if(!validated){
event.preventDefault();
var mock = {
ajax: function() {
return mockAjax({
success: $("#test").val() === "correct",
response: { ok: $("#test").val() === "correct" },
timeout: 500
});
}
};
mock.ajax()
.done(function(valid) {
if(valid) {
$("#err").text("Validated... do submit").show();
validated = true;
return $("form").submit();
} else {
event.preventDefault();
}
})
.error(function(json) {
$("#err").text("Not valid!").show().fadeOut(1000);
});
}
});
function mockAjax(options) {
var that = {
done: function done(callback) {
if (options.success)
setTimeout(callback, options.timeout, options.response);
return that;
},
error: function error(callback) {
if (!options.success)
setTimeout(callback, options.timeout, options.response);
return that;
}
};
return that;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Type 'correct' to validate.</p>
<form action="javascript:console.log( 'success!' );">
<div>
<input id="test" type="text">
<input type="submit">
</div>
</form>
<span id="err"></span>
I hope it helps you, bye.

ajax loading indicator stopped in between

I am saving data on a save button click that calls ajax and passing json data to a controller method but when we save it loading starts and suddenly stop though the data is not saved.
It is not working I have tried it in all way but not working please help me on this.
<button type="button" id="saveDeleg" class="btn_reg_back btnmainsize btnautowidth btngrad btnrds btnbdr btnsavesize " aria-hidden="true" data-icon="">#Resources.Resource.Save</button>
$('#saveDeleg').click(function() {
var response = Validation();
if (!response) {
return false;
}
$("#overlay").show();
$('.loading').show();
if ($('#organName').val() == '') {
$('#validorganisation').show();
return false;
} else {
$('#validorganisation').hide();
}
//Contact name
var SubDelegation = $('#subdelegation').is(':checked');
var CopyNotification = $('#copynotification').is(':checked');
var ArrangementId = $("#ArrangementId").val();
var paramList = {
ArrangementId: ArrangementId,
ArrangementName: $('#arrangName').val(),
OrganisationName: $('#organName').val(),
OrganisationId: $('#OrganisationId').val(),
ContactName: $('#contactName').val(),
ContactId: $('#ContactId').val(),
SubDelegation: $('#subdelegation').is(':checked'),
CopyNotification: $('#copynotification').is(':checked'),
ContactType: $('#ContactType').val(),
SelectedTypeName: $("input[name$=SelectedType]:checked").val()
};
setTimeout(function() {
$.ajax({
async: false,
type: "POST",
url: '#Url.Action("SaveDelegation", "Structures")',
dataType: "json",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(paramList),
processdata: true,
success: function(result) {
//stopAnimation()
paramList = null;
if (result == 0) {
window.location.href = '../Structures/MyDelegationArrangement';
} else if (result == 1) {
window.location.href = '../Structures/CreateDelegation';
} else if (result == 2) {
window.location.href = '../Home/Error';
} else if (result == 3) {
window.location.href = '../Account/Login';
} else {
//validation message
alert('Error');
}
},
error: function() {},
complete: function() {
$("#overlay").hide();
$('.loading').hide();
}
});
}, 500);
});
The problem with the loading indicator is because you used async: false which locks up the UI. Remove that setting.
Also note that if the data is not being saved I would assume that your AJAX call is returning an error. If so, check the console to see the response code. It may also be worth putting some logic in the error callback function to give you some information on whats happened, as well as inform your users about what to do next.

avoid sending if any field empty Axax

In my form I have various fields including (input and selects) in which I want to check any empty field and prevent ajax call if any of the field is empty and focus on empty fields. so far I am trying this way, It alerts but also makes an ajax call.
$('#submit').click(function() {
$('input').each(function() {
if (!$(this).val()) {
alert('Some fields are empty');
return false;
}
});
event.preventDefault(); // using this page stop being refreshing
$.ajax({
type: 'POST',
url: "<?php echo site_url(''); ?>/shipment/create_shipment",
data: $('form').serialize(),
cache: false,
success: function(data) {
$('#F_id').val('');
$('#v_id').val('');
$('#shp_no').val('');
$('#shipDate').val('');
$('#sup').val('');
$('#sup-quantity').val('');
$('#box').val('');
$('#box-quantity').val('');
$("#sup").prop('disabled', true);
$("#sup-quantity").prop('disabled', true);
$("#box").prop('disabled', true);
$("#box-quantity").prop('disabled', true);
$('.alert-success').fadeOut(200).show();
$('.alert-danger').fadeOut(200).hide();
/// alert('form was submitted');
},
error: function(data) {
$('.alert-success').fadeOut(200).hide();
$('.alert-danger').fadeOut(200).show();
}
});
});
The return false returns from the each function and not the click function.
Try having a bool variable denoting valid, and return false if not.
var valid = true;
e.prevent.preventDefault(); // e being event variable in submit
$('input').each(function() {
if(!$(this).val()){
alert('Some fields are empty');
valid = false;
return false;
}
});
if(!valid) return false;
//.....
Hope this helps.

Function called by jQuery Form Plugin's beforeSubmit not returning value

The beforeSubmit function in my jQuery Form plugin needs to check whether the selected file already exists on the server. Here's that relevant code:
$('#frmSermonUpload').ajaxForm({
beforeSubmit: function() {
// Reset errors and clear messages
ClearForm(false);
var formValid = true,
fileExists = CheckFileExists();
console.log('beforeSubmit fileExists: ' + fileExists);
if (fileExists === 'true') {
$('#uploadedFile').addClass('inputError');
$('#fileErrorMsg').append(' A file with that name already exists on the server.');
formValid = false;
} else {
if (!ValidateUploadForm()) {
formValid = false;
}
}
console.log('formValid: ' + formValid);
if (!formValid) {
return false;
}
},
...
Here's the CheckFileExists() function:
function CheckFileExists() {
var fileName = $('#uploadedFile').val().replace(/C:\\fakepath\\/i, ''),
dataString;
dataString = 'checkFileExists=' + fileName;
console.log('fileName: ' + fileName);
console.log('dataString: ' + dataString);
$.ajax({
type: 'POST',
url: '../scripts/sermonUpload.php',
data: dataString,
success: function(serverResult) {
console.log('serverResult: ' + serverResult);
if (serverResult === 'existsTrue') {
return 'true';
} else {
return 'false';
}
},
error: function(xhr, status, error) {
alert('An error occurred while attempting to determine if the selected file exists. Please try again.);
}
});
//console.log('Current value of returnResult: ' + returnResult);
//return returnResult;
}
As you can see I'm using console output to check what's going on. In the CheckFileExists() function, fileName and dataString are being reported correctly. On the PHP side, I know that the POST data is getting there due to some logging I've got going on there.
Here's the PHP code that uses the POST data:
if (isset($_POST['checkFileExists']) && $_POST['checkFileExists'] !== '') {
$log->lwrite('**Checking if file exists.**');
$fileToCheck = $targetPath . $_POST['checkFileExists'];
$log->lwrite('file_exists: ' . file_exists($fileToCheck));
if (file_exists($fileToCheck)) {
echo 'existsTrue';
} else {
echo 'existsFalse';
}
}
What's happening is, in the console, the line console.log('beforeSubmit fileExists: ' + fileExists); is returning "undefined" (beforeSubmit fileExists: undefined).
Here's all of the console output for an upload where the file already exists, so the beforeSubmit should be stopped:
fileName: 042913sermon.mp3
dataString; checkFileExists=042913sermon.mp3
beforeSubmit fileExists: undefined
formValid: true
serverResult: existsTrue
It must be significant that the serverResult line is displaying after everything else. Does that have to do with how long the ajax call takes? If so, is there a way to delay the rest of the script until the ajax call is done executing?
UPDATE
As aorlando pointed out, the order of the console output signified that I needed to add async: false to my $.ajax call. After doing so, the console output was correct, but the function CheckFileExists() is still getting reported as undefined in beforeSubmit.
Ok. Now the problem is the scope of return.
If you use "async: false" you can return in this way (not so elegant)
var returnValue='';
$.ajax({
type: 'POST',
url: '../scripts/sermonUpload.php',
data: dataString,
async: false,
success: function(serverResult) {
console.log('serverResult: ' + serverResult);
if (serverResult === 'existsTrue') {
returnValue = 'true';
} else {
returnValue= 'false';
}
},
error: function(xhr, status, error) {
alert('An error occurred while attempting to determine if the selected file exists. Please try again.);
}
});
return returnValue;
You must declare a var returnValue out of the scope of the ajax call. Inside the ajax function you can modify the value of returnValue;
This is a solution which use closure, a quite complex javascript feature. Further read something about scope of a variable in javascript: What is the scope of variables in JavaScript?
This is not a very nice solution; is better if you call a function inside "success" function of ajax call as my previous example.
That's all folks!
You are using an AJAX async call.
Your method CheckFileExists()n return a value before the ajax call complete.
So the simplest solutions is to use:
$.ajax({
type: 'POST',
url: '../scripts/sermonUpload.php',
data: dataString,
async: false ...
if you want to use async call (the default as you can see: http://api.jquery.com/jQuery.ajax/
you must call (for ex.) a postcall function in the success function of the ajax call:
success: function(serverResult) {
console.log('serverResult: ' + serverResult);
if (serverResult === 'existsTrue') {
postFn('true');
} else {
postFn('false');
}
}, ...
Be carefull with the scope of the postFn
funcion postFn(_result){
console.log(_result);
}
I hope to be clear.
That's all folks!

How to save var value outside ajax success function?

I am trying to make some form validation functions. Here is what I have:
<script>
$(document).ready(function() {
var myObj = {};
$('#username').keyup(function () {
id = $(this).attr('id');
validateUsername(id);
});
function validateUsername(id){
var username = $("#"+id).val();
$.ajax({
url : "validate.php",
dataType: 'json',
data: 'action=usr_id&id=' + username,
type: "POST",
success: function(data) {
if (data.ok == true) {
$(myObj).data("username","ok");
} else {
$(myObj).data("username","no");
}
}
});
} // end validateusername function
$('#submit').click(function(){
if (myObj.username == "ok") {
alert("Username OK");
} else {
alert("Username BAD");
}
});
}); // end doc ready
So you can see, when a key is pressed in the textbox, it checks if it's valid. The "data.ok" comes back correctly. The problem is based on the response, I define $(myObj).username. For some reason, I can't get this value to work outside the validateusername function. When clicking the submit button, it has no idea what the value of $(myObj).username is.
I need to use something like this, because with multiple form fields on the page to validate, I can do something like:
if (myObj.username && myObj.password && myObj.email == "ok")
... to check all my form fields before submitting the form.
I know I must just be missing something basic.... any thoughts?
EDIT: SOLVED
All I had to do was change var myObj = {}; to myObj = {}; and it's working like a charm. I think I've been staring at this screen waaaaay too long!
You're not accessing the data that you stored properly. Access the username value this way:
$(myObj).data("username")
Resources:
Take a look at jQuery's .data() docs.
Very simple jsFiddle that shows how to properly set and retrieve data with jQuery's .data() method.
I would store the promise in that global variable and then bind an event to the done event within your submit button click.
$(document).ready(function() {
var myObj = false;
$('#username').keyup(function () {
id = $(this).attr('id');
validateUsername(id);
});
function validateUsername(id){
var username = $("#"+id).val();
myObj = $.ajax({
url : "validate.php",
dataType: 'json',
data: 'action=usr_id&id=' + username,
type: "POST",
success: function(data) {
$('#username').removeClass('valid invalid');
if (data.ok == true) {
$('#username').addClass('valid');
}
else {
$('#username').addClass('invalid');
}
}
});
} // end validateusername function
$('#submit').click(function(){
// if myObj is still equal to false, the username has
// not changed yet, therefore the ajax request hasn't
// been made
if (!myObj) {
alert("Username BAD");
}
// since a deferred object exists, add a callback to done
else {
myObj.done(function(data){
if (data.ok == true) {
alert("Username BAD");
}
else {
alert("Username OK");
}
});
}
});
}); // end doc ready
you may want to add some throttling to the keyup event though to prevent multiple ajax requests from being active at once.

Categories

Resources