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
Related
I was wondering if my code should have return statement in my AJAX function. Here is example:
$.ajax({
type: 'POST',
url: 'Application.cfc?method=runProcess',
data: {'userID':userID},
dataType: 'json'
}).done(function(obj){
if(obj.STATUS == 200){
$('#searchMsg').addClass("success").show().text(obj.MESSAGE).delay(3500).fadeOut('slow').queue(function(){
$(this).removeClass("success").dequeue();
});
return true; //Should I keep this
}else{
$('#searchMsg').addClass("error").show().text(obj.MESSAGE).delay(3500).fadeOut('slow').queue(function(){
$(this).removeClass("error").dequeue();
});
return false; //Should I keep this
}
}).fail(function(jqXHR, textStatus, errorThrown){
alert(errorThrown);
});
As you can see I have two return statements in my function. Both will return either true or false depends on the ajax return obj. Should I keep them in my function or not? What is benefit of having them and what are the cons? If anyone can explain please let me know. Thank you!
No. Remove them. They do nothing for you. You already have the ability to know if the AJAX call succeeded or failed by which portion of your if/then in your callback function you hit.
All these statements do is send a value back to the caller that the caller then can use as it wishes and stop programmatic execution. Here, the caller is the done method call, which isn't expecting any return value and since you have the statements as the last things that will be done in the function, execution will stop anyway.
No need for this true or false if you send ajax call to check something and return server is exist they return true else false e.g Login i send ma username and password to database if exist return true than i check if ajax return true mean they user login to the system if false means user not exist but not need for true false if exist you need to open new link else give error not exist its depend on what scenario you want but not necessary to return true false its not compulsory
code example
$.ajax({
url: geturl,
type: "POST",
data:{email:email,pass:pass},
success: function (res) {
if (res == "admintrue")
{
AutoLoader("Admin Login Succeffully", "success");
var URL = $("#Afetlogin").val();
window.location.href = URL;
} else if (res == "membertrue") {
AutoLoader("Member Login Succeffully", "success");
var URL = $("#memberlogin").val();
window.location.href = URL;
}
else {
AutoLoader("Error", "error");
}
}
})
Good day guys. In my laravel application I'm trying to check if attendence for a particular date, subject, grade exists in my table. If so I have an if statement setup to display desire results based on what is returned.
I'm making the request with ajax but it seems like ajax keeps running the error function and I don't seem to get any error code whatsoever or internal server error(500, 404, 403, etc) In my console the status return is 200 ok
here is my script:
$(document).on('change', '#subject', function(event) {
event.preventDefault();
/* Act on the event */
var subject = $('#subject').val();
var grade = $('#grade').val();
var date = $('#date').val();
if (subject != "" && grade != "") {
$.ajax({
url:"/attendence/students",
method:"GET",
data:{"subject_id":subject, "grade_id":grade, "date":date},
dataType:"json",
success:function(data){
$("#result").html(data);
},
error:function(){
$("#result").html('There was an error please contact administrator');
}
});
}
});
Here is the controller the request is send to:
public function students(Request $request)
{
//
$grade = Grade::findOrFail($request->grade_id);
$subject = Subject::findOrFail($request->subject_id);
$students = Student::where('grade_id', $grade->id)->get(['id', 'first_name','middle_name', 'surname', 'grade_id']);
$statuses = Attendence::statuses();
// this check if attendence has been setup for the given date.
// if so prevent user for enter another date
$attendenceExists = Attendence::where([
'grade_id' => $grade->id,
'subject_id' => $subject->id,
'date' => $request->date
])->first();
if ($attendenceExists) {
return response()->json('A recorded attendence already exists for the seleced grade and subject!');
}
else {
return \View::make('attendence.partials.attendence-form')->with(array(
'students' => $students,
'subject' => $subject,
'date' => $request->date,
'statuses' => $statuses
));
}
}
Now, if this code returns true:
// this check if attendence has been setup for the given date.
// if so prevent user for enter another date
$attendenceExists = Attendence::where([
'grade_id' => $grade->id,
'subject_id' => $subject->id,
'date' => $request->date
])->first();
if ($attendenceExists) {
return response()->json('A recorded attendence already exists for the seleced grade and subject!');
}
The condition here runs and the right result is returned. But my else statement in the above does run but I don't get the right result. This is the result I get:
There was an error please contact administrator
Which shows that it is this part of the ajax request that is running:
error:function(){
$("#result").html('There was an error please contact administrator');
}
Surprisingly when I check the console this is what I see:
Which is exactly what I want but ajax is return otherwise. Am I doing something wrong?
Your dataType is set to json while you're returning html. Change it to html.
$.ajax({
url:"/attendence/students",
method:"GET",
data:{"subject_id":subject, "grade_id":grade, "date":date},
dataType:"json",
statusCode: {
200: function(data) {
$("#result").html(data.responseText);
};
}
}
});
Try this. I hope this will help you
I would say don't set the dataType at all. Just remove that setting altogether and let the jQuery ajax() method detect it automatically for you. That way, if the response type is JSON, it'll work. If the response type is HTML, it'll also work. 👍🏻
I read your reply regarding the jQuery validator where you outline a method to check a username against a value in a database.
Ive tried implementing this method but no matter what is returned from the PHP file I always get the message that the username is already taken.
Here is ths custom method...
$.validator.addMethod("uniqueUserName", function(value, element) {
$.ajax({
type: "POST",
url: "php/get_save_status.php",
data: "checkUsername="+value,
dataType:"html",
success: function(msg)
{
// if the user exists, it returns a string "true"
if(msg == "true")
return false; // already exists
return true; // username is free to use
}
})}, "Username is Already Taken");
And here is the validate code...
username: {
required: true,
uniqueUserName: true
},
Is there a specific way i am supposed to return the message from php.
Thanks
A
For anyone else who stumbles upon this, validate supports 'remote' method, which may not have existed in 2010:
https://jqueryvalidation.org/remote-method/
$("#myform").validate({
rules: {
email: {
required: true,
email: true,
remote: {
url: "check-email.php",
type: "post",
data: {
username: function() {
return $("#username").val();
}
}
}
}
}
});
You are doing an AJAX request, ergo: the validation is already finished working when your custom validator returns either true or false.
You will need to work with async. See also this post: How can I get jQuery to perform a synchronous, rather than asynchronous, Ajax request?
Something like:
function myValidator() {
var isSuccess = false;
$.ajax({ url: "",
data: {},
async: false,
success:
function(msg) { isSuccess = msg === "true" ? true : false }
});
return isSuccess;
}
Warning:
As of jQuery 1.8, the use of async: false with jqXHR ($.Deferred) is
deprecated; you must use the success/error/complete callback options
instead of the corresponding methods of the jqXHR object such as
jqXHR.done() or the deprecated jqXHR.success().
It took me forever to figure out how to get a jsonified string containing the value of an element in the page into the remote request- this is the result of a combination of many hours and trying many search results.
Key points:
async:false has been deprecated,
the function call right after remote: is the key for creating the data string with the element's value. Trying to access a current value from the form after data: was returning a blank value for the field with dataType set as json.
$("#EmailAddress").rules("add", {
required: true,
remote: function () { // the function allows the creation of the data string
// outside of the remote call itself, which would not
// return a current value from the form.
var emailData = "{'address':'" +
$('#SignupForm :input[id$="EmailAddress"]').val() +
"'}";
var r = {
url: "foobar.aspx/IsEmailAvailable",
type: "post",
dataType: "json",
contentType: "application/json; charset=utf-8",
cache: false,
data: emailData,
dataFilter: function(response) {
this.email_run = true; //fix for race condition with next button
return isAvailable(data); //return true or false
}
};
return r;
},
messages: {
remote: "* Email in use"
}
});
.ASPX page:
<input id="EmailAddress" required name="Email" type="email" placeholder="Email Address*" runat="server"/>
C# Code Behind:
[WebMethod]
public static object IsEmailAvailable(string address){...}
Formatting the response object:
function isAvailable(data) {
var response = JSON.parse(getJsonObject(data));
return (response.isAvailable === "True") ? true : false;
};
//transform response string to a JavaScript Object()
//http://encosia.com/never-worry-about-asp-net-ajaxs-d-again/
function getJsonObject(data) {
var msg = eval('(' + data + ')');
if (msg.hasOwnProperty('d'))
return msg.d;
else
return msg;
};
Here's my "old school" hack...
Below a utility function that allows the use of "asynchronous" validations with "jquery.validate.js" library. This function creates a delay between user keystrokes otherwise the validation function "validFunc" will be called "all time" which is not very performative in some circumstances and especially problematic for functions that perform validations on "serverside"/"backend" (ajax calls basically). In this way the "validFunc" validation function is only called when the user stops typing for a certain period of time which also allows a "realtime" validation ("onkeyup": true on jqv settings) as it occurs while the user is typing.
IMPORTANT: Validations involving the use of the "jqvAsyncValid" function should always be the last ones to avoid conflicts with the others due to the asynchrony.
{
[...]
"rules": {
"field_name": {
"required": true,
"maxlength": 12,
"minlength": 4,
// NOTE: Validation involving the use of the "jqvAsyncValid" function. By Questor
"my_custom_ajax_validation": true
},
[...]
}
ANSWER'S CODE:
// NOTE: Adds the custom validation "my_custom_ajax_validation". By Questor
$.validator.addMethod("my_custom_ajax_validation", function (value, element) {
return jqvAsyncValid(element, "my_custom_ajax_validation", myValidationFunc, this);
}, "My error message!");
// NOTE: My validation function. By Questor
function myValidationFunc(domElement) {
if (someFuncWithAjaxCall(domElement.value) == "ALL_RIGHT!") {
return true;
} else {
return false;
}
}
// NOTE: Global "json" variable that stores the "status" ("isValid") and cycle control
// ("toCtrl") of asynchronously validated elements using the "jqvAsyncValid" function.
// By Questor
var jqvAsyncVState = {};
// NOTE: A utility function that allows the use of asynchronous validations with
// "jquery.validate.js". This function creates a delay between one user keystroke and
// another otherwise the validation function "validFunc" will be called "all time"
// which is not very performative in some circumstances and especially problematic
// for functions that perform validations on the serverside/backend (ajax calls basically).
// In this way the "validFunc" validation function is only called when the user stops
// typing for a certain period of time, which also allows a "realtime" validation
// as it occurs while the user is typing. By Questor
// [Ref .: https://jqueryvalidation.org/ ]
//. domElement - DOM element informed by jqv in the "addMethod" for the anonymous
// function;
//. asyncRuleNm - Validation name added via "addMethod";
//. validFunc - Function that will do the validation. Must have the signature
// "funcName(domElement)" returning "true" for valid and "false" for not;
//. jQValidInst - Instance of the current jqv within "addMethod". It is usually
// denoted by "this";
//. toInMsecs - "Timeout" in "milliseconds". If not informed the default will be
// 1500 milliseconds. Be careful not to use a very short timeout especially in
// "ajax" calls so as not to overload the serverside/backend.
// Eg.: `return jqvAsyncValid(element, "my_custom_ajax_validation", myValidationFunc, this);`.
function jqvAsyncValid(domElement, asyncRuleNm, validFunc, jQValidInst, toInMsecs) {
if (typeof toInMsecs === "undefined" || toInMsecs === "") {
toInMsecs = 1500;
}
var domEKey = jQValidInst.currentForm.id + domElement.name;
// NOTE: The validation messages need to be "displayed" and "hidden" manually
// as they are displayed asynchronously. By Questor
function errMsgHandler() {
if (jqvAsyncVState[domEKey]["isValid"]) {
// NOTE: If the current error message displayed on the element was that
// set in the rule added via "addMethod" then it should be removed since
// the element is valid. By Questor
// [Ref.: https://stackoverflow.com/a/11652922/3223785 ,
// https://stackoverflow.com/a/11952571/3223785 ]
if (jQValidInst.errorMap[domElement.name] == $.validator.messages[asyncRuleNm]) {
var iMsgNow = {};
iMsgNow[domElement.name] = "";
jQValidInst.showErrors(iMsgNow);
}
} else {
var iMsgNow = {};
// NOTE: If the element is invalid, get the message set by "addMethod"
// for current rule in "$.validator.messages" and show it. By Questor
iMsgNow[domElement.name] = $.validator.messages[asyncRuleNm];
jQValidInst.showErrors(iMsgNow);
}
}
if (!jqvAsyncVState.hasOwnProperty(domEKey)) {
// NOTE: Set the global json variable "jqvAsyncVState" the control attributes
// for the element to be asynchronously validated if it has not already been
// set. The key "domEKey" is formed by the "id" of the "form" that contains
// the element and the element's "name". By Questor
jqvAsyncVState[domEKey] = {
"toCtrl": null,
"isValid": undefined
};
}
var useOnKeyup = true;
// NOTE: The "onblur" event is required for "first validation" that only occurs
// in a "blur" event - this is inherent to jqv - and for situations where the
// user types very fast and triggers "tab" and the event "onkeyup" can not deal
// with it. By Questor
domElement.onblur = function (e) {
jqvAsyncVState[domEKey]["isValid"] = validFunc(domElement);
errMsgHandler();
useOnKeyup = false;
}
if (useOnKeyup) {
// NOTE: The strategy with the event "onkeyup" below was created to create
// a "delay" between a "keystroke" and another one otherwise the validation
// function "validFunc" will be called "all time" which is not very performative
// in some circumstances and especially problematic for functions that perform
// serverside/backend validations (ajax calls basically). In this way the
// "validFunc" validation function is only called when the user stops typing
// for a certain period of time ("toInMsecs"). By Questor
domElement.onkeyup = function (e) {
// NOTE: Clear the "toCtrl" if it has already been set. This will
// prevent the previous task from executing if it has been less than
// "toInMsecs". By Questor
clearTimeout(jqvAsyncVState[domEKey]["toCtrl"]);
// NOTE: Make a new "toCtrl" set to go off in "toInMsecs" ms. By Questor
jqvAsyncVState[domEKey]["toCtrl"] = setTimeout(function () {
jqvAsyncVState[domEKey]["isValid"] = validFunc(domElement);
errMsgHandler();
}, toInMsecs);
};
}
return jqvAsyncVState[domEKey]["isValid"];
}
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
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.