
There are some dynamicpicklist examples on the Internet. You may find it from CRM SDK as well, and there's A (slightly) different approach to dynamic picklists from
Greg Owens.But none of those can meet my client's requirement. We have 2 picklists(which is normal), but picklist2 has hundreds of items. And those picklists repeat 3 times on all activites. Furthermore, they don't want to use another entity. So I create a XML file to keep the data, and using it dynamicly fill out picklist2 when picklist1 has value selected. It works great, and you only need to maintain one XML file.
This is a very simple XML to do the demonstration, put it ('section.xml') into the root folder of CRMWeb. The idea is: when user selects type1 in picklist1, then picklist2 only shows item1, item2, item3; when user selects type2 in picklist1,the picklist2 only shows item4, item5, item6.
<?xml version="1.0" encoding="utf-8" ?>
<Section>
<type1>
<item>item1</item>
<item>item2</item>
<item>item3</item>
</type1>
<type2>
<item>item4</item>
<item>item5</item>
<item>item6</item>
</type2>
</Section>
Suppose there are two picklists on crmForm, picklist2's value depends on picklist1's selection.
In my example:
picklist1 is: new_type1, it has two values: 'typeA/typeB' and 'typeC/typeD'
picklist2 is: new_section1, it doesn't have any value, and I add another nvarchar attribute: new_section1Text to save it's value(see example)
/*
Form.onLoad() event
GetItems() is a global function to get section's list items based on type's selection
typeValue: picklist1's DataValue
section: picklist2(object)
sectionText: picklist2.SelectedText
*/
GetItems = function(typeValue, section, sectionText)
{
//clean the section object
section.length = 0;
//it is the index of picklist2.SelectedText in XML file
var sectionTextIndex = 0;
//get the typeName, used for XML node
var typeName = 0;
switch(typeValue)
{
case "1" : typeName = "type1"; break;
case "2" : typeName = "type2"; break;
case "0" : return;
}
//load XML file
var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = false;
xmlDoc.load("/section.xml");
//get all items under this type
xmlDoc = xmlDoc.getElementsByTagName(typeName)[0];
var items = xmlDoc.getElementsByTagName('item');
//insert all items into section object
for(var i=0; i<items.length; i++)
{
section.AddOption(items(i).firstChild.nodeValue, i+1);
if((sectionText != null)&&(sectionText.DataValue == items(i).firstChild.nodeValue))
{
sectionTextIndex = i+1;
}
}
return sectionTextIndex;
}
GetPicklist(crmForm.all.new_type1, crmForm.all.new_section1, crmForm.all.new_section1text);
function GetPicklist(type, section, sectionText)
{
if(sectionText.DataValue != null)
{
//select the right one
section.DataValue = GetItems(type.DataValue, section, sectionText);
}
}
/*
Form.onSave() event, save the current new_section1's selectedText
Becasue we need to add this option to new_section1 on Form.onLoad()
*/
SetPicklist(crmForm.all.new_section1 , crmForm.all.new_section1text);
function SetPicklist(section, sectionText)
{
if(section.SelectedText != "")
{
sectionText.DataValue = section.SelectedText;
section.length = 0;
}
}
/*
new_type1.onChange() event to call GetItem() funciton, passing new_type1.DataValue and new_section1, sectionText as parameters
*/
if(crmForm.all.new_type1.DataValue != null)
{
GetItems(crmForm.all.new_type1.DataValue, crmForm.all.new_section1, null);
}
else
{
crmForm.all.new_section1.options.length = 0;
}