Fixed - see below :)
I'm using the jQuery validate plugin and for some reason I can't get it to return a valid field - always returns invalid.
http://plugins.jquery.com/project/jqueryvalidate
Here's what I have
$(function(){
$("#address").validate({
valid: function(val){
$.getJSON("http://maps.google.com/maps/geo?q="+ escape(val) +"&key=ABQIAAAAnfs7bKE82qgb3Zc2YyS-oBT2yXp_ZAY8_ufC3CFXhHIE1NvwkxSySz_REpPq-4WZA27OwgbtyR3VcA&sensor=false&output=json&callback=?",
function(data, textStatus)
{
if(data.Status.code=='200')
{
return true;
}else{
return false;
}
});
},
errorMessage: function(val){
return "must geo code";
},
appendCompletionIcon: true
});
});
I can see the GEO code requests coming back as found or not found for any particular address but the validation still fails - if I amend the function as follows I do get an alert yes or alert no in relation to a valid or invalid address but the validation still fails.
function(data, textStatus)
{
if(data.Status.code=='200')
{
alert('yes');
return true;
}else{
alert('no');
return false;
}
});
Any help would be appreciated
I found a way to hack around this, it's not extremely pretty as it takes two geo code calls to complete. Good enough for my purposes though.
var geocode = false;
function geoadd()
{
$.getJSON("http://maps.google.com/maps/geo?q="+ $("#address").val() +"&key=ABQIAAAAnfs7bKE82qgb3Zc2YyS-oBT2yXp_ZAY8_ufC3CFXhHIE1NvwkxSySz_REpPq-4WZA27OwgbtyR3VcA&sensor=false&output=json&callback=?",
function(data, textStatus)
{
if(data.Status.code=='200')
{
geocode = true;
}else{
geocode = false;
}
});
}
$(function(){
$("#address").validate({
valid: function(val){
geoadd();
return geocode;
},
errorMessage: function(val){
return "must not be blank";
},
appendCompletionIcon: true
});
});
Your validation fails regardless of ajax call status because the value returned from your valid handler is null, not true or false.
The true or false values are returned by the complete handler of the ajax which is not the same as returning true/false value from your valid function.
To solve this issue you would have to either make a synchronous ajax call (I wouldn't recommend it since it locks-up user interface while waiting for the response) or change your validation plugin for some other that supports validation using ajax calls.
Related
I am using jquery validation to double-check entered values. This is working find as long as my controller return true or false. Now I would like to analyze the return value first and then decide if the value is correct or incorrect.
So I am running the remote function like this:
supervisor: {
required:true,
remote: function() {
return {
url: "getADobject/" + $('#supervisor').val(),
data: '',
complete: function(data) {
console.info(data);
$(".loading").css('visibility', 'hidden');
if(data.responseJSON === false){
console.info(data.responseJSON);
//$('#supervisor').validate() = false;
//return 'false';
}
}
}
The object data returns the correct information and I also can do an if statement. But now I would like to say, yes the validation is OK or not. Can someone tell me how to add this information? I tried it already with an easy return true / 'true' / $valid = true but nothing :(
Thanks in advance
Stephan
I have been dealing with these issue for a few days, and I can't seem to be able to fix it on my own. I've already asked a question here on Stack regarding this, however I've been told this is resolved by using callback functions. I've done exactly that but the variable inside the callback still isn't changed.
I am using abide validation that is built into the Foundation framework, and I am trying to have my own custom validator for checking if an email already exists in our database. Everything works, even the console.log returns the correct results, but the variable value is not changed from false to true. Only check the code from emailVerification downwards.
Thank you for your help.
$(document).foundation({
abide : {
live_validate : false, // validate the form as you go
validate_on_blur : false,
patterns: {
positive_price: /^\+?[0-9]*\,?[1-9]+$/,
},
validators: {
positiveNumber: function(el, required, parent) {
var value = el.value.replace(/,/, '.'),
valid = (value > 0);
return valid;
},
emailVerification: function (el, required, parent) {
var email = el.value,
ajax = 1,
valid = false;
function checkServer(callback) {
$.ajax({
type: "GET",
url: "/check.do?action=userEmailAvailable",
data: "userEmail1=" + email + "&ajax=" + ajax,
success: callback
});
}
checkServer(function(data) {
if (data.result == 1) {
console.log(data.result + "does not exist");
valid = true;
} else {
console.log(data.result + "already exist");
valid = false;
}
});
return valid;
}
}
}
});
the valid that you declare in positiveNumber function is locally scoped to that function only. the next time you attempt to access it outside the function you actually create a global var called valid
As many answered, you need async validation and Abide does not support this.
I would suggest you use the excellent Parsley.js library which supports async validators through its Remote plugin
$.ajax runs asynchronously. You function returns "valid" before callback function is called. You can try running your ajax request synchronously or you need to add logic in your callback function that updates "valid" when it's called
How to create sync ajax
Add validation function to you callback
checkServer(function(data) {
if (data.result == 1) {
console.log(data.result + "does not exist");
valid = true;
} else {
console.log(data.result + "already exist");
valid = false;
}
DoCoolValidation(valid)
});
If you are sure that your server validation is fast enough you can do
function Validate(dataToSend) {
return JSON.parse($.ajax({
url: '/check.do?action=userEmailAvailable',
type: "GET",
dataType: "json",
data: dataToSend,
async: false
}).responseText);}
And use it:
valid = Validate("userEmail1=" + email + "&ajax=" + ajax);
Have a look at this post. It can help
I use Prototype.js to validate a form. For one of the fields, I have the prototype script ajax a request to a file. The file is a simple PHP file and will return '1' if the value is OK and '0' if the value is not OK. I have the script as below, which should work perfectly. The prototype validation is supposed to show a validation error message when a field does not pass validation, and not display / remove the message once the field passes validation. But in this case, even when the ajax file returns '1', the validation will display the error message anyway. Anyone able to help would be greatly appreciated!
['validate-number3', numessage3, function(v) {
new Ajax.Request('test.php?nr='+v, {
method:'get',
onSuccess: function(transport) {
var response = transport.responseText;
if(response == '1'){return true;}else{return false};
}
});
}],
the return value from Ajax.Request is the Ajax.Request object and returns as soon as the request is setup - the onsuccess callback is called after the request has been completed - so checking the results of Ajax.Request is not useful for what you want to accomplish.
The reason that this doesn't work as you expect, this is an asynchronous call which means it will start the call and then return control to the script while it is processing and then run the callbacks when it is completed.
Try it this way
new Ajax.Request('test.php?nr='+v, {
method:'get',
onSuccess: handleResponse
});
function handleResponse( transport ){
var response = transport.responseText;
if(response == '1'){
//everything is OK
}else{
//value is not OK
};
}
I was able to solve my question!
Thanks to this teriffic page: http://inchoo.net/ecommerce/magento/magento-frontend/magento-form-field-ajax-validation/ it was no problem. This is what I ended up with:
var ok = false;
new Ajax.Request('test.php?nr='+v, {
method:'get',
asynchronous: false,
onSuccess: function(transport) {
var response = transport.responseText;
if(response == '1'){ok = true;}else{ok = false;};
},
onComplete: function() {
if ($('advice-validate-number-pay_bank_no')) {
$('advice-validate-number-pay_bank_no').remove();
}
}
});
return ok;
I am using dojo forms and submitting using AJAX. I use 2 methods of validate: on client side and on server side:
dojo.connect(form, "onsubmit", function(event){
dojo.stopEvent(event);
var digit_form = dijit.byId("user_profile_form");
if (!digit_form.validate()) {
return false;
}
// client-side validation is ok, so we submit form using AJAX
var xhrArgs = {
form: form,
handleAs: "json",
load: function(responseText){
// here I get response from server
// and if there are errors on server
// responseText object contains array with errors, so I
// need to show this errors to user
},
error: function(error) {
}
}
var deferred = dojo.xhrPost(xhrArgs);
}
The problem is that validate() method shows nice error messages to user, but when I get errors from server I can't show errors like method validate() does, so I use native javascript alert() method that is not so nice. I would like equal displaying of errors that validates on server and client side.
For each server side error, set a new widget.SSError property.
error: function(error) {
widget.set('SSError','The value is invalid because server thought so...'
form.validate();
}
Override the widget.isValid() function and make it check the new widget.SSError property.
Based on this message,
var myCustomFS = dojo.declare(dijit.form.FIlteringSelect, {
postMixInProperties: function() {
this.inherited(arguments);
// Point _isValidOld at the function isValid currently points at
this._isValidOld = this.isValid;
// Point isValid at a new function
this.isValid = function() {
if (this.SSError) {
return false;
}
return this._isValidOld(); // Calls the original isValid function
}
}
};
Put a watch on the value and reset widget.SSError when it changes.
widget.watch('value', function(){
widget.set('SSError', false)
})
I understand that AJAX is asynchronous, and all that. But I have the following code:
function doesUsernameExist(element)
{
// Check via AJAX (POST) if username already exists in the database
var funcReturned = null;
$.post(
'_ajax_checkexist.php',
{
var: 'username',
value: element.value
},
function(data) {
funcReturned = (data.toLowerCase() == 'exists');
},
'data'
);
return funcReturned;
}
I understand why the function isn't returning a value properly, but what can I use as a workaround? This is for the Validity plugin, which requires a boolean returned by the doesUsernameExist function. I can't do the usual workaround of having the $.post function alter some HTML element. It needs to return true/false to doesUsernameExist.
What kind of workaround can I use? I'm stumped by this.
You could return a value if the call is synchronous. Here you have an example:
Solution for synchronous mode:
function doesUsernameExist(element)
{
// Check via AJAX (POST) if username already exists in the database
var funcReturned = null;
$.ajaxSetup({async: false});
$.post(
'_ajax_checkexist.php',
{
var: 'username',
value: element.value
},
function(data) {
funcReturned = (data.toLowerCase() == 'exists');
},
'data'
);
$.ajaxSetup({async: true});
return funcReturned;
}
The problem with your code, is that while the $.post is executing, the function continues it's execution (that's asynchronous), so will return null before your $.post ended.
Solution for asynchronous mode:
Using an asyncrhonous call, you cannot return a value, but can call callbacks or execute code just there. This could be an async solution:
function doesUsernameExist(element)
{
var funcReturned = null;
$.post( //This post is asynchronous
'_ajax_checkexist.php',
{
var: 'username',
value: element.value
},
function(data) {
funcReturned = (data.toLowerCase() == 'exists');
userExistanceCallback(funcReturned);
},
'data'
);
//We don't return anything
}
function userExistanceCallback(funcReturned){
if(funcReturned == true)
alert("User exists!!");
else
alert("User does not exist!!");
}
Hope this helps. Cheers
If this is for validation purposes you will find that the jquery.validate plugin and its remote rule are perfectly adapted for what you are trying to achieve.
So, instead of writing doesUsernameExist functions and worrying about asynchronousness of AJAX and how to return values you will write validation rules for your form (which in fact is the final goal of the exercise => focus on the business and leave the plumbing to plugins):
$('#id_of_some_form').validate({
rules: {
password: {
required: true
},
username: {
remote: '_ajax_checkexist.php'
}
}
});