IFrames and Scripting


Microsoft CRM allows you to add an IFrame (also known as an inline frame) to the form of an entity. Chapter 5 introduced IFrames and described how to set up a simple IFrame within a form, but now we'll go into the details of how to really take advantage of this powerful feature with client-side customization techniques. The IFrame feature creates tremendous integration and customization opportunities for a developer within Microsoft CRM. Because you can programmatically access an IFrame document from the Microsoft CRM form through the DOM, your enhancements can appear seamless to the user. Figure 10-3 shows a sample IFrame that references a Windows SharePoint Services Web site.

image from book
Figure 10-3: IFrame sample

IFrames can reference any URL or Web page, whether they are hosted on your Web server or any other any Web server. Common uses might include displaying SharePoint sites, adding mapping functionality through external Web sites, and custom application integration.

Caution 

Remember that Microsoft CRM laptop client for Outlook users can work offline, so they might experience an issue with a form if the IFrame references a Web page that they can't access offline. Therefore, don't include any key functionality that offline users will require within an IFrame.

Security

We couldn't possibly provide a comprehensive analysis on Web application security within the scope of this book, but we want to briefly touch upon the notion of Microsoft CRM cross-site scripting and its IFrame-related security issues. Cross-site scripting provides a powerful (and potentially dangerous) feature within Web applications, including Microsoft CRM. In most cases, DHTML and the user's browser settings permit scripting access to and from IFrame documents that reside on the same domain and reference matching protocols (such as FTP, HTTP, or HTTPS).

For example, consider an HTML document called Main.htm located on the www.adatum.com domain (http://www.adatum.com/main.htm). The Main.htm page includes an IFrame that references a second Web page named Frame.htm. The protocol in this example is HTTP for both pages, and because they both reside on the same domain, the browser will permit the scripts from the Frame.htm page to access and manipulate content on the Main.htm document. Internet Explorer will disable scripting access to IFrame URLs that refer to a page on another domain or reference the page through a different protocol. So if the IFrame source was https://www.adatum.com/frame.htm (accessed by using the SSL protocol) or http://www.contoso.com/frame.htm (located on another domain), Internet Explorer will prevent script access between the pages. Figure 10-4 shows a graphical representation of this.

image from book
Figure 10-4: Default Internet Explorer IFrame security

In addition to the default Internet Explorer security behavior, Microsoft CRM allows you to add another layer of security with its Restrict cross-frame scripting setting. This option will set the value of the security attribute of the IFrame tag to restricted. Under default conditions, this setting will have the following affects:

  • Restricts JavaScript and VBScript from executing on the IFrame page

  • All hyperlinks will open in a new browser window

So even if Internet Explorer would have allowed cross-frame scripting, you can disable this for a specific IFrame in Microsoft CRM. By default, Microsoft CRM restricts cross-frame scripting on new IFrame pages. So if you want your scripts to run, you must uncheck the cross-frame scripting setting. Obviously, we recommend that you leave the default setting of not allowing cross-frame scripting for security purposes unless you have a specific need for this feature.

CRM IFrame Scripting Example

We will now demonstrate how the domain and Microsoft CRM IFrame property settings affect the form's display and scripting capabilities between the IFrame document and the Microsoft CRM Contact form. In this example, we will integrate a custom Web page that calculates monthly mortgage payments. The custom Web page within the IFrame will take values entered by a user, calculate the correct mortgage payment, and then populate that payment value back into a native Microsoft CRM field.

The resulting form should look like Figure 10-5.

image from book
Figure 10-5: Contact form with custom mortgage Web page

Adding Attributes

For this example, we need to add a new attribute (Mortgage Amount) to the Contact entity.

  1. Browse to the Customization area of Microsoft CRM and double-click the Contact entity. Click Attributes in the navigation pane.

  2. Add a money attribute called mortgagepayment (the schema name will be new_mortgagepayment, provided that you haven't changed your default schema name prefix).

  3. Type Mortgage Payment in the Display Name box.

  4. Change the Type field to money. Leave the money value defaults and click Save and Close.

Modifying the Form
  1. In the navigation pane, click Forms and Views, and then click Form to open the Form Editor window.

  2. Add a new tab called Mortgage on the Contact form. This tab will contain an automatically expanding IFrame that points to a custom HTML page and two currency fields.

  3. Add a section called Mortgage Info. Select both the label and the divider line options.

  4. Add the new Mortgage Payment field that you just created.

  5. Add a section called iframe. This section will contain an automatically expanding IFrame.

  6. Select the newly created section, and then click the IFrame link. We will vary the properties of the IFrame to see the impact that they have on the form. Initially, set the following properties:

    1. Name: test

    2. URL: http://<crmserver>/workingwithcrm/mortgage.htm. (Note that <crmserver> should be replaced with the name of the server on which CRM is installed. We will explain how to deploy the mortgage.htm file next.)

    3. Label: Leave blank.

    4. Security: Clear the Restrict cross-frame scripting check box. We will start by allowing the two pages scripting access, so that the IFrame page can update a field on the Microsoft CRM form.

  7. Switch to the Formatting tab, and set the following properties:

    1. Number of Rows: Select Automatically expand to use available space.

    2. Scrolling: Select Never. We have created a form to mirror the existing Microsoft CRM form. If we allow scrollbars, Internet Explorer will allocate space for this, shifting our IFrame form, as shown in Figure 10-6.

    3. Border: Clear Display Border. As with scrolling, we don't want to alert users that they are looking at a different page. We want to create the illusion that they are working on the native Microsoft CRM form.

  8. Switch to the Dependencies tab, select Mortgage Amount and Mortgage Payment, and make them dependent.

image from book
Figure 10-6: IFrame with automatic scrolling enabled and a border displayed

image from book
Blending an IFrame Web Page with the Microsoft CRM Form

In our mortgage calculator example, we want the users to believe they are using one form. We don't want (or need) them to know that some of the fields on the Mortgage tab are actually hosted within an IFrame. Therefore, it's important that we modify the IFrame settings to make our page blend in as much as possible.

Figure 10-6 shows how the IFrame page would look with the border enabled and scrolling set to As Necessary. If you look to the right, Microsoft CRM automatically allotted space for a scrollbar should it need it. Therefore, the Interest Rate and Mortgage Payment fields in our IFrame shift to the left and they don't line up with the native Mortgage Payment form field. In addition, with the border enabled, a blue outline frames our IFrame page.

Since we like our Web pages and forms neat and tidy with all of the fields lined up correctly, we're going to tweak the IFrame configuration options. By setting the scrollbars to Never and disabling the border, we can then format our custom IFrame Web page to blend in with the Microsoft CRM form, creating the illusion of one page and a consistent interface to the user, as shown back in Figure 10-5.

image from book

Custom HTML Page

Now we need to create the custom Mortgage.htm Web page that contains the mortgage calculator within the IFrame. The Web page takes three financial inputs and then it calculates a monthly mortgage payment by using a custom JavaScript method. It then attempts to write the value back to the CRM form, allowing it to be saved with the Contact record.

You should take note of the following in regards to the Mortgage.htm file:

  • The styles of the custom Web page mirror those of the native Microsoft CRM form. This allows us to seamlessly integrate our IFrame page into the form.

  • This example includes a simple JavaScript page, but you can create much more sophisticated Web pages within an IFrame.

  • Our custom page will also contain a Mortgage Payment field to demonstrate the interaction between the Microsoft CRM form and the custom Web page.

  • The script attempts to send the monthly payment result back to the Microsoft CRM form. The Microsoft CRM form is unnamed, but it will always be the first item in the forms collection. So, you can reference it with the following syntax:

     parent.document.forms[0] 

  • For this example, we use a submit button on the custom page. In the "Client-Side Code Examples" section later in this chapter, the "Saving an IFrame Form from Microsoft CRM" sample shows how you can also use cross-frame scripting to force a submit event of your custom page.

The code for the Mortgage.htm page is shown in Listing 10-1.

Listing 10-1: mortgage.htm HTML Code:

image from book
 <html> <head>  <title>Mortgage Calculator</title>  <script type="text/javascript" language="javascript">  /// <summary>  /// calculate() takes a mortgage amount, an interest rate, and a term in years  /// and calculates what the monthly mortgage payments will be  /// </summary>  function calculate()   {   // Gather inputs from form   var mortgageamount = document.crmForm.mortgageamount.value;   var interestrate = document.crmForm.interestrate.value;   var term = document.crmForm.term.value;   // Calculate payment and assign to field on form   var mortgagepayment = calculatePMT(interestrate, term * 12, mortgageamount)   document.crmForm.mortgagepayment.value = mortgagepayment;   // Also assign back to the Microsoft CRM form   parent.document.forms[0].all.new_mortgagepayment.DataValue = mortgagepayment;  }  /// <summary>  ///  calculatePMT() simulates the financial PMT routine and is used to determine monthly payments  /// </summary>  /// <param name="rate">Annual interest rate</param>  /// <param name="nummonths">Length of term in months</param>  /// <param name="presentvalue">Amount to finance</param>  function calculatePMT(rate, nummonths, presentvalue)  {   var intRate = rate /100 / 12;   var pmt = Math.floor((presentvalue*intRate)/(1-Math.pow(1+intRate,(-1*nummonths)))*100)/100;   return pmt;  }  </script> <style type="text/css">  body { font-size:11px; font-family:"Tahoma,Verdana"; margin:0px; border:0px; background- color:#eef0f6; cursor:default; }  td { font-size:11px; font-family:"Tahoma,Verdana"; }  td.sec { width:100%; color:#000000; font-weight:bold; padding-left:0px; padding- bottom:2px; text-overflow:ellipsis; overflow:hidden; }  td.bar { border-bottom:1px solid #000000; }  td.req { font-weight:bold; color:#9f2409; overflow:hidden; text-overflow:ellipsis; padding-top:5px; }  td.rec { font-weight:bold; color:#466094; overflow:hidden; text-overflow:ellipsis; padding-top:5px; }  table.layout { table-layout:fixed; width:100%; }  input { font-size:8pt; width:100%; height:19px; border:1px solid #7b9ebd; }  button { filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, StartColorStr= #ffffff, EndColorStr=#cecfde); cursor:hand; font-size:11px; padding-left:5px; padding-right: 5px; border:1px solid #7b9ebd; } </style> </head> <body> <form  name="crmForm" action="iframe-example.htm" method="get"> <div style="padding:0px;"> <table  cellspacing="0" cellpadding="3" border="0" >  <col width="115"/><col/><col width="135" style="padding-left:20px;"/><col/>  <tr>   <td>Mortgage Amount ($)</td>   <td><input type="text"  name="mortgageamount" value="500000" /></td>   <td>Interest Rate (%)</td>   <td><input type="text"  name="interestrate" value="6.0" /></td>  </tr>  <tr>   <td>Term (yrs)</td>   <td><input type="text"  name="term" value="30" /></td>   <td>Mortgage Payment ($)</td>   <td><input type="text"  name="mortgagepayment" value="" /></td>  </tr>  <tr>   <td>&nbsp;</td>   <td><input type="button"  name="btnSubmit" value="Calculate" onclick= "calculate();" /></td>  </tr> </table> </div> </form> </body> </html> 
image from book

For this example, we will reuse the workingwithcrm virtual Web. (Instructions on creating this can be found in the Introduction.) After you complete the page, you must deploy it to the location specified by the IFrame URL property (the <crmserver>/workingwithcrm/ directory). Copy the Mortgage.htm file to C:\Inetpub\workingwithcrm on your Microsoft CRM Web server, using whatever method is easiest (such as xcopy or FTP).

After you save the form, you can preview it to see the results. Using the Create Form preview functionality, we can also test how the Restrict cross-frame scripting setting works. Enter some values into the mortgage calculator and click Calculate. You will see that both Mortgage Payment ($) fields on the custom page and the native Microsoft CRM form update, as shown in Figure 10-7.

image from book
Figure 10-7: Mortgage tab preview

Also, notice that with the border turned off and the scrolling set to Never, the form looks as if it is part of the native page. Because we allowed cross-frame scripting in our IFrame properties, we can execute the custom page's JavaScript routines. Also, since we deployed and referenced the page using the same domain and protocol as the Microsoft CRM server, we will be able to access elements on the Microsoft CRM form and populate our monthly payment results back to Microsoft CRM.

What would happen if we restricted cross-frame scripting? Figure 10-8 shows that when the Calculate button is clicked, the IFrame's monthly payment field was not populated. The Microsoft CRM form also remains blank, and no error message is displayed. All scripting on the custom IFrame page was disabled and prevented from executing.

image from book
Figure 10-8: Mortgage tab with cross-frame scripting disabled

Important 

Remember that when you disable cross-site scripting in Microsoft CRM, your referenced IFrame page will also be restricted from running any scripts (even if those scripts don't try to go cross-frame into Microsoft CRM).

Let's enable cross-frame scripting again but move the IFrame form to another server and access it in a different URL domain. We will update the URL property of the IFrame to http://crmserver2/workingwithcrm/iframe-example.htm. Then we preview the form and try the mortgage calculation again. The mortgage payment field correctly populates, but a script error appears in the browser (similar to the one shown in Figure 10-9). Internet Explorer displays the access denied message because it doesn't allow scripting across two Web pages hosted on different domains: crmserver and crmserver2.

image from book
Figure 10-9: Scripting access denied error

Of course, you could accomplish this particular mortgage calculation example by using alternate methods. For example, you could simply add the mortgage fields from the IFrame to the native Contact form and use the onChange event to do the same calculations. Another option would be to add the fields to the native form and call a Web service or Web page from the onChange event. With simple business logic, you really don't need the overhead of a custom IFrame, but you can see that with more complex situations, the IFrame element with cross-frame scripting can be a valuable tool.

Dynamic IFrame URLs

Even though you enter a URL address for an IFrame when you add it to a form, you can still programmatically change this URL on the fly. For example, you might need to change the IFrame URL based on user form selections, or even update the protocol of the URL based on the protocol of Microsoft CRM. To do this, you can update the src property of the IFrame from either the onLoad, onSave, or onChange events. The code would look like:

 crmForm.all.<iframe_name>.src = <URL reference> 




Working with Microsoft Dynamics CRM 3.0
Working with Microsoft Dynamics(TM) CRM 3.0
ISBN: 0735622590
EAN: 2147483647
Year: 2006
Pages: 120

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net