Masking Input on VisualForce Pages

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.

25 thoughts on “Masking Input on VisualForce Pages”

  1. 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.

    Reply
    • 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 😉

      Reply
  2. 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.

    Reply
    • 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 😉

      Reply
  3. 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

    Reply
  4. 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

    Reply
  5. 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

    Reply
  6. 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

    Reply
  7. 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?

    Reply
    • 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?

      Reply
      • 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”

        Reply
    • 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.

      Reply
  8. 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?

    Reply
    • 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?

      Reply
    • 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.

      Reply
  9. 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!

    Reply
    • $(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”);

      });

      Reply
  10. 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?

    Reply

Leave a Comment