A Dynamics CRM Blog
Random ramblings on CRM and sundry topics

Displaying CRM Views in IFRAMES

Thursday, 13 November 2008 03:21 by James Downey

Recently I needed to display a CRM view in an IFRAME and built a solution using the approach outlined by Michael Michael Höhne's on his blog. Michael was himself building upon an idea suggested by Stefan on the CRM newsgroup microsoft.public.crm.developer. I've made a slight addition to this technique that I'd like to share with the community.

As is noted in Michael's article, it is fairly easy to display an associated view in an IFRAME, but since each entity supports only one associated view and it is not possible to customize the filter, the use of an associated view will not always meet the requirements.

A more flexible approach is based on Advanced Find, which builds a query by forming an HTTP POST request that returns a set of records in a view. The form elements included in the post define the FetchXML query, which determines which rows get returned, as well as the layout of the columns.

After defining an Advanced Find, you can extract the form elements by placing javascript:alert(resultRender.outerHTML) in the address bar and looking for the resultRender form. Another way to get at the resultRender form is to use the IE developer toolbar. After extracting the resultRender form, insert it into an html page with an onload event that posts it to /AdvancedFind/fetchData.aspx. You can then reference this html page in an IFRAME to display it on a CRM form.

However, you will frequently need to make the view dynamic by displaying only the records related to another entity, such as all of the contacts related to an account. Michael suggests using an ASP.NET page that would accept the parent record id and insert it into the FetchXML query. I took a somewhat different approach and used JavaScript to accomplish the same task.

Here are the steps:

1) Open the Advanced Find window and click Ctrl-N to open the browser with the menu. Define an Advaned Find query for Contact (or any other entity) and set the Parent Customer (or any other field that you need to filter by) to equal a specific customer. Make sure to define the columns by clicking Edit Columns.

2) Click on the icon for the IE developer toolbar. (Download the toolbar from http://www.microsoft.com/downloads/details.aspx?familyid=e59c3964-672d-4511-bb3e-2d5e1db91038&displaylang=en.) Right-click on the element <FORM id=resultRender> and select Element Source.

3) Copy all of the elements between the <FORM> and </FORM> tags.

4) Paste the form elements into the html page below between the FORM tags in the html below.

<html>
<head>
<SCRIPT LANGUAGE="JavaScript" SRC="ViewFunctions.js">
</SCRIPT>
<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">
</head>

<body onload="setKey('id');resultRender.submit();">
        <FORM id=resultRender action="/AdvancedFind/fetchData.aspx" method="post">

     
        </FORM>
    </body>
</html>

5) Find the Condition element that contains the GUID for the account. Delete the uiname attribute and replace the GUID (including the braces) with __ID.

Before: <condition attribute='parentcustomerid' operator='eq' uiname='Blue Yonder Airlines' uitype='account' value='{D44D44AD-36D0-DC11-AA32-0003FF33509E}'/>

After: <condition attribute='parentcustomerid' operator='eq' uitype='account' value='__ID'/>

6) Save the html file to a subdirectory under the ISV folder on your CRM web server.

7) Save the following JavaScript code into a .js file named ViewFunctions.js and save it to the same directory as the html page.

function PageQuery(q) {
 if(q.length > 1) this.q = q.substring(1, q.length);
 else this.q = null;
 this.keyValuePairs = new Array();
 if(q) {
  for(var i=0; i < this.q.split("&").length; i++) {
   this.keyValuePairs[i] = this.q.split("&")[i];
  }
 }
 this.getKeyValuePairs = function() { return this.keyValuePairs; }
 this.getValue = function(s) {
 for(var j=0; j < this.keyValuePairs.length; j++) {
  if(this.keyValuePairs[j].split("=")[0] == s)
   return this.keyValuePairs[j].split("=")[1];
  }
  return false;
 }
 this.getParameters = function() {
 var a = new Array(this.getLength());
 for(var j=0; j < this.keyValuePairs.length; j++) {
  a[j] = this.keyValuePairs[j].split("=")[0];
 }
 return a;
 }
 this.getLength = function() { return this.keyValuePairs.length; }
}

function queryString(key){
 var page = new PageQuery(window.location.search);
 return unescape(page.getValue(key));
}

function setKey(id){
 var id = queryString(key);
 var fetch = resultRender.FetchXml.value;
 fetch=fetch.replace(/__ID/g,id);
 resultRender.FetchXml.value=fetch;
}

8) Place an IFRAME and your form and set the URL property to the html file. Make sure to check the "Pass record object-type code" check box.

After publishing, the result looks like the screen below.

By way of warning, this is not a supported customization because it depends upon the html structure in Dynamics CRM. When it comes time to migrate to CRM 5.0, these views may break. On the other hand, it is a fast and powerful technique for meeting many business requirements without writing custom Asp.Net pages. When CRM 5.0 is released, keep tuned to the newsgroup and blogs on ways to make this customization work in the new version.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

CRM 4.0 Version of FetchXML Builder Released (Finally)

Monday, 10 November 2008 14:50 by James Downey

I have finally updated FetchXML Builder with a few new features including IFD authentication support and the ability to auto-generate code for using QueryExpression.

This version was built against the CRM 4.0 web services but I have kept the CRM 3.0 version on the site for those organizations that have not yet upgraded.

FetchXML Builder is an interactive query builder for constructing and testing FetchXML statements. FetchXML is an XML-based query language for retrieving data through the Dynamics CRM web services.

Although FetchXML is not as powerful as SQL, it has certain advantages when used in CRM development. Unlike the QueryExpression class, FetchXML can be used to retrieve attributes from multiple entities. And unlike filtered views, FetchXML makes use of the CRM web services and does not require passing end user credentials to the SQL Server, which in some scenarios requires the configuration of Kerberos.

As a rule of thumb, I'd recommend using the QueryExpression class if you do not need to retrieve attributes from more than one entity. It is faster than FetchXML and it also uses the web services. If QueryExpression will not work, then go with FetchXML. If the query is too complex to form with FetchXML, you will need write a SQL statement to call the filtered views, which are database views in SQL Server that filter results based on the user's identity.

FetchXML Builder is a useful tool regardless of whether you will use QueryExpression, FetchXML or filtered views. Use the controls on the form to formulate a query. Click the Create FetchXML button to generate a FetchXML statement. Click Run Query to test it. Click on Create Code to copy either C# or VB.Net QueryExpression code to the clipboard. If you need to write a SQL statement, use the tool to discover the relationships between entities and the schema names, which will be helpful in writing the SQL.

Download FetchXML Builder

Currently rated 5.0 by 2 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Categories:   FetchXML
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed