Using jQuery validation plugin, I have been trying to retrieve a form's input field value, concatenate it with some url prefix to make a REST url, and then make a GET request to the resulting url via remote
method.
Below's the REST interface's method (server side is java)
@Path("/user")
public interface UserResource {
@GET
@Path("/registered/email/{value}")
public boolean isRegistered(@PathParam("value") String value);
}
And here's what the input field to be validated looks like
<form id="registerForm" action="/register" method="POST">
<input class="form-control" id="email" name="email" type="email" value='${email}' required/>
...
</form>
And then the jQuery validation script;
$('body #registerForm').validate({
rules : {
'email': {
required: true,
email: true,
remote: "/user/registered/email/" + $(this).find('#email').val()
},
},
messages : {
'email': {
required: 'Please enter your email address',
email: 'Please provide a valid email address',
remote: 'Email has already been taken',
},
},
});
Please note how the value passed to the remote
method is simply the REST url because according to /, the default request type
is GET... Note also how dataType
and data
are not specified because they are not necessarily needed for this case.
THE GOAL:
... Now, say the email entered by the user is [email protected]
I would normally expect the resulting url to look like the following;
http://localhost:8080/user/registered/email/[email protected]
THE PROBLEM: ... but instead here's what I get;
http://localhost:8080/user/registered/email/[email protected]
QUESTION: ... Notice the ?email=
before [email protected]
in the url... I wonder why the result of $(this).find('#email').val()
is being concatenated as a query param?... Please can somebody explain to me why this is happening?.. And also how do I solve this problem?
Thanks.
Using jQuery validation plugin, I have been trying to retrieve a form's input field value, concatenate it with some url prefix to make a REST url, and then make a GET request to the resulting url via remote
method.
Below's the REST interface's method (server side is java)
@Path("/user")
public interface UserResource {
@GET
@Path("/registered/email/{value}")
public boolean isRegistered(@PathParam("value") String value);
}
And here's what the input field to be validated looks like
<form id="registerForm" action="/register" method="POST">
<input class="form-control" id="email" name="email" type="email" value='${email}' required/>
...
</form>
And then the jQuery validation script;
$('body #registerForm').validate({
rules : {
'email': {
required: true,
email: true,
remote: "/user/registered/email/" + $(this).find('#email').val()
},
},
messages : {
'email': {
required: 'Please enter your email address',
email: 'Please provide a valid email address',
remote: 'Email has already been taken',
},
},
});
Please note how the value passed to the remote
method is simply the REST url because according to http://jqueryvalidation/remote-method/, the default request type
is GET... Note also how dataType
and data
are not specified because they are not necessarily needed for this case.
THE GOAL:
... Now, say the email entered by the user is [email protected]
I would normally expect the resulting url to look like the following;
http://localhost:8080/user/registered/email/[email protected]
THE PROBLEM: ... but instead here's what I get;
http://localhost:8080/user/registered/email/[email protected]
QUESTION: ... Notice the ?email=
before [email protected]
in the url... I wonder why the result of $(this).find('#email').val()
is being concatenated as a query param?... Please can somebody explain to me why this is happening?.. And also how do I solve this problem?
Thanks.
Share Improve this question asked May 12, 2015 at 14:04 SourceVisorSourceVisor 1,9961 gold badge29 silver badges48 bronze badges 7- I think is because the plugin gets the name of validation rule to pass the parameter. – pabgaran Commented May 12, 2015 at 14:22
-
This is not an answer, but, you'd be better of using the
submitHandler
and making your own ajax call etc. – lshettyl Commented May 12, 2015 at 14:24 - have you tried setting email: false, in stead? I mean, how does it know to make the query string [email protected] – Jacob Finamore Commented May 12, 2015 at 14:28
-
1
The value of the field is simply
$('#email').val()
.$(this).find()
is pletely unnecessary. And using a query string,?field="value"&field2="value2"....
, is exactly how data is sent with aGET
request. You would not use a URL segment for picking this value up on the server-side, just use theGET
array. – Sparky Commented May 12, 2015 at 14:49 - @Sparky, thanks for the heads-up... I was thinking the GET array might be a way out too. I'll give it a shot right-away and give feed back afterwards – SourceVisor Commented May 12, 2015 at 14:58
4 Answers
Reset to default 2QUESTION: ... Notice the
?email= before [email protected]
in the url... I wonder why the result of$(this).find('#email').val()
is being concatenated as a query param?... Please can somebody explain to me why this is happening?.. And also how do I solve this problem?
By default, a query string, ?field="value"&field2="value2"....
, is exactly how data is sent along with a GET
request. Typically, you would not use a URL segment for picking up this value on the server-side, just use the GET
array.
The jQuery Validate plugin's remote
method uses the same options as jQuery .ajax()
. Referring to the .ajax()
documentation...
data
Type: PlainObject or String or Array
Data to be sent to the server. It is converted to a query string, if not already a string. It's appended to the url for GET-requests. SeeprocessData
option to prevent this automatic processing. Object must be Key/Value pairs. If value is an Array, jQuery serializes multiple values with same key based on the value of the traditional setting (described below).
...
processData (default: true)
Type: Boolean
By default, data passed in to the data option as an object (technically, anything other than a string) will be processed and transformed into a query string, fitting to the default content-type "application/x-www-form-urlencoded". If you want to send a DOMDocument, or other non-processed data, set this option to false.
OP Title: JQuery Validation - How to correctly retrieve form field value in “remote” method?
To get the value of the field, simply select the field and attach it to a jQuery .val()
. There is no need to use $(this).find(...
$('#email').val()
Try this...
rules : {
'email': {
required: true,
email: true,
remote: {
url: "/user/registered/email/" + $('#email').val(),
processData: false
}
},
},
THE GOAL: ... Now, say the email entered by the user is [email protected] I would normally expect the resulting url to look like the following;
http://localhost:8080/user/registered/email/[email protected]
THE PROBLEM: ... but instead here's what I get;
http://localhost:8080/user/registered/email/[email protected]
There are two issues here. The first is that the validate method resolves the url path as it is executed - it is not reexamined dynamically by default. And when it is run, basically when the form is rendered, your email input field is empty. The path is thus resolved to 'http://localhost:8080/user/registered/email/' + '' (the static string you started with, concatenated with the empty string from the empty input field).
The second issue is that jQuery.validate's remote method by default sends along the validated field's 'name' and 'value' attributes as query parameters - which is, of course, not the REST way of doing things. these are flattened into '[email protected]', which is placed after the rest of the URL as it was resolved in the first step.
To get around the first issue, and build a REST-worthy path, you have to wrap your URL building in a function, which will be executed each time validation is requested on that input.
$('body #registerForm').validate({
rules : {
'email': {
required: true,
email: true,
remote: function() {
return '/user/registered/email/' + $('#email').val()
}
}
}
});
This will result in a proper REST API url, though it will still have the query string appended to it. It will look something like this:
http://localhost:8080/user/registered/email/[email protected][email protected]
Granted, this is ugly, but chances are your API will silently ignore the query string, and execute as expected.
But in order to get a cleaner, more RESTful url, you need to reset the data attribute of the ajax call. You do that by having your remote function from step one return an object, with the url string from before as the url parameter, and setting a data parameter to an empty string.
$('body #registerForm').validate({
rules : {
'email': {
required: true,
email: true,
remote: function() {
return {
url: '/user/registered/email/' + $('#email').val(),
data: ''
}
}
}
}
});
This will result in the desired, RESTful url
http://localhost:8080/user/registered/email/[email protected]
I used this code to work-around the REST service issue:
$("#mailingAddress").rules("add", {
required: true,
remote: function () {
var r = {
url: "/Api/Address/ValidateAddressSimple/" + $("#mailingAddress").val(),
type: "post",
cache: false,
dataFilter: function (response)
{
return response;
}
};
return r;
},
messages: {
remote: "* not valid"
}
});
taken from this post: https://stackoverflow./a/22467664
You are making a get request to what looks like a folder or location on your website. You need to provide a script that does the checking. So your remote url should be something like "/user/registered/email/check_email.php".
Also, the whole idea of a GET request is that the parameters are passed as name/value pairs that are tacked onto the query string after the "?" separator. See http://www.w3schools./tags/ref_httpmethods.asp. You are not providing an actual remote script, and are not providing a parameter name for your value, so you just get the url + "?" + your value.
Finally, I would remend you go with the POST method. In the resource you provided a link for, look at the second example. It shows you how to specify POST.
Does all this make sense?