0

We currently use the following logic to mask the inputs:

  1. Set a specific class to several inputs <input type="text" class="typenumdec" />

  2. In document.ready() bind a propertychange event with the rules:

    $('table tbody > tr > td.tiponumdec').children('input[type=text], input[type=number]')
            .add('input[type=text].tiponumdec, input[type=number].tiponumdec').bind('input propertychange', function () {
            $(this).val($(this).val().replace(/[^0-9,]/g, ''));
        });
    

But we wanted to centralize the logic and make it more streamlined for our developers so they dont have to add/modify the bindings.

Something like this:

  1. Developer defines somewhere the format and its name (javascript globals? key/value array?):

    var formatmoney1 ='5.2'; //5 integers and 2 decimals

    var formatmoney2 ='5.3'; //5 integers and 3 decimals

    var formatdays ='3'; //3 integers

  2. Developer sets the format to a data-atribute or css class (recommended option?)

    <input type="text" class="formatmoney1" data-formatx="formatmoney1" />

  3. On document.ready() a generic function parses the format definitions and the inputs in order to mask them depending on its assigned format

PS: we saw this plugin that seems interesting in order to cover part of the mask logic (your opinions?): http://igorescobar.github.io/jQuery-Mask-Plugin/

techfoobar
  • 65,616
  • 14
  • 114
  • 135
VSP
  • 2,367
  • 8
  • 38
  • 59
  • What are the system requirements? Can you use HTML5 for example? – Patrick Hofman Jan 14 '14 at 09:50
  • If you use Bootstrap, the excellent Jasny Bootstrap add-on has a configurable input mask which may fit your needs. http://jasny.github.io/bootstrap/javascript/#inputmask. If you wanted you could use something like KnockoutJS to dynamically bind the HTML attributes to an easily accessible variable in Javascript land – Adam Marshall Jan 14 '14 at 09:58
  • @PatrickHofman yes, we currently use HTML5, JQuery 2.0.3, JQueryUI 1.10.3, Twitter Bootstrap 3.0.3, ASP.NET with Framework 4.5 – VSP Jan 14 '14 at 16:24
  • @AdamMarshall interesting, your tip would accomplish the third point, could you add an answer with an example code that meets the 3 points we outlined in the question? – VSP Jan 14 '14 at 16:30
  • 2
    It is interesting to imagine the value of stackoverflow reputation. Here the OP is asking for a prototype of a system, something that they might normally need to hire a freelancer for. How many minutes will it take for an SO regular to post a solution? How many dollars per hour would that user normally charge? Is 50 reputation worth $50 or $0.50 – Ziggy Jan 15 '14 at 09:27
  • @Ziggy not sure if this is the place to do a philosofical debate about the worth of SO reputation...Also nobody is forced to reply the question if he doesnt like the reward. Offer and demand market and so. I asked this as it seemed that after searching there wasnt a streamlined/standard way of doing it, and could be useful to more people that usually encounters with this requirement/need. – VSP Jan 19 '14 at 13:52

3 Answers3

1

We are currently using HTML 5 to make 99% of all validations. You can use them in a very understandable and developer-friendly way.

For example this code will prevent entering everything else then an email address:

<input type="email" />

Or use this with custom regex:

<input type="text" name="dutch_zip_code" pattern="[A-Za-z]{4}[0-9]{2}" />

You can also set the pattern in javascript / jquery like this:

<html>
<head>
  <script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
  <script type="text/javascript" src="jquery.mask.js"></script>
</head>
<body>
<input type="text" name="dutch_zip_code" data-validation-type="dutch_zip_code" />

<script>
$(document).ready(function()
{
    $('input[type=text]').each( function()
                           {
                               var type = $(this).data('validation-type');

                               if (type == 'dutch_zip_code')
                               {
                                   $(this).attr('pattern', '[A-Za-z]{4}[0-9]{2}');
                                   //
                                   // Use jquery mask plugin:
                                   // https://plugins.jquery.com/mask/
                                   //
                                   $(this).mask('0000SS');
                               }
                           }
                         );
});
</script>
</body>
</html>

You can use modernizr for backwards compatibility.

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
  • As using standards is good but its preferable a mask solution (so the user cannot even input the incorrect value). – VSP Jan 15 '14 at 09:17
  • The jquery example provides a good hint though, maybe if you can change your code so it uses some mask jquery plugin (or custom javascript mask function) + a javascript array variable that holds the maskname/maskpattern values and applies them in the .each function i will grant you the bounty ^^ – VSP Jan 15 '14 at 09:23
  • @ase69s: Ofcouse I can, but the new HTML5 way of working will do the same. I will take a look for you. – Patrick Hofman Jan 15 '14 at 09:26
  • I tried some websites with the new html5 "pattern" atribute and it let me input incorrect caracters and exceed field size...it only outlined the error after focusing out of the field or when clicking the submit button...example websites: http://www.wufoo.com/html5/attributes/10-pattern.html http://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_input_pattern – VSP Jan 15 '14 at 14:11
  • @ase69s: I posted a full working example. Can you please confirm this is according your wishes? – Patrick Hofman Jan 17 '14 at 14:00
  • Sorry for the delay, eventful week :S, yes the example will do fine with some touches according to our enviroment, thanks... – VSP Jan 19 '14 at 13:47
0

As mentioned in comments, if you use bootstrap (http://getbootstrap.com/), there is the excellent Jazny Bootstrap (http://jasny.github.io/bootstrap/) plugin which makes input masks extremely easy and tidy.

Here is a fiddle which demonstrates your 3 formats: http://jsfiddle.net/JNfxa/9/

Here is the HTML:

<label>formatmoney1</label>
<input type="text" class="form-control" data-mask="99999.99" data-placeholder=" ">
<label>formatmoney2</label>
<input type="text" class="form-control" data-mask="99999.999" data-placeholder="0">
<label>formatdays</label>
<input type="text" class="form-control" data-mask="999" data-placeholder="#">

And that is it, no extra CSS or JS required.

I have used three different examples for the data-placeholder attribute, this is the character that appears for the empty digits that the user must complete, default is '_'. Where I have used '9', this will restrict the user to enter a number, there are other options detailed here: http://jasny.github.io/bootstrap/javascript/#inputmask

Now, to centralise the data-mask to a single, maintainable variable, you could bind it to an observable ViewModel property using KnockoutJS. (http://knockoutjs.com/index.html)

You can do a lot more than this, but here is an updated fiddle: http://jsfiddle.net/JNfxa/11/

Now there is some JS, to declare our observable properties containing each of the masks:

vm = {};

vm.formatmoney1Mask = ko.observable("99999.99");
vm.formatmoney2Mask = ko.observable("99999.999");
vm.formatdaysMask = ko.observable("999");

ko.applyBindings(vm);

Knockout has an attr binding, which lets you bind the value of an observable property to a custom HTML attribute of your choice. More details here: http://knockoutjs.com/documentation/attr-binding.html

The HTML changes slightly to bind the data-mask attribute instead of setting it directly:

<label>formatmoney1</label>
<input type="text" class="form-control" data-bind="attr: { 'data-mask': vm.formatmoney1Mask }" data-placeholder=" ">
<label>formatmoney2</label>
<input type="text" class="form-control" data-bind="attr: { 'data-mask': vm.formatmoney2Mask }" data-placeholder="0">
<label>formatdays</label>
<input type="text" class="form-control" data-bind="attr: { 'data-mask': vm.formatdaysMask }"  data-placeholder=" ">

What's great about this, is you can update the mask observable on the fly, and the HTML will automatically update without refreshing the page, so you could have e.g. a radio button control to choose different input mask types.

Adam Marshall
  • 3,010
  • 9
  • 42
  • 80
0

I would HIGHLY recommend taking a look at this plugin- Robin Herbots inputMask

This plugin is robust, has alot of callbacks/options and is actively developed. One of the major advantages of this plugin are the extensions which is where you define masks and aliases.

You can define a mask however you want..if you wanted to extend the out of box decimal mask definition you could do it like this...

$.extend($.inputmask.defaults.aliases, 
{
  'formatmoney1': 
  {
            mask: "99999.99",
            placeholder: "_____.__",
            alias: "decimal"
  },
  'formatmoney2': 
  {
            mask: "99999.999",
            placeholder: "_____.___",
            alias: "decimal"
  }
}

Once you have defined your mask, and extended the out of box decimal definition then you could pick up all elements and apply the inputmask.

$(document).ready(function()
{
  $('.formatmoney1').inputmask('formatmoney1');
  $('.formatmoney2').inputmask('formatmoney2');
});

This mask allows you to have a very high amount of control through the numerous callbacks and is highly configurable by setting default options.

Another option you have with using this plugin is to take advantage of the data-inputmask attribute. For example,

<input type="text" data-inputmask="'alias':'formatmoney1'" />

Be sure you look through the Usage page as well as the extension files, there are a few of them but it looks like you will want to use the jquery.inputmask.numeric.extensions.js

Kevin
  • 2,752
  • 1
  • 24
  • 46