[UPDATE: See version 6 of the code in this post at http://crmentropy.blogspot.com/2009/11/embedding-advanced-find-views-in-entity.html]
Well, it's been interesting seeing my code deployed on the CRM system here at work. I've run into the following bug that has been corrected in this newest version:
- The Run Workflow button on the embedded view would not function properly, because of the modal dialog function hack; corrected by adjusting the modal dialog override to return a value, and refrain from refreshing the grid.
Version 5:
/// Summary: /// Provides a mechanism for replacing the contents of any Iframe on an entity form /// with any Advanced Find view. /// /// Param Description /// ---------- ------------------- /// iFrameId The id established for the target Iframe /// entityName The name of the entity to be found by the Advanced Find /// fetchXml FetchXML describing the query for the entity /// layoutXml LayoutXML describing the display of the entity /// sortCol The schema name of the entity attribute used for primary sorting /// sortDescend "true" if sorting the sortCol by descending values, or "false" if ascending /// defaultAdvFindViewId The GUID of an Advanced Find View for the entity; may that of a saved view /// entityTypeId (Optional) The Object Type ID for the entity. Setting this causes the system /// to overwrite the functionality of the "New" button to establish related records function EmbedAdvancedFindView (iFrameId, entityName, fetchXml, layoutXml, sortCol, sortDescend, defaultAdvFindViewId, entityTypeId) { // Initialize our important variables var httpObj = new ActiveXObject("Msxml2.XMLHTTP"); var url = SERVER_URL + "/AdvancedFind/fetchData.aspx"; var iFrame = document.getElementById(iFrameId); var win = iFrame.contentWindow; var doc = iFrame.contentWindow.document; // Provide a global function within the parent scope to avoid XSS limitations // in updating the iFrame with the results from our HTTP request PushResponseContents = function (iFrame, httpObj, entityTypeId) { var win = iFrame.contentWindow; var doc = iFrame.contentWindow.document; var m_iFrameShowModalDialogFunc = null; var m_windowAutoFunc = null; // Write the contents of the response to the Iframe doc.open(); doc.write(httpObj.responseText); doc.close(); // Set some style elements of the Advanced Find window // to mesh cleanly with the parent record's form doc.body.style.padding = "0px"; doc.body.scroll="no"; // Should we overwrite the functionality of the "New" button? if ((typeof(entityTypeId) != "undefined") && (entityTypeId != null)) { var buttonId = "_MBopenObj" + entityTypeId; var newButton = doc.getElementById(buttonId); if (newButton != null) { eval("newButton.action = 'locAddRelatedToNonForm(" + entityTypeId + ", " + crmForm.ObjectTypeCode + ", \"" + crmForm.ObjectId + "\",\"\");'"); } } // Swap the showModalDialog function of the iFrame if (m_iFrameShowModalDialogFunc == null) { m_iFrameShowModalDialogFunc = win.showModalDialog; win.showModalDialog = OnIframeShowModalDialog; } if (m_windowAutoFunc == null) { m_windowAutoFunc = win.auto; win.auto = OnWindowAuto; } // Configure the automatic refresh functionality for dialogs function OnIframeShowModalDialog(sUrl, vArguments, sFeatures) { var returnVar = m_iFrameShowModalDialogFunc(sUrl, vArguments, sFeatures); if (sUrl.search(/OnDemandWorkflow/) < 0) { doc.all.crmGrid.Refresh(); } return returnVar; } function OnWindowAuto(otc) { doc.all.crmGrid.Refresh(); m_windowAutoFunc(otc); } } // Without a null src, switching tabs in the form reloads the src iFrame.src = null; // Preload the iFrame with some HTML that presents a Loading image var loadingHtml = "" + "<table height='100%' width='100%' style='cursor:wait'>" + " <tr>" + " <td valign='middle' align='center'>" + " <img alt='' src='/_imgs/AdvFind/progress.gif' />" + " <div /><i>Loading View...</i>" + " </td>" + " </tr>" + "</table>"; doc.open(); doc.write(loadingHtml); doc.close(); // Compile the FetchXML, LayoutXML, sortCol, sortDescend, defaultAdvFindViewId, and viewId into // a list of params to be submitted to the Advanced Find form var params = "FetchXML=" + fetchXml + "&LayoutXML=" + layoutXml + "&EntityName=" + entityName + "&DefaultAdvFindViewId=" + defaultAdvFindViewId + "&ViewType=1039" // According to Michael Hohne over at Stunnware, this is static + "&SortCol=" + sortCol + "&SortDescend=" + sortDescend; // Establish an async connection to the Advanced Find form httpObj.open("POST", url, true); // Send the proper header information along with the request httpObj.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); httpObj.setRequestHeader("Content-length", params.length); // Function to write the contents of the http response into the iFrame httpObj.onreadystatechange = function () { if (httpObj.readyState == 4 && httpObj.status == 200) { parent.PushResponseContents(iFrame, httpObj, entityTypeId); } } // Set it, and forget it! httpObj.send(params); }
No comments:
Post a Comment
Unrelated comments to posts may be summarily disposed at the author's discretion.