The current controls which can be put on a CRM entity form are:
- String
- Integer
- Float
- Currency
- Date/Time
- Boolean
- Picklist
- Memo
As you can see, there is no such option like a multi select box. Even within CRM you do sometimes need this. For example: Several contacts are receiving business gifts every now and then. You do not want the enduser to fill in which gifts they received in by hand, because they might make typing mistakes. Then you can't use this field for searching. So you want to use a multi select box.
In this article I will describe a way to create a workaround for archieving this by using a combination of a picklist and a memo field.
First we will have to add the picklist and memo field to the deployment manager. We will add a picklist called CFPgifts and a memo field called CFMgifts. It probably wouldn't surprise you that the next step is to add these fields to the contact form of CRM. We will add them under eachother, the picklist on top, the Memo under. I have removed the label for the Memo field to make it look better.
Now we can fill the picklist with the values. I have added the values 'Christmas card', 'Wine', 'PDC tickets'. Now we need to copy the selected value to the memo field. This will be done by using Javascript. The properties window of a picklist field allows you to add some scripting to the onChange event. This field is very useful, but not really user friendly. First lets get the control working, later I will describe an easier way to modify the script.
We communicate with the picklist value by using:
crmForm.CFPgifts.value
The memofield is available by using:
crmForm.CFMgifts.value
That means that if we enter this script in the onChange event, that we can copy data from the picklist to the memo field:
crmForm.CFMgifts.value = crmForm.CFMgifts.value + crmForm.CFPgifts.value;
Don't forget to switch the event on with the checkbox!
Now we can extend this task by putting a separator between the values. We should also check if the new item is a new item or if it is already in the list. If we add all this to the onChange event, then that small box will not be clear anymore. It also removes the breaks you enter manually. Therefore I prefer to only call a function from this onChange event and store the real code in a separate file, although this is not support. To do this, we have to modify the edit.aspx located at: drive:/website/SFA/conts/edit.aspx. In this file there are several other javascript files linked. We add one for ourselves which will look like this:
<script language="javascript" src="/sfa/conts/PicklistEx.js"></script>
Here is the file which includes the separator and check for existing items.
// Functions needed by the multi select box in MSCRM
// Author: Ronald Lemmen
// Company: Avanade Netherlands
// function to check if an item exists and if not, add it to the item list
function checkAndAdd(item, itemlist){
if (item != ""){
if (checkItemExists(item, itemlist) == false){
itemlist = addItem(item, itemlist);
}
itemlist = clearup(itemlist);
}
return itemlist;
}
// function which adds a new item and clears up the item list
function addItem(newItem, itemlist){
return newItem + ";" + itemlist; //modified by ronald 05-11-04
}
//this function checks if the submitted item is in the list;
//this can be done by checking on ;item; ;
//an item like "wine" is not the same as "red wine";
function checkItemExists(item, itemlist){
itemlist = strReplaceAll(itemlist, " ", ""); // remove the spaces from the existing list;
item = strReplaceAll(item, " ", ""); // also remove the spaces from the new item
itemlist = ";" + itemlist + ";"; // also the first charactar without a semicolon will be recognized now.;
if (itemlist.indexOf(";" + item + ";") >= 0){
return true;
}else{
return false;
}
}
function clearup(itemlist){
itemlist = strReplaceAll(itemlist, ";;", ";"); // remove double semicolons;
if (itemlist.substring(0,1) == ";"){ //remove the first semicolon;
itemlist = itemlist.substr(1);
}
if (itemlist.substring(0,1) == " "){ //remove the first space;
itemlist = itemlist.substr(1);
}
return itemlist;
}
//function to search and replace all occurances of a string;
function strReplaceAll(str,strFind,strReplace){
var returnStr = str;
var start = returnStr.indexOf(strFind);
while (start>=0){
returnStr = returnStr.substring(0,start) + strReplace + returnStr.substring(start+strFind.length,returnStr.length);
start = returnStr.indexOf(strFind,start+strReplace.length);
}
return returnStr;
}
When this file is stored on the correct location (drive:/website/SFA/conts/PicklistEx.js), then you can modify the onChange event to:
crmForm.CFMgifts.value = checkAndAdd(crmForm.CFPgifts.value, crmForm.CFMgifts.value);
This keeps the CRM code readable and you will be able to modify this code a lot easier compared to that small box. Now you just have to publish the modifications and run an iisreset and you're done.
You might want to enhance this control. Now the users are still able to modify the memo field by hand. You could add another picklist which will remove values from the memo field and then disable the memofield upon opening of the form. This is up to you to create :)
Update: James indeed did take the time to enhance this control and to make this for CRM 3.0! See his blogpost at this address:
http://jameswilcox.ca/random/ms-crm-30-multi-select-boxes/