PDA

View Full Version : Form Fields Masking Plugin - Ext.ux.plugins.MaskIt



ethraza
10 Sep 2010, 9:51 AM
I was unable to find the Upload File in Toolbox menu under Ext_extension page, so I gonna post it here... anyway it's a plugin! :)

The MaskIt is a ExtJs plugin to mask form fields. After years of waiting the ExtJs come up with a builtin mask method I giveup and did it myself. It's far from perfection but works good enough for my needs.
It mask the field after default validation. It works on typing and on setValue too. It can fill the field with placeholder mask or just add the mask characters when needed.
Down there you'll find some documentation, usage examples and the code itself. If I fix or change something I gonna edit this first post and add a release comment.

~o)

MaskIt ExtJs Plugin

1.0.1: Minor fix. Grid renderer usage example. By Allan Brazute Alves (EthraZa)
1.0: Initial release. By Allan Brazute Alves (EthraZa)

Doc:

Config Options

mask: Word characters are word characters, numbers limit the max number and non word, numbers or the placeholder char are the mask it self. Default is '(99) 9999-9999', Brazil 10 digit phone number
ie. mask: 'AA-92' # "A" accepts anything from A to Z; "-" is a mask char; "9" accepts from 0 to 9; "2" accepts from 0 to 2
placeholder: If set, it generally will be '_' and the field will be filled with the place holder plus the mask. Default is false
unmaskRe: The RegExp to remove the mask and return the value only characters. Default is /(\W|_)/g that take out any non word or number char plus the underscore.
getUnmasked: If true, the getValue method will return the unmasked value. Default is true
applyValue: If true, it applies the value plus the mask to the field, the function maskIt will just return the value masked and do nothing to the field. Default is true.


Methods

maskIt: Apply the defined mask to a string.
Params:
- {string} (optional) The string to be masked. Default to field raw value
- {bool} (optional) If true the masked value will be set to the field, if false the masked value will be just returned

Return:
- {string} The masked value
unmaskIt: Replace a string mask characters with "" (empty) using the defined unmaskRe RegExp.
Params:
- {string} The string to be unmasked

Return:
- {string} The unmasked value


Events

mask: Fires when masking the field


TODO/Know bugs

When using placeholder, the backspace can't go back over a mask char! :(


Usage:


<script type="text/javascript">
Ext.onReady(function() {
desk = new Ext.Viewport({
layout: 'border',
items: [{
region: 'center',
title: 'Test Hangar',
xtype: 'form',
activeTab: 0,
autoDestroy: true,
enableTabScroll: true,
items: [{
xtype: 'textfield',
fieldLabel: 'TSTa',
id: 'tsta',
mask: '999.999.999-99',
emptyText: '___.___.___-__',
placeholder: '_',
plugins: new Ext.ux.plugins.MaskIt()
},{
xtype: 'textfield',
fieldLabel: 'TSTb',
id: 'tstb',
mask: 'ZZZ-5599',
emptyText: '___-____',
placeholder: false,
plugins: ['maskit']
},{
xtype: 'combo',
fieldLabel: 'TSTc',
id: 'tstc',
name: 'tstcn',
hiddenName: 'tstcn',
mask: 'ZZZ-5599',
emptyText: '___-____',
plugins: ['maskit'],
displayField: 'text',
valueField: 'value',
typeAhead: false,
mode: 'local',
triggerAction: 'all',
forceSelection: false,
selectOnFocus: false,
autoSelect: false,
allowBlank: false,
store: new Ext.data.SimpleStore({
fields: ['text','value'],
data : [
['abc-1234', 'abc1234'],
['xyz-9871', 'xyz9871']
]
})
}]
}]
});

//Ext.util.Observable.capture(Ext.getCmp('tsta'), function(e){console.info(e)});
});
</script>
Grid / EditorGrid renderer usage:


{
header: 'Federal TAX ID',
dataIndex: 'taxId',
width: 100,
editor: new Ext.form.TextField({
mask: '99-9999999',
plugins: new Ext.ux.plugins.MaskIt()
}),
renderer: function(v){
return (this.editor)? (v)? this.editor.maskIt(v, false) : '' : v;
}
}
Plugin Code:


Ext.ns('Ext.ux.plugins');

/*!
* MaskIt 1.0
* Allan Brazute Alves (EthraZa)
* http://www.ghsix.com.br/allan
*
* ExtJs plugin to mask a form field
*/
Ext.ux.plugins.MaskIt = function(config) {
this.addEvents({
'mask' : true
});
Ext.apply(this, config);
};

Ext.extend(Ext.ux.plugins.MaskIt, Ext.util.Observable, {
init: function(field){
if (!field.isFormField)
return false;

// Defaults
Ext.applyIf(field, {
/**
* @cfg {String}
* Word characters are word characters,
* numbers limit the max number
* and non word, numbers or the placeholder char are the mask it self.
* Default is '(99) 9999-9999', Brazil 10 digit phone number
*/
mask: '(99) 9999-9999',
/**
* @cfg {Bool/String}
* If set, it generally will be '_' and the field will be filled with the place holder plus the mask.
*/
placeholder: false,
/**
* @cfg {RegEx}
* The RegExp to remove the mask and return the value only characters.
* Default is /(\W|_)/g that take out any non word or number char plus the underscore.
*/
unmaskRe: /(\W|_)/g,
/**
* @cfg {Bool}
* If true, the getValue method will return the unmasked value. Default is true
*/
getUnmasked: true,
/**
* @cfg {Bool}
* If true, it applies the value plus the mask to the field,
* the function maskIt will just return the value masked and do nothing to the field. Default is true.
*/
applyValue: true
});

// Apply
Ext.apply(field, {
validationDelay: 0,
validateOnBlur: false,

getCursor : function(oCom) {
var elDom = oCom.getEl().dom;
var s, e, r;
if(elDom.createTextRange){
r = document.selection.createRange().duplicate();
r.moveEnd('character', elDom.value.length);

if(r.text === ''){
s = elDom.value.length;
} else {
s = elDom.value.lastIndexOf(r.text);
}
r = document.selection.createRange().duplicate();
r.moveStart('character', -elDom.value.length);
e = r.text.length;
} else {
s = elDom.selectionStart;
e = elDom.selectionEnd;
}
return {start: isNaN(s)? 0 : s, end: isNaN(e)? 0 : e, range: r};
},

setCursor : function(cursorPosition, incPos) {
var elDom = this.getEl().dom;
var p = cursorPosition.start + incPos||0;
p = (p > elDom.value.length)? elDom.value.length : p;

if (elDom.createTextRange) {
cursorPosition.range.move('character', p);
cursorPosition.range.select();
} else {
elDom.focus();
elDom.setSelectionRange(p,p);
}
},

/**
* @param {string} (optional) The string to be masked. Default to field raw value
* @param {bool} (optional) If true the masked value will be set to the field, if false the masked value will be just returned
*
* Apply the defined mask to a string.
*/
maskIt : function(sValue, bApplyValue){
bApplyValue = (!Ext.isEmpty(bApplyValue))? bApplyValue : this.applyValue||false;
sValue = (sValue)? String(sValue) : this.unmaskIt(this.getRawValue());
if (!sValue)
return false;

var vp = 0; //value position
var mp = 0; //mask position
var cp = 0; //increase cursor position in
try {
var pos = this.getCursor(this) || 0; //cursor position
} catch(err) {
var pos = 0;
}
var r = ''; //return isValid

if (typeof this.placeholder == 'string') {
while (sValue.length < this.mask.length) {
sValue += this.placeholder;
}
}

while (vp < sValue.length && r.length < this.mask.length) {
var mm = this.mask.charAt(mp); //get next mask char
var vv = sValue.charAt(vp); //get next val char

if (/\W/.test(mm)) { // Non word char
var vreg = new RegExp('\\W')
} else if(isNaN(mm*1)) { // Word
var vreg = new RegExp('[A-Za-z]')
} else { // Number
var vreg = new RegExp('\\d')
}

if (/\W/.test(mm)) { // Mask char
r += mm;
++mp;
if ((mp == pos.start+cp) || (mp >= pos.start && vreg.test(vv) && vv != this.placeholder)) ++cp;
} else if (vreg.test(vv) || vv == this.placeholder) { // Value char
if (isNaN(mm*1) || vv == this.placeholder) {
r += vv;
} else if (vv <= mm){
r += vv;
}
++vp;
++mp;
} else {
++vp;
}
}

// Fire mask event passing scope, old value and new masked value
this.fireEvent('mask', this, sValue, r);

if (bApplyValue) {
try {
this.setRawValue(r);
this.setCursor(pos, cp);
} catch(err){}
return true
} else {
return r
}
},

/**
* @param {string} The string to be unmasked
*
* Replace a string mask characters with "" (empty) using the defined unmaskRe RegExp.
*/
unmaskIt : function(sValue){
return (Ext.isString(sValue))? sValue.replace(this.unmaskRe,'') : '';
},

extGetValue : field.getValue,

getValue : function(){
return (this.getUnmasked)? this.unmaskIt(this.extGetValue()) : this.extGetValue();
},

// Events
validate : field.validate.createSequence(function(){
this.maskIt();
})

});

}
});
Ext.preg('maskit', Ext.ux.plugins.MaskIt);
//eo maskIt plugin