Now that you understand the framework and the details of the Microsoft Dynamics CRM scripting SDK, we want to get into the fun of coding examples and real-world uses of these features. We included a variety of script samples for reference and to provide a starting pointfor your own customization needs. The following examples offer just a sampling of the manyways in which you can integrate custom logic by using scripting:
Display customer information in a tooltip.
Set the form’s title at run time.
Enhance the form’s display.
You can use each of the examples discussed with any deployment of Microsoft Dynamics CRM, including CRM Online. Chapter 15, contains more scripting samples and utilities for your use.
Most of the sample scripts use DOM properties or methods not available with the CRM SDK and therefore might not upgrade to future versions of Microsoft Dynamics CRM.
The first example demonstrates a simple technique for displaying related information about a customer by using Internet Explorer’s tooltip functionality. An element’s tooltip displays information when a user places the mouse over it. Figure 7-9 shows an example of what the user sees when she hovers her mouse over the Potential Customer label on an Opportunityform after you apply the code in Example 7-4.
The script in Example 7-4 retrieves some information about the customer by constructing a SOAP message. It then concatenates the result to a string to be applied to the title property of the potential customer label (customerid_c).
The script can be immediately used on an Opportunity or a Case form because both entities use a Customer field. Remember to apply the script to both the onLoad event as well as the onChange event of the Customer attribute. You can also use this approach with any related field, including custom relationships, or extend it to display additional information.
Example 7-4. Display customer information from a customer label
var CRM_FORM_TYPE_CREATE = 1; var CRM_FORM_TYPE_UPDATE = 2; var CRM_FORM_TYPE_READONLY = 3; switch (crmForm.FormType) { case CRM_FORM_TYPE_CREATE : case CRM_FORM_TYPE_UPDATE : case CRM_FORM_TYPE_READONLY : var customer = new Array; customer = crmForm.all.customerid.DataValue; if (customer != null) { var customerId = customer[0].id; var typeName = customer[0].typename; var details = RetrieveCustomerDetails(customerId, typeName); if (details != null) { crmForm.all.customerid_c.title = BuildCustomerDetails(details); } } } function BuildCustomerDetails(customerDetails) { // Create a new DOM document and load the response XML var doc = new ActiveXObject("MSXML2.DOMDocument"); doc.async = false; doc.loadXML(customerDetails); var result = ""; // Return the q1:telephone1 node var telephone1Node = doc.selectSingleNode("//q1:telephone1"); if( telephone1Node != null ) result += "Telephone: " + telephone1Node.text + " "; // Return the q1:address1_line1 node var address_line1Node = doc.selectSingleNode("//q1:address1_line1"); if( address_line1Node != null ) result += "Address: " + address_line1Node.text; // Return the q1:address1_city node var address_cityNode = doc.selectSingleNode("//q1:address1_city"); if( address_cityNode != null ) result += ", " + address_cityNode.text; // Return the q1:address1_stateorprovince node var address_stateorprovinceNode = doc.selectSingleNode("//q1:address1_stateorprovince"); if( address_stateorprovinceNode != null ) result += ", " + address_stateorprovinceNode.text; // Return the q1:address1_postalcode node var address_postalcodeNode = doc.selectSingleNode("//q1:address1_postalcode"); if( address_postalcodeNode != null ) result += " " + address_postalcodeNode.text; return result; } // Return additional customer details for a record function RetrieveCustomerDetails(customerId, typeName) { // Define URL to CRM API service var serverUrl = "/MSCrmServices/2007/CrmService.asmx"; // Set up XMLHTTP request var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); xmlhttp.open("POST", serverUrl, false); xmlhttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8") xmlhttp.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/crm/2007/WebServices/Retrieve") // Define the retrieve message var message = [ "<?xml version='1.0' encoding='utf-8'?>", "<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" ", "xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ", "xmlns:xsd="http://www.w3.org/2001/XMLSchema">", GenerateAuthenticationHeader(), "<soap:Body>", "<Retrieve xmlns='http://schemas.microsoft.com/crm/2007/WebServices'>", "<entityName>", typeName, "</entityName>", "<id>", customerId, "</id>", "<columnSet xmlns:q1='http://schemas.microsoft.com/crm/2006/Query' xsi:type='q1: ColumnSet'>", "<q1:Attributes><q1:Attribute>address1_line1</q1:Attribute>", "<q1:Attribute>address1_city</q1:Attribute>", "<q1:Attribute>address1_stateorprovince</q1:Attribute>", "<q1:Attribute>address1_postalcode</q1:Attribute>", "<q1:Attribute>telephone1</q1:Attribute></q1:Attributes>", "</columnSet>", "</Retrieve>", "</soap:Body>", "</soap:Envelope>" ].join(""); xmlhttp.send(message); return xmlhttp.responseXML.xml; }
An entity’s form title is always in the format Entity: [Primary Attribute Value]. While this format works fine in most situations, you might find that you want a more descriptive title based on information gathered at run time. Figure 7-10 shows an example of changing the title of an account record to include the account number.
To use this example, add the code in Example 7-5 to the onLoad event of the Account form.
Example 7-5. Setting the Account form’s title at run time
var CRM_FORM_TYPE_UPDATE = 2; var CRM_FORM_TYPE_UPDATE = 2; var CRM_FORM_TYPE_READ_ONLY = 3; // Only set the title if the form is in update or read-only mode if ( (crmForm.FormType == CRM_FORM_TYPE_UPDATE) || (crmForm.FormType == CRM_FORM_TYPE_READ_ONLY) ) { var cells = document.getElementsByTagName("span"); // Only continue if the account number has a value if (crmForm.all.accountnumber.DataValue != null) { // Loop through the span elements for the ms-crm-Form-Title class style for (var i = 0; i < cells.length; i++) { if (cells[i].className == "ms-crm-Form-Title") { cells[i].innerText = "Account: " + crmForm.all.accountnumber.DataValue + " - " + crmForm.all.name.DataValue; break; } } } }
Microsoft Dynamics CRM forms provide a standard way to display data to users. A system administrator has the ability to alter the form’s layout, including adding tabs, sections, and fields. However, the Microsoft Dynamics CRM form editor does not permit you to change the color or graphical design. But because you have full access to the form’s DOM, you can altervarious elements on the form to provide a more visually appealing display.
In this next sample, you will add a color-coded bar across the opportunity entity to quicklyinform the user of the Opportunity’s rating. The script changes the bar’s color based on the selected Rating value of the Opportunity. As you will quickly see, the code can easily be extended for many useful scenarios. Figure 7-11 shows the colored bar across the top of theGeneral tab. The bar is displayed in red when the Rating value equals Hot.
To complete this sample, follow these straightforward steps:
Add a notification bar to the Opportunity form
On the Opportunity entity, create a new one-character nvarchar attribute called Notification.
Add the Notification attribute to the top of the Opportunity form on the first tab.
Update the Notification attribute properties on the form by turning off the label display and have the attribute span two columns.
Add the following script to the form’s onLoad event and the customerratingcode attribute’s onChange event.
UpdateDisplayBar(); function UpdateDisplayBar() { var notificationDisplay = document.getElementById("new_notification_d"); var displayColor = "#EAF3FF"; switch (crmForm.all.opportunityratingcode.DataValue) { case "1": displayColor = "red"; break; case "2": displayColor = "yellow"; break; case "3": displayColor = "blue"; break; } var displayBar = "<div style='background=" + displayColor + "'> </div>"; notificationDisplay.innerHTML = displayBar; }
Save and publish your changes.