Examples
The following examples represent some possibilities for customization or extending Microsoft Dynamics CRM when you don't need to worry about security outside of your domain.
Example One: Formatting the Phone Number
When entering a phone number into the system, no formatting logic/mask is applied to the entered number. Not having a formatting mask is helpful if you need to enter a phone number and an extension (such as 916-712-5451, ext: 001), but a properly formatted phone number adds to both human and integrated system readability.
Figure 3.9 shows a standard CRM Account form with a freely entered telephone in the Main Phone field.
Figure 3.9 Microsoft Dynamics CRM with regular phone entry.
To add formatting to this field, place the following code in the Account form onLoad event. (Be sure the event is enabled.)
phoneFieldValidationFun = function (source) { var oField = source; if (!IsNull(oField)) { if(IsNull(oField.DataValue)) { return; } var sUSPhone = oField.DataValue.replace(/[^0-9]/g, ""); // Check the length and format as necessary switch (sUSPhone.length) { case "19167125451".length: oField.DataValue = "+1 ("+ sUSPhone.substr(1, 3) + ") " + sUSPhone.substr(4, 3) + "-" + sUSPhone.substr(7, 4); break; case "9167125451".length: oField.DataValue = "("+ sUSPhone.substr(0, 3) + ") " + sUSPhone.substr(3, 3) + "-" + sUSPhone.substr(6, 4); break; case "167125451".length: oField.DataValue = "(0"+sUSPhone.substr(0, 2)+") " + sUSPhone.substr(2, 3) + "-" + sUSPhone.substr(5, 4); break; case "7125451".length: oField.DataValue = sUSPhone.substr(0, 3) + "-" + sUSPhone.substr(3,4); break; } } }
Now place the following code for each phone field (using the onChange event):
phoneFieldValidationFun(event.srcElement);
Applying the preceding code to the onChange event of the fields that need to be formatted with phone numbering will properly format the phone number entry, as shown in Figure 3.10.
Figure 3.10 Microsoft Dynamics CRM with formatted phone entry.
This example clearly shows how to format data simply and easily on data entry. It would be a trivial matter to apply error handling and formatting for other fields by modifying the example shown.
Example Two: Validating Data Across the CRM Application
It is common to be working with Microsoft Dynamics CRM and need to query/validate entered data against another entity's data. A common example is when a Parent Customer or Primary Contact is selected for the Contact or Account records, but it could be used in a number of situations. Other common scenarios include the following:
- Populating data on the account for invoice quantities and/or amounts (if you wanted to use CRM to show total orders/amounts)
- Updating subordinate records such as Opportunities, Quote, Orders, or Invoices with information entered on the Account level
- Modifying Account data based on case status
This example shows how to check the related Account record of the Contact and validate phone numbers. If they differ, the system prompts the user as to whether the user wants to update the Contact record with the main phone number from the Account.
Place the following code on the Parent Customer field of the Contact entity using the JavaScript onChange event to call an asynchronous event to query the CRM database and update/validate a value based on a user selection:
//Check to see if the parentcustomer is populated if(crmForm.all.parentcustomerid.DataValue != null) { if(crmForm.all.parentcustomerid.DataValue[0].type == '1') { var xml = "" + "<?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>" + " <RetrieveMultiple xmlns=\"http://schemas.microsoft.com/crm/2007/WebServices\">" + " <query xmlns:q1=\"http://schemas.microsoft.com/crm/2006/Query\" xsi:type=\"q1:QueryExpression\">" + //Query against the account entity " <q1:EntityName>account</q1:EntityName>" + " <q1:ColumnSet xsi:type=\"q1:ColumnSet\">" + " <q1:Attributes>" + //Check the telephone1 attribute – this can be modified to //check any of the telephone fields that exist " <q1:Attribute>telephone1</q1:Attribute>" + " </q1:Attributes>" + " </q1:ColumnSet>" + " <q1:Distinct>false</q1:Distinct>" + " <q1:Criteria>" + " <q1:FilterOperator>And</q1:FilterOperator>" + " <q1:Conditions>" + " <q1:Condition>" + " <q1:AttributeName>accountid</q1:AttributeName>" + " <q1:Operator>Equal</q1:Operator>" + " <q1:Values>" + " <q1:Value xsi:type=\"xsd:string\">"+ crmForm.all.parentcustomerid.DataValue[0].id + " </q1:Value>" + " </q1:Values>" + " </q1:Condition>" + " </q1:Conditions>" + " </q1:Criteria>" + " </query>" + " </RetrieveMultiple>" + " </soap:Body>" + "</soap:Envelope>" + ""; var xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP"); xmlHttpRequest.Open("POST", "/mscrmservices/2007/CrmService.asmx", false); xmlHttpRe- quest.setRequestHeader("SOAPAction","http://schemas.microsoft.com/crm/2007/WebServices/RetrieveMultiple"); xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8"); xmlHttpRequest.setRequestHeader("Content-Length", xml.length); xmlHttpRequest.send(xml); var resultXml = xmlHttpRequest.responseXML; //alert(resultXml.xml); var accountMainPhone = re sultXml.selectSingleNode("//BusinessEntity/q1:telephone1"); if(accountMainPhone != null) { var contactBusinessPhone = crmForm.all.telephone1; //Validate the contact business phone against the account phone if(contactBusinessPhone.DataValue != accountMainPhone.text) { //If not equal then prompt to change it if(confirm("Account Main Phone is not equal to Contact Business Phone. Would you like to change it?")) { //User responded affirmatively, so let's update the contact //phone with the account phone information contactBusinessPhone.DataValue = accountMainPhone.text; } } } } }
Figure 3.11 shows what happens when you try to set the Parent Customer of a Contact record. The code checks the Business Phone of the Contact against the Main Phone of the Account and prompts for updating of the Contact record.
Figure 3.11 Microsoft Dynamics CRM with validation across multiple entities.
This example can easily be applied across other entities within the CRM system and is a common request to extend functionality internally.
Example Three: Extending a Form for IFrame Integration
As mentioned previously, there are several considerations when working with IFrames, including the fact that IFrames load asynchronously and are shared across all clients. This example checks whether the user is working offline, and if not, sets the target of the IFrame dynamically.
To follow this example, create a new IFrame on the Contact entity, and set the URL on the IFrame URL equal to about:blank. This will open the IFrame to a blank page by default.
Modify the onLoad event for the form and add the following code:
Var sURLString = ""; //Validate if the user is offline or not if(IsOnline()) { //Check to see if the form is saved or just being created switch (crmForm.FormType) { //Form is being created – we can't pass anything yet case 1: //Set to our generic intranet site sURLString = "http://intranet"; break; //Form is saved and we have data we can grab case 2: //Set to the intranet site with content specific to the contact sURLString = "http://intranet?contact="; //encode and add contact information sURLString += encodeURIComponent(crmFORM.all.name.DataValue); break; } } //User is not online else { //We can leave the URL as about:blank or change it to an //internal URL if we want } //Finally set the IFrame URL (be sure to replace <<name>> with the name of //your IFrame: crmForm.all.IFRAME_<<name>>.src = sURLString;
If the user is online, the intranet site is displayed.