Reputation: 22742
I am using the remote
method of jQuery Validation to check if a username already exists in the system. The script does_user_exist.php
returns 1
if the user exists.
$registration.find(".username").each(function() {
var $this = $(this);
$this.rules('add', {
remote: {
url: "does_user_exist.php",
type: "post",
dataType: "json",
data: {uname: function(){ return $this.val(); } },
async: false,
success: function (data) { //returns 1 if user exists
if (data) {
console.log("false!");
return "Sorry, that user already exists." //doesn't work
//return false; //doesn't work
//return data; //doesn't work
//return {"string"}; //doesn't work
//return {0: "string"};//doesn't work
} else {
console.log("true!");
return true;
}
}
},
messages: {
remote: jQuery.format("{0}") //doesn't work
// remote: "Simple string doesn't work here either"
}
});
});
My problem is that the error message is never displayed. I can see from my console.log
output that it correctly logs false!
when the user exists, but the error message never shows up.
As you can see from the commented out lines, I've been trying to figure out what exactly I'm doing wrong via guess-and-check, on the assumption that I'm somehow returning the error string in the wrong format, but I'm not having success.
Edit3:
I was able to get the backend response to be changed. The PHP is now sending JSON encoded true
/false
, to no avail. We have tried sending the backend response in the following ways, but the plugin doesn't seem to be catching it no matter what we do:
json_encode( false )
json_encode( '["false"]' )
json_encode( "false" )
json_encode( ["false"] )
"false"
false
NULL
""
0
As far as I can tell based on the documentation, one of these should have worked:
The response is evaluated as JSON and must be true for valid elements, and can be any false, undefined or null for invalid elements, using the default message;
Note, the answer to this question may be related to this issue.
Here is the revised code:
$registration.find(".username").each(function() {
var $this = $(this);
remote: {
url: "does_user_exist.php",
type: "post",
data: {entityExistence: function(){return $this.val();} },
success: function(data){ console.log(data); }
},
messages: {
remote: "Sorry, that username is not available."
}
});
The PHP script is always returning true
or false
correctly. According to the documentation, anything except for true
should trigger the error message. But the error message doesn't come up. I know error messaging is working because there are other checks are working fine (e.g. rangelength
, removed from pasted-in code here for clarity).
Upvotes: 6
Views: 16785
Reputation: 4879
If you need the endpoint to return the validation result as JSON instead of a boolean string like "true" or "false", you can use dataFilter
to validate the response.
Let's say you have an endpoint to validate if username exists, that returns the result as:
{"result": true}
You can check the result like this:
$('form').validate({
rules: {
username: {
minlength: 3,
maxlength: 30,
remote: {
url: "/validate/username/",
type: "post",
dataType: "json",
data: {
username: function () {
return $("#id_username").val()
}
},
dataFilter: function (response) {
response = $.parseJSON(response);
return response.result
}
}
},
...
});
Upvotes: 0
Reputation: 98728
The documentation for the remote
method states:
The serverside response must be a JSON string that must be
"true"
for valid elements, and can be"false"
,undefined
, ornull
for invalid elements, using the default error message. If the serverside response is a string, eg."That name is already taken, try peter123 instead"
, this string will be displayed as a custom error message in place of the default.
Quote OP:
"The script
does_user_exist.php
returns1
if the user exists."
This might be the opposite of what you want. Since 1
may be getting interpreted as true
, which tells the plugin it "passed" validation. As per docs, if the user exists and you want to trigger an error message, the response must be false
, undefined
, null
, or a string (the message).
Upvotes: 3
Reputation: 6696
Unfortunatley the answers above are slightly cryptic.
In order to get it working you need the follow JS.
$('#register-form').validate({
rules: {
'first-name': "required",
'surname': "required",
'email': {
required: true,
email: true,
remote: {
url: 'ajax/users/emailInUse',
type: 'post',
data: {
email: function() {
return $('input[name=email]').val();
}
}
}
},
'username': "required",
'password': "required",
'confirm-password': {
equalTo: "input[name=password]"
}
},
messages: {
'first-name': "Please enter your first name",
'surname': "Please enter your surname",
'email': {
required: "Please enter your email address",
email: "Please enter a valid email e.g. [email protected]"
},
'username': "Please enter a username",
'password': "Please enter a password",
'confirm-password': "Passwords do not match"
}
});
And your backend code should be running the check if the email is valid or not, and return the result as a message within a json string. e.g.
[
" is already in use..."
]
Example backend code:
public function emailInUseAction()
{
$this->setJsonResponse();
if($this->request->isAjax())
{
$email = $this->request->getPost('email');
$emailInUse = Users::emailInUse($email);
$message = false;
if($emailInUse)
{
$message = $email . ' is already in use...';
}
return array(
$message
);
}
}
Hope this helps anyone who encounters the issue!
Upvotes: 2
Reputation: 22742
Ok, finally figured it out, randomly. The success
callback was apparently ruining everything. All I had to do was remove this:
success: function(data){
console.log(data);
}
As soon as I did that, everything worked perfectly as expected using simple string responses:
"true"
and
"false"
I can not explain this, but I hope that someone updates the documentation! I noticed that using complete
does not break it the way that success
does.
Upvotes: 9
Reputation: 4923
Returning the string does not automatically display it. If you want to display it you need to do something like this:
$('#myDiv').html('<p class="error">Sorry, that user already exists.</p>');
Upvotes: -2