Sunday, November 1, 2009

How to retrieve entity and its related attributes in CRM Form










I was working with MS CRM plug-ins for half a year already. When we worked on reusable plug-ins, we needed a setup entity to store some configuration setting that is required in plug-in execution. Most of the time, we need to store THREE configuration values: entity, their related attributes and plug-in related settings.
Luckily, I found out a good article on Internet which was written by a33ik. After playing around with his program for a while, I realize that this is the idea that I am looking for. I want to apply this idea in my reusable plug-ins. Thanks  to a33ik for sharing his idea.

As usual, I changed a little bit on his original idea since my scenario did not need to create all related attributes in child table setup. Moreover, I was worry on performance of CRM when we query through Parent - Child tables to retrieve setup information, and when we run plug-in to extract all related attributes and create unnecessary records.
Another thing is about consistency. If user changed customization of attributes (for example; display name) on CRM, setup table may not be updated automatically.So, lesser information storgae will help us reducing consistency issues. I also add one javascript function to auto populate attribute information and update when user saved the configuration record. For your convenience, here is my javscript code sample:

entityOnChange = function ()
{
crmForm.all.psx_entityname.DataValue = document.getElementById('psx_schemaname').options[document.getElementById('psx_schemaname').selectedIndex].innerText;

var schemaName = document.getElementById('psx_schemaname').options[document.getElementById('psx_schemaname').selectedIndex].getAttribute('schemaName');

var request = "" +
"<soap:envelope xmlns:soap="\"http://schemas.xmlsoap.org/soap/envelope/\"" xmlns:xsd="\"http://www.w3.org/2001/XMLSchema\"" xmlns:xsi="\"http://www.w3.org/2001/XMLSchema-instance\"">" +
GenerateAuthenticationHeader() +
" <soap:body>" +  
"     <execute xmlns="\"http://schemas.microsoft.com/crm/2007/WebServices\"">" +
"         <request xsi:type="RetrieveEntityRequest">" +
"             <metadataid>00000000-0000-0000-0000-000000000000</metadataid>" +
"             <entityitems>IncludeAttributes</entityitems>" +
"             <logicalname>" + schemaName + "</logicalname>" +
"             <retrieveasifpublished>true</retrieveasifpublished>" +
"         </request>" +
"     </execute>" +
" </soap:body>" + 
"</soap:envelope>";

var xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
xmlHttpRequest.Open("POST", "/mscrmservices/2007/MetadataService.asmx", false);
xmlHttpRequest.setRequestHeader("SOAPAction","http://schemas.microsoft.com/crm/2007/WebServices/Execute");
xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xmlHttpRequest.setRequestHeader("Content-Length", request.length);
xmlHttpRequest.send(request);

var result = xmlHttpRequest.responseXML;
var schemaNames = result.selectNodes("//EntityMetadata/Attributes/Attribute");
ConvertAttributeToPicklist('psx_attributename', schemaNames);
}

attribOnChange = function ()
{
crmForm.all.psx_displayname.DataValue = document.getElementById('psx_attributename').options[document.getElementById('psx_attributename').selectedIndex].innerText;
}

function ConvertEntityToPicklist(fieldName, dataItems)
{
var defaultValue = crmForm.all[fieldName].DataValue;
var table = crmForm.all[fieldName + "_d"]; 
var select = "<select class="ms-crm-SelectBox" defaultselected="" id="" + fieldName + "" name="" + fieldName + "" onchange="javascript:entityOnChange();" req="0" tabindex="1170">      <option ).text="" +="" ;="" logicalname="" value="" + dataItems[i].selectSingleNode(">            select += "schemaName='"+ dataItems[i].selectSingleNode('LogicalName').text+"'";                        if (dataItems[i].selectSingleNode('LogicalName').text == defaultValue)             {                select += " SELECTED";                defaultValueFound = true;            }                        select += ">" + dataItems[i].selectSingleNode('DisplayName/LocLabels/LocLabel/Label').text + "</option>        <option selected="selected" value="" + defaultValue + "">" + defaultValue + "</option> </select>";

table.innerHTML = select; 
entityOnChange();
}

function ConvertAttributeToPicklist(fieldName, dataItems)
{
var defaultValue = crmForm.ObjectId != null ? crmForm.all[fieldName].DataValue: null;
var table = crmForm.all[fieldName + "_d"]; 

var select = "<select class="ms-crm-SelectBox" defaultselected="" id="" + fieldName + "" name="" + fieldName + "" onchange="javascript:attribOnChange();" req="0" tabindex="1170">       <option ).text="" +="" ;="" logicalname="" value="" + dataItems[i].selectSingleNode(">            select += "schemaName='"+ dataItems[i].selectSingleNode('LogicalName').text+"'";                        if (dataItems[i].selectSingleNode('LogicalName').text == defaultValue)             {                select += " SELECTED";                defaultValueFound = true;            }            select += ">" + dataItems[i].selectSingleNode('DisplayName/LocLabels/LocLabel/Label').text + "</option>        <option selected="selected" value="" + defaultValue + "">" + defaultValue + "</option> </select>";

table.innerHTML = select; 
attribOnChange();
}

var request = "" +
"<soap:envelope xmlns:soap="\"http://schemas.xmlsoap.org/soap/envelope/\"" xmlns:xsd="\"http://www.w3.org/2001/XMLSchema\"" xmlns:xsi="\"http://www.w3.org/2001/XMLSchema-instance\"">" +
GenerateAuthenticationHeader() +
"  <soap:body>" +  
"    <execute xmlns="\"http://schemas.microsoft.com/crm/2007/WebServices\"">" +
"      <request xsi:type="\"RetrieveAllEntitiesRequest\"">" +
"        <retrieveasifpublished>true</retrieveasifpublished>" +
"        <metadataitems>EntitiesOnly</metadataitems>" +
"      </request>" +
"    </execute>" +
"  </soap:body>" + 
"</soap:envelope>";

var xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
xmlHttpRequest.Open("POST", "/mscrmservices/2007/MetadataService.asmx", false);
xmlHttpRequest.setRequestHeader("SOAPAction","http://schemas.microsoft.com/crm/2007/WebServices/Execute");
xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xmlHttpRequest.setRequestHeader("Content-Length", request.length);
xmlHttpRequest.send(request);

var result = xmlHttpRequest.responseXML;
var schemaNames = result.selectNodes("//CrmMetadata/CrmMetadata");

ConvertEntityToPicklist('psx_schemaname', schemaNames);  
crmForm.all.psx_entityname.ForceSubmit = true;

document.getElementById('psx_entityname').style.visibility = 'hidden';
document.getElementById('psx_entityname_d').style.visibility = 'hidden';
document.getElementById('psx_entityname_c').style.visibility = 'hidden';
crmForm.all.psx_displayname.ForceSubmit = true;
document.getElementById('psx_displayname').style.visibility = 'hidden';
document.getElementById('psx_displayname_d').style.visibility = 'hidden';
document.getElementById('psx_displayname_c').style.visibility = 'hidden';
 
if (crmForm.ObjectId != null)
{    
document.getElementById('psx_schemaname_d').disabled = true;
document.getElementById('psx_attributename_d').disabled = true;
} 

Download: 
Customization File

Feel free to use this application.
Either leave comment or email me if you want to know further information.

Reference:
Field Security Level With Own Hands

1 comment:

Anonymous said...

Hi, does anyone have a Cap plugin that will work with CRM2011? Thanks!

Post a Comment