How can I add a mask to format a form input?

Sometimes it would be helpful to control the format of an entry in a text input to make sure that it is a date, or a money amount, or a credit-card number, . . . To do this we can add ‘masks’ to the input which will only allow certain kinds of input. This FAQ explores how to use the MeioMask library to do this. 
The MeioMask library is a MooTools library written by Fábio Miranda Costa to do just this task. The library is available from his GitHub account. There is also a jQuery version of the library but I have not yet looked at that.

The MeioMask library has very little documentation so this FAQ is mostly written from trial and error and may not be complete or correct!

Install the library on your site

First download the Zip package from GitHub; unzip it and dig down to the Sources folder where you will find six files with names like Meio.Mask.xxx.js 
Copy all of these files to your website. I added them to the /components/com_chronoforms/extras/meio_mask/ folder.
We will need to load some or all of these into out form using a Custom Code action in the form On Load event.
<?php
JHtml::_('behavior.framework', true);
$doc =& JFactory::getDocument();
$url = JURI::root().'components/com_chronoforms/extras/meio_mask/';
$doc->addScript($url.'Meio.Mask.js');
$doc->addScript($url.'Meio.Mask.Extras.js');
$doc->addScript($url.'Meio.Mask.Fixed.js');
$doc->addScript($url.'Meio.Mask.Regexp.js');
$doc->addScript($url.'Meio.Mask.Repeat.js');
$doc->addScript($url.'Meio.Mask.Reverse.js');
?>
The main Meio.Mask.js file is always needed, Extras probably is; if any of the others are not needed in your application then you can comment out those lines.

The built-in masks

Fixed

The Fixed library includes mask used for fixed values like date, time, phone, etc. Here are the built-in masks:
  • Brazilian Phone [Phone]: '(99) 9999-9999'
  • US Phone [PhoneUs]: '(999) 999-9999'
  • Brazilian CPF [Cpf]: '999.999.999-99'
  • Brazilian CNPJ [Cnpj]: '99.999.999/9999-99'
  • Date [Date]: '3d/1m/9999'
  • US Date [Dateus]: '1m/3d/9999'
  • Brazilian CEP [Cep]: '99999-999'
  • Time [Time]: '2h:59'
  • Credit Card [Cc]: '9999 9999 9999 9999'
  • MAC address [Mac]: 'HH:HH:HH:HH:HH:HH'
In each of these the text in square brackets [] is the code used to identify the mask and the last string shows the mask format.
As you can see these masks use pre-defined characters to define the allowable entries: e.g. 9 is a digit, H is a hex digit, 1m is a month, 2h is an hour and the punctuation cahracters :-/() are used to format the entry. 

As you may have noticed, Fábio Miranda Costa is Brazilian: CPF is a personal tax code; CHPJ a corporate one; and CEP a postcode.

Regexp

The Regexp library builds masks using Regular Expressions which are more flexible, but can be more complex to build. There are just three built in masks: IP address [ip], IPv6 address [ipv6] and Email [email].

Repeat

The Repeat library provides a set of masks that limit the kind of character that is allowed and the number of times it can be repeated. So, for example you call set H and 7 to set a mask of seven Hexadecimal characters.

The available characters 'kinds' are:

  • z: a-z
  • Z: A-Z
  • a: a-zA-Z
  • *: 0-9a-zA-Z
  • H: 0-9a-fA-F
  • @: 0-9a-zA-ZçáàãâéèêíìóòõôúùüñÇÁÀÃÂÉÈÊÍÌÓÒÕÔÚÙÜÑ
  • h: 0-9 max 23
  • d: 0-9 max 31
  • m: 0-9 max 12
  • 1: 0-1
  • 2: 0-2
  • . . .
  • 9: 0-9

You can see that these character 'kinds' match up with the codes used in the Fixed Group above.

Reverse

The Reverse library is so named because the inputs they mask are mostly numbers and they are entered at the right of the input box. The built-in set of masks are:

  • Integer [Integer]: 999.999
  • Integer US [IntegerUs]: 999,999
  • Decimal [Decimal]: 999.999,00
  • Decimal US [DecimalUs]: 999,999.00
  • Reais [Reais]: R$ 999.999,00
  • Euro [Euro]: € 999.999,00
  • Dollar [Dollar]: US$ 999,999.00

Note that the default values are Brazilian with . and , as the separators. Each of these masks has a default maximum length of 18 characters, including separators e.g. 999.999.999.999,99

Using the masks

The mask libraries are built to use the data- attributes of a form input, so if you want to add, for example, a 'time' mask you can do it by adding data-meiomask='fixed.time' to a text input on my form like this:

<input name='time' type='text' data-meiomask='fixed.time' />
And, if the mask has options then you can add those in the same way using the data-meiomask-options attribute (this example  creates a mask that will accept up to eight digits with values from 0-4 e.g. 01234432):
<input name='repeat' type='text' data-meiomask='repeat' data-meiomask-options="{mask: '4', maxLength: 8}"  />

Unfortunately the current version of ChronoForms doesn't make it easy to add data attributes to form elements in the Form Wizard (unless you use the Custom Element element and add your own HTML).

Fortunately there are some other methods that we can use using JavaScript to add the validations.

If you just have a few validations to apply then you can attach them individually to inputs. Please first add a unique id to each element (in most cases this can be the same as the element name e.g. amount). Then to mask an input we can use a Load JS action and add JavaScript like this to mask the input as a US formatted number with two decimal places:

window.addEvent('domready', function() {
  $('amount').meiomask('Reverse', 'DecimalUs');
});

Note: the first and last lines only needed to be used once to wrap all of the JavaScript in a Load JS action. We'll leave it out of the following examples.

Or if we want to add a US$ prefix we can use this version:

window.addEvent('domready', function() {
  $('amount').meiomask('Reverse', 'DecimalUs');
});

Or we can use a third parameter to set a custom option for this Mask:

window.addEvent('domready', function() {
  $('amount').meiomask('Reverse', 'DecimalUs', {symbol: '£'});
});

These three parameters: the Mask Library, the Mask Preset and the Mask Options let us define a wide range of masks. There  is more about the Mask Options in the next section.

If you have several elements in your form that you want to format the same way for example, a group of amount elements, then there is a short-cut way to add Masks. You need to add a class to each element in the group like, say, 'dollar_amount'. Then JavaScript like this can add the same Mask to all of the elements with this class set.

window.addEvent('domready', function() {
  $$('input.dollar_amount').each(function(item) {
    $(item).meiomask('Reverse', 'Dollar');
  });
}); 

Meio Mask options

We've seen a couple of examples of setting Mask Options, in this section I've added a list of the available options that I have found.

See the sections above for examples of setting options. 

Fixed

The Fixed library has four options:

  • autoSetSize: defaults to false; I'm not sure what it does
  • placeholder: defaults to '_'; sets the 'placeholder' character where data will be entered e.g. __:__ for time
  • removeIfInvalid: defaults to false; removes the value onblur if the input is not valid
  • removeInvalidTrailingChars: defaults to true; cleans up any extra input

Regexp

This library only has one option regexp: which sets the regular expression to use.

Repeat

  • mask: defaults to an empty string; see the section above for allowable 'kinds'
  • maxLength: defaults to 0 which sets no limit; enter an integer to set a maximum length

Reverse

  • autoSetSize: defaults to false; I'm not sure what it does
  • autoEmpty: defaults to false; I'm not sure what it does
  • alignText: defaults to true;, I think this right-aligns the input content
  • symbol: defaults to an empty string; sets the currency symbol
  • precision: defaults to 2; sets the number of places after the decimal point
  • decimal: defaults to comma , ; sets the character used as the decimal point
  • thousands: defaults to stop . ; sets the character used to separate thousands
  • maxLength: defaults to 18; sets the maximum length (including separators and the decimal point)
Note: I think that there is a small bug with the symbol character. Both 'A$ ' (with a trailing space) and '$' (with no space) work OK, but '$ ' with a trailing space misplaces the symbol.

Creating custom masks

The examples above showed how to use the preset masks and also how to use the options parameter to over-ride the default options for that preset. You can also create new masks with your own preferred options using the createMask class.

Reverse

Here's an example of a new Reverse library mask: 

Meio.Mask.createMasks('Reverse', {
  'Adollar': {
    precision: 0,
    maxLength: 10,
    symbol: '$',
    thousands: ','
  }
});

The first line Meio.Mask.createMasks('Reverse', { tells Meio Mask that this is a new Mask using the Reverse library.

The next line sets the name for the new Mask 'Adollar' in this example.

The remaining lines specify the options for this mask: it has no decimal places; uses a comma as the thousands separator; shows '$' as the symbol and allows 10 characters - as this includes the separators the maximum amount is 99,999,999.

Once this Mask is defined we can apply it in exactly the same way as the preset masks:

$('input_name').meiomask('reverse', 'Adollar'); 

Regexp

Here's another example, this time for a Regexp library mask, the mask is for a British VAT (sales tax) number which has is a 9 or 12 digit number with an optional GB prefix. 

Meio.Mask.createMasks('Regexp', {
    'VatGB': {regex: /^(GB)?([0-9]{9}([0-9]{3})?|[A-Z]{2}[0-9]{3})$/}
});

As before, once the mask is created you can use it with any text input:

$('input_name').meiomask('regexp', 'VATGB'); 

Note: see the Regular Expression Library at RegExpLib.com for many more useful examples of regular expressions that you can use or adapt.

 

WORK IN PROGRESS - TO BE CONTINUED


 

Category: CFv4 Validation

Comments:

You need to login to be able to post a comment.