I have a dream, and in this dream form-validation is not a chore. All the nasty work is done client-side, and we – the developers – control what an error message says and where it says it! Server-side validation?! Pah, I spit in it’s general direction (but only if no ladies are present). I don’t need or want client-server round-trips.. I want speed, I want beauty, I want control; and I think you do too.
Using either inputFields, Apex exception handling and/or the ‘required’ attribute in VisualForce, we have a number of mechanisms to deal with form-validation, but if we’re honest with ourselves, they’re the ten-thousands-spoons when all we need is a knife. I know you’ve heard me singing it’s praise from the rooftops, but yet again, jQuery is here to save the day.
In preparation you may want to read this article on VisualForce and JavaScript.
Using a typical web registration form as an example, we’d typically expect our VisualForce to look something like this:
<pagemessages>
</pagemessages>
<form id="commentForm">
<outputlabel for="name">
Name (required, at least 2 characters)
</outputlabel>
<inputtext id="name" value="{!name}">
</inputtext>
<outputlabel for="email">
E-Mail (required)
</outputlabel>
<inputtext id="email" value="{!email}">
</inputtext>
<outputlabel for="url">
URL (optional)
</outputlabel>
<inputtext id="url" value="{!url}">
</inputtext>
<outputlabel for="comment">
Your comment (required)
</outputlabel>
<inputtextarea id="comment" value="{!comment}">
</inputtextarea>
<outputlabel for="pwd">
Password
</outputlabel>
<inputsecret id="pwd" value="{!pwd}">
</inputsecret>
<outputlabel for="cpwd">
Password
</outputlabel>
<inputsecret id="cpwd" value="{!cpwd}">
</inputsecret>
<commandbutton action="{!save}" value="Submit">
</commandbutton>
</form>
How would we usually add validation? Well to enforce some of the more common rules you’d need to add the ‘required’ attribute on the desired fields, and in addition to that you would still need to perform server side validation using Apex, which is slow, and takes a lot of monotonous effort.
Of course inputFields have quite a bit of neat baked-in validation, but what if we’re not working with SObject fields (or selectlists or we want more validation than just required or we want validation to happen in realtime or.. or.. or.. )?
So how do we “fix” this? Well I’m glad you asked, because it’s easier than you might think. Starting at the beginning we’ll need to include the base jQuery library in our page, as well as the jQuery Validate plugin:
<apex:includescript value="{!$Resource.jquery}"></apex:includescript>
<apex:includescript value="http://ajax.microsoft.com/ajax/jquery.validate/1.6/jquery.validate.min.js"></apex:includescript>
And then we can start with the real magic. In the document.ready() jQuery function we attach the validate event-handler to the form, and using the short, human-readable syntax, we attach rules – with their specific requirements – to each field:
$(document).ready(function() {
$(‘[id$=commentForm]’).validate();
$(‘[id$=name]’).rules("add",{
required: true,
minlength: 5
});
$(‘[id$=email]’).rules("add",{
required: true,
email: true
});
$(‘[id$=url]’).rules("add",{
url: true
});
$(‘[id$=comment]’).rules("add",{
required: true
});
$(‘[id$=pwd]’).rules("add",{
required: true,
minlength: 5
});
$(‘[id$=cpwd]’).rules("add",{
required: true,
minlength: 5,
equalTo: ‘[id$=pwd]’
});
/* Continued below */
The syntax is straight-forward, for each VisualForce element we’re ADDing a set of rules. For some we are dictating that they be required, for others we’re saying they must adhere to the recognised form of a URL or EMAIL ADDRESS. We even have the ability to easily say that the password- and password-confirmation fields must be the same. Not only that, but we can combine the rules to any degree we wish! I’ve only listed a few of the rule options here, there are many others such as NUMBER, TEXT, CREDIT CARD, DATE, NUMBER RANGES as well as the ability to write your own custom validations. Additionally you can customise the wording of the error message:
/* Customised the messages */
jQuery.validator.messages.required = "You better have entered a value.. or else!";
jQuery.validator.messages.equalTo = "No silly, you’re supposed to type the same set of characters AGAIN.";
});
These messages can include images; be grouped together at the top of the page (or anywhere else) or appear independently. Messages are also displayed in AJAXy realtime without any client-server round-trips. This, ladies and gentlemen is the the mother of all validation libraries, and it is far too big for me to [re]document. The example I’ve given is enough to get you going and I invite, nay, I challenge you to dig into it’s depths. The full documentation can be found on the jQuery site, but I’d recommend taking a look at a few of the worked examples on the plugin-creator’s site, and checkout the above VisualForce code in action.
The full code is listed below (feel free to correct/optimise/twist/tweak/break in all manners imaginable).
<apex:page standardcontroller="Account" showHeader="false" standardStylesheets="false">
<apex:includeScript value="{!$Resource.jquery}" />
<apex:includeScript value="http://ajax.microsoft.com/ajax/jquery.validate/1.6/jquery.validate.min.js" />
<script type="text/javascript">
$(document).ready(function () {
$('[id$=commentForm]').validate();
$('[id$=name]').rules("add", {
required: true,
minlength: 5
});
$('[id$=email]').rules("add", {
required: true,
email: true
});
$('[id$=url]').rules("add", {
url: true
});
$('[id$=comment]').rules("add", {
required: true
});
$('[id$=pwd]').rules("add", {
required: true,
minlength: 5
});
$('[id$=cpwd]').rules("add", {
required: true,
minlength: 5,
equalTo: '[id$=pwd]'
});
/* Customised the messages */
jQuery.validator.messages.required = "You better have entered a value.. or else!";
jQuery.validator.messages.equalTo = "No silly, you're supposed to type the same set of characters AGAIN.";
});
</script>
<!-- Ignore my template -->
<apex:composition template="Template">
<apex:define name="title">
<a href="http://thesilverlining-developer-edition.na7.force.com/jqueryvalidatedemo/">jQuery Forms Validation Demo</a>
</apex:define>
<apex:define name="blurb">
<p>
Fiddle with the form entering combinations of correct and incorrect values to see the validation rules in action. Hitting
the sumbit button will also trigger form checking.
</p>
</apex:define>
<apex:define name="content">
<apex:outputPanel layout="block" style="text-align:center; font-size:12px;padding: 4px">
<apex:form id="commentForm">
<apex:outputlabel for="name">Name
<span class="star">*</span>
</apex:outputlabel>
<apex:inputtext id="name" value="{!account.name}" />
<br/>
<apex:outputlabel for="email">E-Mail
<span class="star">*</span>
</apex:outputlabel>
<apex:inputtext id="email" value="{!account.name}" />
<br/>
<apex:outputlabel for="url">URL (optional)</apex:outputlabel>
<apex:inputtext id="url" value="{!account.name}" />
<br/>
<apex:outputlabel for="comment">Your comment
<span class="star">*</span>
</apex:outputlabel>
<apex:inputtextarea id="comment" value="{!account.name}" style="width: 30%" />
<br/>
<apex:outputLabel for="pwd">Password
<span class="star">*</span>
</apex:outputLabel>
<apex:inputSecret id="pwd" value="{!account.name}" />
<br/>
<apex:outputLabel for="cpwd">Confirm Password
<span class="star">*</span>
</apex:outputLabel>
<apex:inputSecret id="cpwd" value="{!account.name}" />
<br/>
<input type="submit" />
</apex:form>
</apex:outputPanel>
</apex:define>
</apex:composition>
</apex:page>
Falling in love with JQuery aren’t you? Well I have to admit it’s a neat and clear way of validating forms.
Good post again!
/MRG
In a big way 🙂 Thanks bud.
Nice post, Wes.
Thanks Mz J.
Awesome example. I’m gonna sit down tonight and bang out this code. Thanks, you are a peach.
Cheers ol’ chap.
Great post as always and much love for jQuery.
I’ve got so many jQuery + salesforce blog posts in the works it’s a little ridiculous…..ridiculously awesome.
RAWesome? Thank Tehnrd.
Sweet! Need to play with JQuery asap.
I can’t wait to jump on this bandwagon.
I can’t believe. Is it really that simple?
Indeed! jQuery is simple and powerful.
Great Post!
Very cool stuff!
Although I would add that you should always do the server side validation as well since it’s easy for malicious users to by pass any javascript validation, but thats just a matter of using the declarative interface to write the same rules that are implemented in the javascript.
Indeed! Very good advice.
I’m confused. Isn’t protecting against malicious users a simple matter of appropriately escaping things before they go into query strings? If it is bad/fake data you are worried about, there is no way to protect against it that I know of.
I am not sure that Scott necessarily meant someone trying to inject SOQL or something like that. It seems like his concern is with someone sidestepping the validation to put in any garbage data they want into a text field. You’d be duplicating your efforts to create client side and server side validation to guard against improperly formatted data.
In that case, I’m planning to develop a standard JQuery library for all standard fieldTypes in SFDC, to make the validation easier. Hopefully I’ll be able to integrate it w/ the form generation included in CMSForce.
Hi –
Thanks for the providing neat and clear solution on the validation.
I am trying this and having some road blocks. Can some one please address where the issue is?
This is the one i am trying.
I am receiving error: Static Resource JQuery not found
and sometimes
unexpected token: ” at line 0 column -1.
Please advise.Thanks
$(document).ready(function()
{
$(jq(f)).validate();
$(jq(vendor_meet)).rules(“add”,{
required: true
});
jQuery.validator.messages.required = “Please enter a value”;
jQuery.validator.messages.equalTo = “You have to enter a value. Please!!!”;
});
var vendor_meet = “{!$Component.vendor_meet}”;
Vendor (required)
function jq(myid)
{
return ‘#’ + myid.replace(/(:|\.)/g,’\\\\$1′);
}
var f = “{!$Component.commentForm}”;
Yes, you must create a static resource with the JQuery library.
For example:
there is a static resource called jquery that contains the Jquery library.
Cheers.
Wes,
Really digging this jquery form validation functionality! However, I’m having issues getting it to work. I’ve combed through my code dozens of times and it appears to look correct per the sample code on this post. I’ve also checked my VF Id’s using Firebug and the problem doesn’t appear to lie there. But when I submit my form – voila! it submits without any validation.
My page does reference other libraries like Mootools so I’m wondering if it has something to do with that. Anyone else have problems while using multiple js libraries on one page?
Thanks!
Hey Clint
Other libraries can cause conflicts (it’s usually a namespace thing), Tehnrd has a good article detailing the fix, you can get it here: http://www.tehnrd.com/setting-up-jquery-with-salesforce-com/.
Awesome! You’re the man. I just had to add the following:
var j$=jQuery.noConflict();
then change my $ to j$.
Working like a charm. Thanks to you and Jason (@tehnerd)
I’m late to the party, but this is exactly what I was looking for. Thanks!
There seems to be an error in the following portion. Spent a lot of time tracking this one down. I feel like an idiot.
return ‘#’ + myid.replace(/(:|\.)/g,’\\$1′);
should be
return ‘#’ + myid.replace(/(:|\.)/g,’\\\$1′);
It is correct in your actual example, but not in the above text.
Thanks for that, WordPress messes around with my markup, especially in this example because of all the JS :\
On a side note, I’ve found that on some of the servers you only need ‘\\’ while on others you’ll nee ‘\\\’. It’s a lovely inconsistency, but if you know what to look for when problems occurs it’s quick to find.
Only wanna tell that this is invaluable , Thanks for taking your time to write this.
Cheers mate.
FROM: http://www.salesforce.com/us/developer/docs/pages/Content/pages_variables_global.htm
If your component is nested, you must declare the entire component tree.
For example:
“{!$Component.theBlock.theSection.theSectionItem.text}”
This is true but it’s not the only way and if fact it’s quite brittle as discussed here: http://th3silverlining.com/2009/06/17/visualforce-component-ids-javascript/.
First off, thanks for the write up, time and effort.
Yea, the down side to the document.getElementById method is that it has to be at the same level as the object in question. This leads to having to maintain script sections at each level to be ‘dynamic’ vs. having to maintain the full component tree.
I am trying to get this to work and my first problem was that my ID’s were not pulling back. Now they are pulling correctly and so I thought I would share the ‘fix’ for that since your example doesn’t have as many levels as mine.
It still doesn’t appear to be working in my sandbox though.
Correct, neither method is perfect unfortunately, c’est la vie. Some people prefer one method to another. I know that my friend Jason (tehnrd) does not dig my approach.
Recently I’ve been thinking that we should just wildcard our jQuery selectors, you can give this a bash as shown here:http://james.padolsey.com/javascript/regex-selector-for-jquery/
If we were to use this approach we could give our visualforce element of id=”el-id” and then select it in jQuery using something like $(‘*el-id’).
Good luck.
Please, do not approve my previous post. but, approve this one:
I get no validation messages. Not sure why?
$(document).ready(function() {
/* Note: The jq() function is explained @ http://wp.me/pxPpB-8B */
$(jq(f)).validate();
$(jq(name)).rules(“add”,{
required: true,
minlength: 2
});
$(jq(email)).rules(“add”,{
required: true,
email: true
});
$(jq(url)).rules(“add”,{
url: true
});
$(jq(comment)).rules(“add”,{
required: true
});
$(jq(password)).rules(“add”,{
required: true,
minlength: 5
});
$(jq(cpassword)).rules(“add”,{
required: true,
minlength: 5,
equalTo: jq(password)
});
/* Customised the messages */
jQuery.validator.messages.required = “You better have entered a value.. or else!”;
jQuery.validator.messages.equalTo = “No silly, you’re supposed to type the same set of characters AGAIN.”;
});
var name = “{!$Component.name}”;
Name
ATS Journal Type
Active
Refundable
Refund pro-Rate
Disallow Person Account Purchase
Disallow Standard Account Purchase
Allow Line Description Input
Staff Only
Non-Standard Product
Purchasable
Opt Out Allow
Allow Multiple Quantity Purchase
Allow Price Adjustments
Allow Price Write-Off
Require Approval
Journal Issue #
Journal Volume
U.S. Price
International Price
Journal Issue Date
Purchasable Expiration Date
Quantity Ordered
Quantity Limitation
Product Description
Allow Nation Group
Product Group
Product Family
Dynamics GP Batch ID Prefix
Credited General Ledger Account
function jq(myid){
return ‘#’ + myid.replace(/(:|\.)/g,’\\$1′);
}
var f = “{!$Component.atsJournalEntryForm}”;
Looks like your markup has been stripped out. I’m going to delete your comment but if you could post in the SFDC developer forums and post a link here I’ll take a look.
Hi
First of all thanks for sharing the great piece of work .!
I am trying to use this in a visual force page. I am getting an error at the validate() function and it says “Unspecified”.
I have included the static resources as mentioned by your blog.
Notifiably, I have other java script and jquery methods are working fine.
I do not understand why it was not working for me..
Please help me
Thanks
Sai.
Has anyone tried this with apex:inputField’s ? How do we handle the lookup icon/image when a jquery validation messages is added to these fields?
The jQuery validation message renders after the form input field. In the HTML layout structure, the validation message is inserted between the the text field and the lookup icon. For me, this has become a CSS mess as I have the lookup icon moving around, or being placed behind the validate message, or my validate messages have issues if they need to line wrap. Everything regarding jQuery validation was fine until I came across forms that use lookup (inputField) in them. jQuery validate continues to work, but the presentation has become somewhat tricky.
Hopefully someone who is using this method with inputFields in their forms has some ideas.Thanks.
i get no validation messages.. i already uploaded the static resources, copied your code, and still couldn’t make it work.. please help..
What i’d like to know is if there is a way to use something like Jquery Tools (with a much nicer validation graphics) – i can’t seem to figure out how to add the required=”required” attribute to an necessary to trigger validation on that plugin…
to an *inputfield* necessary… stripped out my tags
I’m sorry I don’t know what you’re asking. This post details how to use validation and it seems that’s what you’re asking?
I’ve simplified the code significantly, have another read through 🙂
What i’d like to know is if there is a way to use something like Jquery Tools (with a much nicer validation graphics) – i can’t seem to figure out how to add the required=”required” attribute to an necessary to trigger validation on that plugin…
to an *inputfield* necessary… stripped out my tags
I’m sorry I don’t know what you’re asking. This post details how to use validation and it seems that’s what you’re asking?
I think u can just use styleclass=”required” instead
I’ve simplified the code significantly, have another read through 🙂
What i’d like to know is if there is a way to use something like Jquery Tools (with a much nicer validation graphics) – i can’t seem to figure out how to add the required=”required” attribute to an necessary to trigger validation on that plugin…
I’m sorry I don’t know what you’re asking. This post details how to use validation and it seems that’s what you’re asking?
I think u can just use styleclass=”required” instead
Where does the save() method get called?
It’s called by the commandbutton.
In your “full” code block, I don’t see a commandbutton. It looks like you substituted it with a standard submit button.
That is true. It is shown in the code within the post although I can see how that might be confusing.
Where does the save() method get called?
It’s called by the commandbutton.
Where does the save() method get called?
We are using tabpanel to create a multi tab form. we have the form and tabs all worked out with next command buttons on each tab and submit on last tab. How can we get a “next tab” commandbutton to fire the validation on the fields if it is not a submit button? any ideas?
we will be using validations ignore function to avoid validating other tabs fiels, so that is not an issue, just how to fire the validation with the “next” commandbutton
Got this to work by adding submit event to onclick.
We are using tabpanel to create a multi tab form. we have the form and tabs all worked out with next command buttons on each tab and submit on last tab. How can we get a “next tab” commandbutton to fire the validation on the fields if it is not a submit button? any ideas?
we will be using validations ignore function to avoid validating other tabs fiels, so that is not an issue, just how to fire the validation with the “next” commandbutton
Got this to work by adding submit event to onclick.
We are using tabpanel to create a multi tab form. we have the form and tabs all worked out with next command buttons on each tab and submit on last tab. How can we get a “next tab” commandbutton to fire the validation on the fields if it is not a submit button? any ideas?
we will be using validations ignore function to avoid validating other tabs fiels, so that is not an issue, just how to fire the validation with the “next” commandbutton
This technique looks like it will save a lot of trouble – if I can get it to work for me. I’m currently getting a “element is undefined” (according to Firefox) error on the jquery validate script. I’m current loading the jquery code via these lines:
I’m using jquery 1.3.2 and the jquery validate plugin 1.6 (same as in this example).
Any ideas on what I’m doing wrong would be welcome.
Is the following page structure critical to this technique?
…
My form isn’t wrapped by a define or an output panel.
You code has been stripped out. If you link to a live example or github gist/typepad I’ll have a look.
I’ve added this question (with the code blocks) to the Developerforce Visualforce board. Here’s the link:
http://boards.developerforce.com/t5/Visualforce-Development/Getting-JQuery-validation-working-in-Saleforce/td-p/421625
That post also links back to this page.
Has anyone gotten jquery validation to work with apex:selectRadio or checkbox?
Has anyone gotten jquery validation to work with apex:selectRadio or checkbox?
Hey! Thank you for taking the time to write this as well as address a few people’s questions/comments.
I too am having trouble getting this to work and posted a follow up question to Bruce Perry’s post: http://boards.developerforce.com/t5/Visualforce-Development/Getting-JQuery-validation-working-in-Saleforce/m-p/421625/highlight/false#M48631
I could really use someone’s help on this as I am not at all a js/jquery jedi master.
Hey! Thank you for taking the time to write this as well as address a few people’s questions/comments.
I too am having trouble getting this to work and posted a follow up question to Bruce Perry’s post: http://boards.developerforce.com/t5/Visualforce-Development/Getting-JQuery-validation-working-in-Saleforce/m-p/421625/highlight/false#M48631
I could really use someone’s help on this as I am not at all a js/jquery jedi master.
Hey! Thank you for taking the time to write this as well as address a few people’s questions/comments.
I too am having trouble getting this to work and posted a follow up question to Bruce Perry’s post: http://boards.developerforce.com/t5/Visualforce-Development/Getting-JQuery-validation-working-in-Saleforce/m-p/421625/highlight/false#M48631
I could really use someone’s help on this as I am not at all a js/jquery jedi master.
Hi,
This is a great article. Is the template you used available for reference as well?
Thanks!
Hi,
This is a great article. Is the template you used available for reference as well?
Thanks!
Please Provide me Jquerry Static Resource link for download
Thanks for the great article. I was able to implement successfully. But I am trying to have the error message in the container rather having the error message next to the field. Any thoughts around that?