Wednesday, October 1, 2008

Finding crmForm elements By Css Class Names


There are situations where you need to change form elements text or appearance dynamically, i.e. changing a section name or page title, but find it “impossible” since the form html DOM doesn’t include identifiers for those elements.

Most examples I’ve seen regarding similar requests use a simple drill down (or up) mechanism from a certain anchor element, usually the closest element the target.
For example:

var anchorElement = document.getElementById(“An Element WithID”);
var targetElement = anchorElement.parentElement.parentElement.parentElement;
targetElement.innerText = "New Text";


This type of method is less then elegant and is a highly unmanageable technique.

In order to address this issue I’ve created a simple getElementsByClassName function which is a method similar to the already known getElementsByTagName function. The function receives an anchor element ( or null ) and a css class Name and return an array of html element that match the class Name. This type of mechanism is actually very popular in most JavaScript libraries like jquery and prototype.

The following code includes getElementsByClassName function and two common requests that are handled by that function.



function OnCrmPageLoad()
{
//Example #1: Change Address Section Text
var anchorNode = document.getElementById( "tab0" );
var secBarCss = "ms-crm-Form-SectionBar";
var addrSecTxt = "Address";
var addrSecElm = null;

var results = getElementsByClassName( secBarCss , anchorNode );
for( var i = 0 ; i < results.length ; i++ )
{
if( results[i].innerText == addrSecTxt ){
addrSecElm = results[i]; break;
}
}

addrSecElm.innerText = "Partial Address Information";

//Example #2: Change Account title form account: name to account: name (accountnumber)
anchorNode = null;
titleCss = "ms-crm-Form-Title";
titleTag = "SPAN";
titleElem = null;

results = getElementsByClassName( titleCss , anchorNode );
for( var i = 0 ; i < results.length ; i++ )
{
if( results[i].tagName == titleTag ){
titleElem = results[i]; break;
}
}

var accountNumber = crmForm.all.accountnumber.DataValue;
if (accountNumber == null)
accountNumber = "Not Supplied";

titleElem.innerText = titleElem.innerText + " (" + accountNumber + ")";
}

function getElementsByClassName(className, anchorNode)
{
if(!anchorNode) anchorNode = document.body;
var result = [];
var regEx = new RegExp("\\b" + className + "\\b");
var children = anchorNode.getElementsByTagName("*");
for( var i = 0 ; i < children.length ; i++ )
{
if( regEx.test( children[i].className ) )
result.push( children[i] );
}
return result;
}

OnCrmPageLoad();

9 comments:

Anonymous said...

Hi Adi,
This code was very helpful for renaming a section on my form. I just needed to change the achorName to be "ms-crm-Form-Section" to find my section names.

Anonymous said...

Sorry, I meant I changed my classname to "ms-crm-Form-Section".

Simon Hart said...

Excellent, thank you very much. Solved my problem.

--
Simon.

Andrew Zimmer said...

Excellent post. It saved me a lot of time. Thanks!

-Andrew

Anonymous said...

Thanks mate

oliverb said...

Excellent post. Thanks so much!!

Term Papers said...

I have been visiting various blogs for my term papers writing research. I have found your blog to be quite useful. Keep updating your blog with valuable information... Regards

Anonymous said...

Adi,

is there a quick way to disable all the fields on a form without disabling the tab itself. Right now, we are using the getelementsbyTagName method to gather the TD tags and then looping through and disabling each field. How can we identify the tab so it does not disable it?

Unknown said...

To be honest, I am always becoming confused with this, but you guys have helped me a lo! This type of method is surely less then elegant and is a highly unmanageable technique, you are right! Kindest regards, proofreading-services.org