Monday, June 14, 2010

CRM 4.0 Formatting Form Fields

The following is an intuitive Mask/UnMask JavaScript object. If you’re looking to toggle other clients (other than an entity form) you might use it as a template for a server side plug-in. The object makes it easy to enforce various types of formatting such as phone numbers , a social security number, credit card numbers and many more. The sample below formats the account Main and Other phone fields.

When a user gives focus to a phone field the object unmasks the field’s value leaving only numbers (the original user input) or blank. Once focus is lost the mask is applied again, if a value exists, giving it its final display. The object also fires when the form is saved to support a situation where focus is not fired i.e. when the user uses the keyboard to save the record.

There’re also other features such as displaying the format as a title or telling the mask to fire when the form loads. The later is hardly required but you might find it useful to leverage the user interaction with the form … and cleans/reformat imported/external values along the way.

If you take a closer look you’ll notice that the object receives both a format (mask) such as “(##) ###-####” and a regular expression which is an unmask filter e.g. “\\D”. “\\D” means anything but numbers which is what you need to remove/replace to get the user’s original input.

The code goes in the account entity onload event.
Give it a go and feel free to leave comments.



function Mask(format)
{
var m = this;

/* e.g. (##) ###-#### */
m.Format = format;
m.Field = null;
/* OnLoad - Might be Used to cleans imported values. */
m.OnLoad = false;
/*
A regular expression for unwanted (bad) characters.
e.g. A field (e.g. phone number) original (before formatting) characters must contain numbers only.
*/
m.Filter = null;

var onloadbound = false;
var onsavebound = false;
var onfocusbound = false;

m.Mask = function()
{
if (!m.Field)
{
return alert("Mask is missing a field");
}

/* Sets the textbox title to required Format */
m.Field.title = m.Format;

if (!onfocusbound)
{
onfocusbound = m.Field.attachEvent("onfocusin", unmask);
m.Field.attachEvent("onfocusout", mask);
}

if (m.OnLoad && !onloadbound)
{
onloadbound = mask() == undefined;
}

if (!onsavebound)
{
onsavebound = crmForm.attachEvent("onsave",mask);
}
}

function unmask()
{
m.Field.DataValue = strip();
}

function mask()
{
/* Reformat */
var formated = m.Format;
/* value as Array of characters */

var splitValue = strip().split("");

if (splitValue.length == 0)
{
m.Field.DataValue = null;
return;
}

/* Regex defining a single placeholder */
var placeHolderReg = new RegExp("#{1}");
/* Replace each placeholder with a single character */
for(var i = 0; i < splitValue.length ; i++)
{
formated = formated.replace(placeHolderReg,splitValue[i]);
}

m.Field.DataValue = formated;
}

function strip()
{
if (!m.Field.DataValue)
{
return "";
}
/* Strip field from unwanted characters */
var valueOnlyReg = new RegExp(m.Filter,"gi");
return m.Field.DataValue.replace(valueOnlyReg,"");
}
}

function OnCrmPageLoad()
{
var phoneMask = new Mask("(##)###-####");
phoneMask.Field = crmForm.all.telephone1;
phoneMask.Filter = "\\D"; //Unmask Filter - Strip Everything which is not a Number
phoneMask.Mask();

var cellMask = new Mask("+(##) ### ####");
cellMask.Field = crmForm.all.telephone2;
phoneMask.OnLoad = true;
cellMask.Filter = "\\D"; //Unmask Filter - Strip Everything which is not a Number
cellMask.Mask();
}

OnCrmPageLoad();

3 comments:

Andriy a33ik Butenko said...

Welcome back, Adi!
I missed your posts a lot!

Anonymous said...

Thanks for the post! it will be very useful to me xD

Taylor said...

I have an attribute which show as a ‘bit’ field in a CRM 4.0 database. I need to dynamically add it to a dynamic entity then set its value to either 0 or 1. Which is the best way of doing this?