Natively MS Dynamics CRM 4.0 displays many-to-many relationships as Associated Views. We cannot display records from related entity at any other place on the other entity. To display related records as check boxes on CRM form we need to either create custom web page or write JavaScript.
Following are the steps to create a Multi Select checkbox list to display related record on CRM Form through JavaScript:
1. Create a many-to-many relationship
2. Add OnLoad event on CRM Form
3. Add OnSave event on CRM Form
4. Associate/De-associate Inquiry from Client Request through Create and Update Plugins
Create two new custom entities and add many-to-many relationship between them:
1. Create a new entity called Inquiry.
2. Publish the Inquiry entity.
3. Create an another entity called Client Request
4. Add a section on the CRM Form called ‘Inquiries’ to display list of inquiries.
5. Create a N:N relationship from Client Request to Inquiry entity.
6. Publish the Client Request entity.
7. Open Inquiry entity and add some new inquiries.
Now entities are configured and having some sample data. We are now ready to add JavaScript code on CRM Form to display Inquiry options on Client Request entity as a check box list.
Add an onLoad event on Client Request entity to display Inquiry options as check box list:
2. Using CRM Web Services, retrieve all selected inquiries from relationship table which is created by CRM automatically when we create a many-to-many relationship. Select only inquiries which are associated with current Client Request. This should be done only in case of retrieving Client Request. Check the FormType property of CRM Form and if Update mode then only retrieve selected inquiries. ( How to retrieve multiple records from link entity through JavaScript ) 3. Call “GenerateMultiSelectList()” method and pass the list of all inquiries and list of selected (associated) inquiries and the name of element (location) where to display checkbox list.
Add an onSave event on Client Request entity to save selected inquiries:
1. Call “SaveMultiSelectList()” method and pass the section name, in our case ‘inquiries’. This method will provide you following semicolon (;) separated lists:
a. List: This provides Inquiry ID list of all inquiries
b. SelectedList: This provides Inquiry ID list of selected inquiries
c. SelectedNameList: This provides Inquiry Name list of selected inquiries.
2. Now you have to set each list in any of the CRM field to save into CRM database
Associate/De-associate Inquiry from Client Request:
1. Now finally you have to associate or de-associate inquiries from Client Request based on the user selection. For this purpose you need to create plugins on Create and Update message and add/remove. Use ‘ AssociateEntitiesRequest’ class of CrmService to add a link between Inquiry and Client Request entity instances for a many-to-many relationship. A complete example is given in CRM SDK at MSDN(http://msdn.microsoft.com/en-us/library/cc151609.aspx ) OnLoad JavaScript Code:
//Method to remove all child nodes from an html element
function RemoveAllChilds(element)
{
while(element.hasChildNodes())
{
element.removeChild(element.childNodes[0]);
}
}
//Method to generate check boxes and display them into an area specified and make the default selection
// parentArea : An HTML element where checkboxes will be added
// checkBoxList : List of items that will be displayed as checkboxes
// selectedList : List of items that will be selected by default
// listType : Name or type of the list
function GenerateMultiselectCheckboxes(parentArea, checkBoxList, selectedList, listType)
{
// Clear the container element
RemoveAllChilds(parentArea);
tableTag = document.createElement("table");
tableTag.setAttribute("id","tbl_multiselect" + listType);
tableTag.setAttribute("width","100%");
tbodyTag = document.createElement("TBODY");
var NoOfOptions = checkBoxList.length;
var NoOfRows = 0;
if(NoOfOptions <= 4)
{
NoOfRows = 1;
}
else
{
NoOfRows = (checkBoxList.length /4);
}
for(var iRow = 0; iRow < NoOfRows; iRow++)
{
mycurrent_row = document.createElement("tr");
for(var iCell = 0; iCell < 4 ; iCell++)
{
var addInput;
var OptionIndex = iCell + (iRow * 4);
if(OptionIndex < NoOfOptions)
{
var pOption = checkBoxList[OptionIndex][1];
var cellId = checkBoxList[OptionIndex][0];
if(selectedList != null && typeof(selectedList) != "undefined" && selectedList.indexOf(cellId)> 0)
{
addInput = document.createElement("<input type='checkbox' CHECKED style='border:none; width:25px; align:left;' />" );
}
else
{
addInput = document.createElement("<input type='checkbox' style='border:none; width:25px; align:left;' />" );
}
var addLabel = document.createElement( "<label style='align:left;' />");
addLabel.innerText = pOption;
mycurrent_cell = document.createElement("td");
mycurrent_cell.setAttribute("width","25%");
mycurrent_cell.setAttribute("id",cellId);
mycurrent_cell.setAttribute('align', "left");
mycurrent_cell.appendChild(addInput);
mycurrent_cell.appendChild(addLabel);
}
else
{
mycurrent_cell = document.createElement("td");
mycurrent_cell.setAttribute("width","25%");
mycurrent_cell.setAttribute("id",0);
mycurrent_cell.setAttribute('align', "left");
currenttext = document.createTextNode("");
mycurrent_cell.appendChild(currenttext);
}
mycurrent_row.appendChild(mycurrent_cell);
}
tbodyTag.appendChild(mycurrent_row);
}
tableTag.appendChild(tbodyTag);
return tableTag;
}
// Method to generate Multi Select List based on the list of items
// list : List of items to be displayed as multi select check boxes
// selectedList : List of items to be selected by default
// listType : Name of the control which will hold the multi selct list, this should be unique on the CRM.
function GenerateMultiSelectList(list, selectedList, listType)
{
var row_MultiSelect = document.getElementById("tr_multiselect" + listType);
var cell_MultiSelect = null;
if(row_MultiSelect != null && typeof(row_MultiSelect) != "undefined")
{
cell_MultiSelect = row_MultiSelect.childNodes[0];
if(cell_MultiSelect == null || typeof(cell_MultiSelect) == "undefined")
{
cell_MultiSelect = document.createElement("td");
cell_MultiSelect.setAttribute('id', "td_multiselect" + listType);
cell_MultiSelect.colSpan = 4;
row_MultiSelect.appendChild(cell_MultiSelect);
}
}
else
{
//Find the container element which will hold the multiselect list.
var arrTD = document.getElementsByTagName("td");
var FieldContainer = "";
for(var i = 0; i < arrTD.length; i++)
{
currTD = arrTD[i];
if(currTD != null && typeof(currTD) != "undefined" && currTD.innerText.toLowerCase() == listType.toLowerCase())
{
FieldContainer = currTD;
break;
}
}
parentArea = FieldContainer.childNodes[0].childNodes[1];
row_MultiSelect = document.createElement("tr");
row_MultiSelect.setAttribute("id", "tr_multiselect" + listType);
row_MultiSelect.setAttribute("vAlign", "top");
parentArea.appendChild(row_MultiSelect);
cell_MultiSelect = document.createElement("td");
cell_MultiSelect.setAttribute('id', "td_multiselect" + listType);
cell_MultiSelect.colSpan = 4;
row_MultiSelect.appendChild(cell_MultiSelect);
}
var containerTable = GenerateMultiselectCheckboxes(cell_MultiSelect, list, selectedList, listType);
cell_MultiSelect.appendChild(containerTable);
}
function GetListFromXmlResponse(responseXml)
{
var arrListItem = new Array();
if(responseXml != null)
{
for(i = 0; i < responseXml.length; i++)
{
arrItem = new Array(responseXml[i].childNodes[0].text,responseXml[i].childNodes[1].text);
arrListItem[i] = arrItem;
}
}
return arrListItem;
}
//Example
//Retrieve all inquiries
var responseXml = RetrieveMultiple();
InquiryList = GetListFromXmlResponse(responseXml);
//Note: List type should be same as section name where you want to display the Inquiries as check boxes;
GenerateMultiSelectList(InquiryList, null,"inquiries");
OnSave JavaScript Code:
var List = '';
var SelectedList = '';
var SelectedNameList = '';
function SaveMultiSelectList(listType)
{
var tbl_MultiSelect = document.getElementById("tbl_multiselect" + listType);
var CheckBoxList = tbl_MultiSelect.getElementsByTagName("td");
if(typeof(CheckBoxList) != "undefined" && CheckBoxList != null && CheckBoxList.length > 0)
{
for(i = 0; i < CheckBoxList.length ; i++)
{
var CheckBox = CheckBoxList[i];
if(typeof(CheckBox) != "undefined" && CheckBox != null && CheckBox.childNodes.length > 0)
{
if(CheckBox.id != null && CheckBox.id != 0)
{
var Id = CheckBox.id;
var IsChecked = CheckBox.childNodes[0].checked;
var Name = CheckBox.childNodes[1].innerText;
List = List + ";" + Id
if(IsChecked)
{
SelectedNameList = SelectedNameList + ";" + Name;
SelectedList = SelectedList + ";" + Id;
}
}
}
}
}
}
SaveMultiSelectList("inquiries");