I am a developer and (at least as often) a (l)user. UI and UX design are important from both perspectives, and it’s important to bear this in mind whilst creating any application. What is this waffle all about? There are some platforms, based in yonder cloud that could tweak the tiniest of features, and make the lives of their users (and administrators) 1 x shed-load better. Until they do that, we’re gonna have to do it ourselves.
Let’s get specific. Typically, validation error messages provided by Apex and VisualForce are only apparent after form is submitted ( or when we’re on the last page of a 39-page wizard ). Of course some cases require that it be this way, but for other cases it’s like my (very) old professor used to say, “Jus’ don’t let em make the mistake in the first place boy *tongue-click*”. Heeding Prof. Swart’s advice, let’s see how we can easily do this.
We’re going to use jQuery and one of it’s plugins to help us out. It’s free and it makes JavaScript fun (hard to believe isn’t it?). First you’ll need to upload the static resources required,
jQuery min and,
Digital Bush’s Masked Input Plugin
And you’ll have to include them in your page,
[code language=”java”]
<apex:includeScript value="{!$Resource.jquery}"/>
<apex:includeScript value="{!$Resource.jMaskedInput}"/>
[/code]
Next, let’s have a look-see at the inputs we’ll be using in our demo,
[code language=”java”]
<apex:form >
<!– I’ve attached the jQuery to the fields using classes.
This avoids the awkward issue of dealing with SF generated
ids. The performance impact should be negligiable as long as
your page is not massive. –>
<apex:outputLabel for="tel" value="Telephone"/>
<apex:inputText id="tel" styleClass="tel-mask"/>
<apex:outputLabel for="dbl" value="Double" />
<apex:inputText id="dbl" styleClass="dbl-mask"/>
<apex:outputLabel for="date" value="Date" />
<apex:inputText id="date" styleClass="date-mask" />
<apex:outputLabel for="misc" value="Misc" />
<apex:inputText id="misc" styleClass="misc-mask" />
</apex:form>
[/code]
And as a last step, let’s attach the masks to the inputs,
[code language=”javascript”]
<script>
$(document).ready(function() {
// Attach masks to correct input fields
$(".tel-mask").mask("(999) 999-9999");
$(".dbl-mask").mask("999 999 999.99");
$(".date-mask").mask("99/99/9999");
$(".misc-mask").mask("**-aa-a9-9a-99");
});
</script>
[/code]
Now wasn’t that more laughs than a barrel full of monkeys (I’ve never understood this saying, monkeys used to sneak into my home and steal my bananas. THERE’S NOTHING FUNNY ABOUT BANANA THEFT). Righty-o.. so what do we have here then? Well, our users can’t make mistakes*, and… what’s that Watson? That’s right, we can mimic <apex:inputField> type-restrictions when entering data on <apex:inputText> fields! Can I get five up high!
As fantastically-smashing as this is, I have one request, I’d like to have the mask placeholders ( by default ‘_’ ) be different for alphas and chars. I’ve asked the developer if he’d consider doing this, so let’s see what he says.
In the meantime, you can view the above code as a live demo.
* Disclaimer: I cannot actually guarantee this.
Very cool Wes. I hope you continue to do more jQuery stuff. I’m really lacking it in and could use the help. I look forward to more examples!
Very cool Wes. I hope you continue to do more jQuery stuff. I’m really lacking it in and could use the help. I look forward to more examples!
Triple A post! (Awesome As Always).
jQuery is fanfreakingtastic and I have several posts lined up that deal specifically with jQuery but I am also working on a Batch Apex best practices post. what should come first?!?! Decisions, decisions.
Also, looks like some of your markup got killed in the code sections.
Thanks Mr TehNrd. I find that the code section often munches up some of my tags.. in fact this is the third time I’ve fixed this post, curious..
Looking forward to the posts, let’s show these YUI, MooTools, extJs and Prototype kids how it done 😉
Triple A post! (Awesome As Always).
jQuery is fanfreakingtastic and I have several posts lined up that deal specifically with jQuery but I am also working on a Batch Apex best practices post. what should come first?!?! Decisions, decisions.
Also, looks like some of your markup got killed in the code sections.
Thanks Mr TehNrd. I find that the code section often munches up some of my tags.. in fact this is the third time I’ve fixed this post, curious..
Looking forward to the posts, let’s show these YUI, MooTools, extJs and Prototype kids how it done 😉
Mindblowing!!!!
I have never seen such thing done on a Visual Force page!!!
Thanks
Great post and cool way to prevent users from writing weird values. But the problem is adding external javascript to Salesforce pages can lead to some problems. Indeed Salesforce uses extJs internally (and “might” open it to general use) and uses some weird javascript for Ajax and validation in general. So I’m not too keen on adding lots of external javascript library. You never add any problem on your side?
/MRG
Very true with alot of JS libraries and frameworks but since jQuery has it’s own namespace it *should* not conflict with ExtJs. Personally I use it extensively in my user interfaces, attaching events to commandButtons and commandLinks and I have never had any sort of conflict-related issue. jQuery also has some docs on the topic: http://docs.jquery.com/Using_jQuery_with_Other_Libraries
Great post and cool way to prevent users from writing weird values. But the problem is adding external javascript to Salesforce pages can lead to some problems. Indeed Salesforce uses extJs internally (and “might” open it to general use) and uses some weird javascript for Ajax and validation in general. So I’m not too keen on adding lots of external javascript library. You never add any problem on your side?
/MRG
Very Cool WesMan!
Some very good points and some nice dev to back it up!
I totally agree with you about validation rules I wish there was a real time validation check option for the visualforce inputfield component that could granularly check field xyz. Also with apex error messages handling would be cool if there was a way to assign multiple messages based on user profile or something. I.e show admin or dev, ‘tried to de-ref null etc etc’ but to the user ‘there was an error saving the opportunity, an email has been forwarded to your support team’.
JQuery for me is goes hand in hand with VF. It would be cool if jQuery somehow could be integrated into VF in some way for managing real-time stuff/ UI / Effects.
Cameron
Very Cool WesMan!
Some very good points and some nice dev to back it up!
I totally agree with you about validation rules I wish there was a real time validation check option for the visualforce inputfield component that could granularly check field xyz. Also with apex error messages handling would be cool if there was a way to assign multiple messages based on user profile or something. I.e show admin or dev, ‘tried to de-ref null etc etc’ but to the user ‘there was an error saving the opportunity, an email has been forwarded to your support team’.
JQuery for me is goes hand in hand with VF. It would be cool if jQuery somehow could be integrated into VF in some way for managing real-time stuff/ UI / Effects.
Cameron
Wes,
Good stuff. I can get this to work when opening a VF page in SF, but not from my SF Site. It’s not a browser issue, as I can view/use the demo page on your SF site just fine. Any ideas?
Also, when I reRender a section of the page that has a field with a Mask associated with it, the mask is lost. Any ideas here?
I figured out why they wouldn’t work on my SF Site. The static resources have to be set to public, and they were not.
However, the disappearance of the mask on reRender is still an issue. Any thoughts?
Good job troubleshooting the first issue 🙂 Because you’re reloading the page DOM you’ll either need to call the JavaScript again from somewhere inside the reRendered area, or you can put the JS call in it’s own area and wrap it in some Visualforce and tell the reRender to reload both areas i.e. reRender=”myBlock, myJavaScript”
I had this problem and fixed it by putting all mask calls in one function and call that function onChange in any element that triggers rerender.
Hi BK, can you make a step-by-step on how to do this?
Wes,
Good stuff. I can get this to work when opening a VF page in SF, but not from my SF Site. It’s not a browser issue, as I can view/use the demo page on your SF site just fine. Any ideas?
Also, when I reRender a section of the page that has a field with a Mask associated with it, the mask is lost. Any ideas here?
I figured out why they wouldn’t work on my SF Site. The static resources have to be set to public, and they were not.
However, the disappearance of the mask on reRender is still an issue. Any thoughts?
I had this problem and fixed it by putting all mask calls in one function and call that function onChange in any element that triggers rerender.
Hi BK, can you make a step-by-step on how to do this?
Hello Wes! I’m pretty impressed with your carreer and with your blog. I’m working my ass off to become a good Salesforce professional, as you. I did read your book and I am really thankful to you for helping out community.
I’ve found out again your blog today looking for this specific topic – guess what – I tried to do it and it didn’t work.
Your visualforce page still works. Would you mind helping me out to find why is not working for me? I will go through the steps I did below:
1st – I’ve uploaded your JQuery min file to my static resource and named it jquery
2nd – I’ve uploaded Digital Bush’s code (jquery.maskedinput.js) to static resource and named it jMaskedInput
3rd – I’ve also uplodaded Digital Bush’s MIN code (jquery.maskedinput.min.js) to static resource and named it jMaskedInput2.
Here is my code:
$(document).ready(function() {
// Attach masks to correct input fields
$(“.tel-mask”).mask(“(999) 999-9999”);
$(“.dbl-mask”).mask(“999 999 999.99”);
$(“.date-mask”).mask(“99/99/9999”);
$(“.misc-mask”).mask(“**-aa-a9-9a-99”);
});
Any idea of why it doesn’t work?
Isn’t better using instead of ?
Thanks in advance for your time and patience!
$(document).ready(function() {
// Attach masks to correct input fields
$(“.tel-mask”).mask(“(999) 999-9999”);
$(“.dbl-mask”).mask(“999 999 999.99”);
$(“.date-mask”).mask(“99/99/9999”);
$(“.misc-mask”).mask(“**-aa-a9-9a-99”);
});
This doesn’t seem to work for me. what am I missing?
I added and named the static resources as above. Here’s my simple VF page:
$(document).ready(function() {
// Attach masks to correct input fields
$(“.tel-mask”).mask(“(999) 999-9999”);
$(“.dbl-mask”).mask(“999 999 999.99”);
$(“.date-mask”).mask(“99/99/9999”);
$(“.misc-mask”).mask(“**-aa-a9-9a-99”);
});
any suggestions?
Not working for me