Overview
JavaScript can be used to add a mask to an input field in a Dynaform. A mask is a pattern of characters, such as a phone number like (999) 999-9999
or a product code like aa-99a9
, that ensures that the user only inputs characters which conform to the pattern. Unlike the validate property, which checks whether the entered text conforms to the pattern after the focus leaves the field, masks work while the user is typing and are better at guiding the user to enter the proper input in the field.
Adding the Masked Input Code
Josh Bush's Masked Input plugin can be used to add masks to Dynaform fields. This code has an MIT license, which allows it to be incorporated into ProcessMaker without problems.
The Masked Input library can be incorporated into the Dynaform using one of these three ways:
Download the .js file by going to the Josh Bush's page, right-clicking and saving the Minified file.
A file named jquery.maskedinput.min.js will be downloaded. Place it in the public_html directory, which is typically found in the following location on the ProcessMaker server:
Linux manual install:
/opt/processmaker/workflow/public_html/jquery.maskedinput.min.jsLinux Bitnami install:
/opt/processmaker-3.X.X.b1-0/apps/processmaker/htdocs/workflow/public_html/jquery.maskedinput.min.jsWindows manual install:
C:\opt\processmaker\workflow\public_html\jquery.maskedinput.min.jsWindows Bitnami install:
C:\Bitnami\processmaker-3.X.X-1\apps\processmaker\htdocs/workflow\public_html\jquery.maskedinput.min.jsWindows automatic installer in version 3.0.17 and earlier:
<install-directory>\processmaker\workflow\public_html\jquery.maskedinput.min.jsThen, add the file named
jquery.maskedinput.min.js
to the Dynaform's external libs property, as shown in the image below:Copy and paste the following code (jquery.maskedinput.min.js's code) into the Dynaform's JavaScript property.
/*
jQuery Masked Input Plugin
Copyright (c) 2007 - 2015 Josh Bush (digitalbush.com)
Licensed under the MIT license (http://digitalbush.com/projects/masked-input-plugin/#license)
Version: 1.4.1
*/
!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof exports?require("jquery"):jQuery)}(function(a){var b,c=navigator.userAgent,d=/iphone/i.test(c),e=/chrome/i.test(c),f=/android/i.test(c);a.mask={definitions:{9:"[0-9]",a:"[A-Za-z]","*":"[A-Za-z0-9]"},autoclear:!0,dataName:"rawMaskFn",placeholder:"_"},a.fn.extend({caret:function(a,b){var c;if(0!==this.length&&!this.is(":hidden"))return"number"==typeof a?(b="number"==typeof b?b:a,this.each(function(){this.setSelectionRange?this.setSelectionRange(a,b):this.createTextRange&&(c=this.createTextRange(),c.collapse(!0),c.moveEnd("character",b),c.moveStart("character",a),c.select())})):(this[0].setSelectionRange?(a=this[0].selectionStart,b=this[0].selectionEnd):document.selection&&document.selection.createRange&&(c=document.selection.createRange(),a=0-c.duplicate().moveStart("character",-1e5),b=a+c.text.length),{begin:a,end:b})},unmask:function(){return this.trigger("unmask")},mask:function(c,g){var h,i,j,k,l,m,n,o;if(!c&&this.length>0){h=a(this[0]);var p=h.data(a.mask.dataName);return p?p():void 0}return g=a.extend({autoclear:a.mask.autoclear,placeholder:a.mask.placeholder,completed:null},g),i=a.mask.definitions,j=[],k=n=c.length,l=null,a.each(c.split(""),function(a,b){"?"==b?(n--,k=a):i[b]?(j.push(new RegExp(i[b])),null===l&&(l=j.length-1),k>a&&(m=j.length-1)):j.push(null)}),this.trigger("unmask").each(function(){function h(){if(g.completed){for(var a=l;m>=a;a++)if(j[a]&&C[a]===p(a))return;g.completed.call(B)}}function p(a){return g.placeholder.charAt(a<g.placeholder.length?a:0)}function q(a){for(;++a<n&&!j[a];);return a}function r(a){for(;--a>=0&&!j[a];);return a}function s(a,b){var c,d;if(!(0>a)){for(c=a,d=q(b);n>c;c++)if(j[c]){if(!(n>d&&j[c].test(C[d])))break;C[c]=C[d],C[d]=p(d),d=q(d)}z(),B.caret(Math.max(l,a))}}function t(a){var b,c,d,e;for(b=a,c=p(a);n>b;b++)if(j[b]){if(d=q(b),e=C[b],C[b]=c,!(n>d&&j[d].test(e)))break;c=e}}function u(){var a=B.val(),b=B.caret();if(o&&o.length&&o.length>a.length){for(A(!0);b.begin>0&&!j[b.begin-1];)b.begin--;if(0===b.begin)for(;b.begin<l&&!j[b.begin];)b.begin++;B.caret(b.begin,b.begin)}else{for(A(!0);b.begin<n&&!j[b.begin];)b.begin++;B.caret(b.begin,b.begin)}h()}function v(){A(),B.val()!=E&&B.change()}function w(a){if(!B.prop("readonly")){var b,c,e,f=a.which||a.keyCode;o=B.val(),8===f||46===f||d&&127===f?(b=B.caret(),c=b.begin,e=b.end,e-c===0&&(c=46!==f?r(c):e=q(c-1),e=46===f?q(e):e),y(c,e),s(c,e-1),a.preventDefault()):13===f?v.call(this,a):27===f&&(B.val(E),B.caret(0,A()),a.preventDefault())}}function x(b){if(!B.prop("readonly")){var c,d,e,g=b.which||b.keyCode,i=B.caret();if(!(b.ctrlKey||b.altKey||b.metaKey||32>g)&&g&&13!==g){if(i.end-i.begin!==0&&(y(i.begin,i.end),s(i.begin,i.end-1)),c=q(i.begin-1),n>c&&(d=String.fromCharCode(g),j[c].test(d))){if(t(c),C[c]=d,z(),e=q(c),f){var k=function(){a.proxy(a.fn.caret,B,e)()};setTimeout(k,0)}else B.caret(e);i.begin<=m&&h()}b.preventDefault()}}}function y(a,b){var c;for(c=a;b>c&&n>c;c++)j[c]&&(C[c]=p(c))}function z(){B.val(C.join(""))}function A(a){var b,c,d,e=B.val(),f=-1;for(b=0,d=0;n>b;b++)if(j[b]){for(C[b]=p(b);d++<e.length;)if(c=e.charAt(d-1),j[b].test(c)){C[b]=c,f=b;break}if(d>e.length){y(b+1,n);break}}else C[b]===e.charAt(d)&&d++,k>b&&(f=b);return a?z():k>f+1?g.autoclear||C.join("")===D?(B.val()&&B.val(""),y(0,n)):z():(z(),B.val(B.val().substring(0,f+1))),k?b:l}var B=a(this),C=a.map(c.split(""),function(a,b){return"?"!=a?i[a]?p(b):a:void 0}),D=C.join(""),E=B.val();B.data(a.mask.dataName,function(){return a.map(C,function(a,b){return j[b]&&a!=p(b)?a:null}).join("")}),B.one("unmask",function(){B.off(".mask").removeData(a.mask.dataName)}).on("focus.mask",function(){if(!B.prop("readonly")){clearTimeout(b);var a;E=B.val(),a=A(),b=setTimeout(function(){B.get(0)===document.activeElement&&(z(),a==c.replace("?","").length?B.caret(0,a):B.caret(a))},10)}}).on("blur.mask",v).on("keydown.mask",w).on("keypress.mask",x).on("input.mask paste.mask",function(){B.prop("readonly")||setTimeout(function(){var a=A(!0);B.caret(a),h()},0)}),e&&f&&B.off("input.mask").on("input.mask",u),A()})}})});As shown in the image:
Add the following URL to the Dynaform's external libs property:
https://raw.githubusercontent.com/digitalBush/jquery.maskedinput/1.4.1/dist/jquery.maskedinput.min.jsThe code may load more slowly when downloading from an external site.
- id: Unique ID of the control.
- mask-parameters: The template of the mask, where:
Parameter Represents Example 9 Any number (0-9). A US phone number: $("#id").getControl().mask("1(999) 999-9999")
a Any letter (A-Z,a-z) IATA 3-letter code: $("#id").getControl().mask("aaa")
* Any letter or number (A-Z,a-z,0-9) ? Any characters after ?
are optional.An optional extension to a phone number:
$("#id").getControl().mask("(999) 999-9999? x9999")
Any other characters are automatically inserted into the field.
Ex:$("id").getControl().mask("Good evening, aa?aaaaaaaaaaaaaa")
Placeholder: (Optional) Object that defines the mask's properties, and has the following format:
{placeholder: "placeholder"}
By default, characters to be entered by the user are displayed as "_" (an underscore) when the field has the focus. To use different character(s), define the
placeholder
. For example, to use a space instead of an underscore:
$("#id").getControl().mask("IM-99a9", {placeholder: " "})
- Completed: Defines a custom function that will be executed after the focus leaves the field.
For example, to display a message if the text entered in the "productCode" field starts with "C":
$("#productCode").getControl().mask("a***", {completed: function() {
if (this.val().substr(0,1) == "C") {
alert("Remember to only use Acme Co. product codes");
}
}});
Defining the Fields
Add JavaScript code to the textbox or textarea field to call the mask()
method.
Parameters:
It is also possible to define new wildcard characters or redefine existing ones to use in a mask. For example, the following code defines a new wildcard ~
, which represents either +
(plus sign) or -
(minus sign). Then, it uses that wildcard in a mask in the "amount" field:
$("#amount").getControl().mask("~9.99");
The mask()
function can also be used with text fields inside grids. For example, the following code applies the mask "99-H99" to a grid field with the ID "itemCode", inside a grid whose ID is "orderList":
var fieldId = "amount"; //set to ID of text field inside grid
//set the mask in all existing rows when the Dynaform loads:
var nRows = $("#"+gridId).getNumberRows()
for (var i = 1; i <= nRows; i++) {
$("[id='form["+gridId+"]["+i+"]["+fieldId+"]']").mask("99-H99");
}
//set the mask in newly added rows:
$("#"+gridId).onAddRow(function(aNewRow, oGrid, rowIndex) {
$("[id='form["+gridId+"]["+rowIndex+"]["+fieldId+"]']").mask("99-H99");
});
Numbers with Thousands Separators
Normandes Junior provides a jQuery mask for numbers with two decimal digits and integers that need to automatically insert a thousands separator.
To use this mask in a Dynaform, first download the file jquery.masknumber.js (right click and select Save Link As).
Then, save the file in the public_html folder of your ProcessMaker server:
Linux manual install:
Linux Bitnami install:
Windows manual install:
Windows Bitnami install:
Windows automatic installer in version 3.0.17 and earlier:
Place the file's name in the Dynaform's External Libs property, as shown in the image below:
Then, add JavaScript code to the Javascript property of the Dynaform to configure the textbox or textarea that will use the imported number mask library. Some examples can be found in the table below:
Examples | |
---|---|
Description | Code |
For an English-style decimal number such as 1.99 , 12,288.07 or 182,837,627,897.54 ,
which uses a , (comma) as the thousands separator and a . (dot) as the
decimal point: |
$("#id").getControl().maskNumber() $("#invoiceAmount").getControl().maskNumber(); |
For an English-style integer such as 13 , 12,288 or 182,837,627,897 ,
which uses a , (comma) as the thousands separator: |
$("#id").getControl().maskNumber({integer: true}) $("#invoiceAmount").getControl().maskNumber({integer: true}); |
For an European-style number such as 1,99 , 12.288,07 or 182.837.627.897,54 ,
which uses a . (dot) as the thousands separator and a , (comma) as the
decimal point, use the code: |
$("#id").getControl().maskNumber({decimal: ',', thousands: '.'}) $("#invoiceAmount").getControl().maskNumber({decimal: ',', thousands: '.'}); |
For an European-style integer such as 13 , 12.288 or 182.837.627.897 ,
which uses a . (dot) as the thousands separator, use the code: |
$("#id").getControl().maskNumber({integer: true, thousands: '.'}) $("#invoiceAmount").getControl().maskNumber({integer: true, thousands: '.'}); |
The maskNumber()
function can also be used with text fields inside grids. For example, the following code applies a European style number mask to a grid field with the ID "amount" inside a grid whose ID is "orderList":
var fieldId = "amount"; //set to ID of text field inside grid
//set the thousands separator in all existing rows when the Dynaform loads:
var nRows = $("#"+gridId).getNumberRows()
for (var i = 1; i <= nRows; i++) {
$("[id='form["+gridId+"]["+i+"]["+fieldId+"]']").maskNumber({decimal: ',', thousands: '.'});
}
//set the thousands separator in newly added rows:
$("#"+gridId).onAddRow(function(aNewRow, oGrid, rowIndex) {
$("[id='form["+gridId+"]["+rowIndex+"]["+fieldId+"]']").maskNumber({decimal: ',', thousands: '.'});
});