MSCRM 4.0: Añadir una consulta FetchXML en un IFrame

15 01 2012

Recupero este articulo que publiqué el 16/02/2010 en el blog interno de Qurius por si os es de interés.

En un artículo anterior hemos hablado de cómo mostrar en un IFrame la vista asociada de una entidad relacionada. La vista asociada de una entidad muestra los registros activos relacionados de la entidad relacionada, es decir, muestra una selección de los registros de la entidad relacionada filtrando por el campo relacionado y por el estado activo. Sin embargo, en mucha ocasiones pueda interesarnos mostrar los registros resultantes de una consulta más compleja en un formulario de detalle (en este caso pudiendo ser los registros resultantes de una entidad relacionada o no con la entidad del formulario). A continuación transcribo el código utilizado para mostrar una consulta avanzada (mediante Fetch) en un IFrame.

Figura1. Ejemplo de aplicación del visor de búsquedas avanzadas en un IFRAME

El código siguiente consta de una función principal, ConfigFetchIFrame, que podemos llamar desde el evento OnLoad de un formulario en el que hayamos creado un IFRAME donde queremos insertar el resultado de nuestra consulta. Este código podemos insertarlo en el propio evento OnLoad del formulario o bien, de forma no soportada, en el archivo Global.js o bien, en un archivo .js e inyectando el código (en un artículo posterior mostraré como inyectar el código de un archivo js en un evento de CRM). La función ConfigFetchIFrame utiliza los parámetros siguientes:

iFrame: Nombre de esquema del iframe donde queramos mostrar la vista avanzada
entityCode: Identificador de la entidad de los registros resultantes de la consulta
entityName: Nombre de esquema de la entidad de los registros resultantes de la consulta
tabNum: Identificador del tabulador del formulario donde se ubica el iframe
fetch: Consulta fetch
layout: Formato del resultado

En el ejemplo usado en este artículo los parámetros fetch y layout se obtienen de las funciones getFetchXml y getLayoutXml. Como observareis el formato XML de la consulta fetch y del formato del resultado se pueden obtener fácilmente creando una consulta avanzada y guardándola. Posteriormente, desde la base de datos podemos obtener tanto el fetch usado por la consulta como el layout. En este ejemplo observareis que en el fetch se añade dinámicamente el valor de uno de los parámetros de la consulta.

ConfigFetchIFrame = function(iFrame, entityCode, entityName, tabNum, fetch, layout) {
window.fetchContacts = new FetchViewer(iFrame);
fetchContacts.WithParentContext = true;
fetchContacts.EntityCode = entityCode;
fetchContacts.FetchXml = fetch;
fetchContacts.LayoutXml = layout;
fetchContacts.Entity = entityName;
fetchContacts.QueryId = "{00000000-0000-0000-00AA-000000666400}";
fetchContacts.RegisterOnTab(tabNum);
}
getFetchXml = function() {
return '<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false"><entity name="contact"><attribute name="fullname"/><attribute name="telephone1"/><attribute name="contactid"/><order attribute="fullname" descending="false"/><filter type="and"><condition attribute="parentcustomerid" operator="eq" uitype="account" value="' + crmForm.ObjectId + '"/></filter></entity></fetch>';
}
getLayoutXml = function() {
return '<grid name="resultset" object="2" jump="lastname" select="1" icon="1" preview="1"><row name="result" id="contactid"><cell name="fullname" width="300" /><cell name="telephone1" width="125" /></row></grid>';
}
FetchViewer = function(iframeId) {
var Instance = this;
var vDynamicForm;
var m_iframeTab;
var m_iframeDoc;
var m_iframeShowModalDialogFunc = null;
var m_windowAutoFunc = null;
Instance.WithParentContext = false;
Instance.EntityCode = 0;
Instance.Entity = "";
Instance.Iframe = null;
Instance.FetchXml = "";
Instance.QueryId = "";
Instance.LayoutXml = "";
Instance.RegisterOnTab = function(tabIndex) {
Instance.Iframe = document.getElementById(iframeId);
if (!Instance.Iframe) {
return alert("Iframe " + iframeId + " is undefined");
}
m_iframeDoc = getIframeDocument();
var loadingGifHTML = "<table height='100%' width='100%' style='cursor:wait'>";
loadingGifHTML += "<tr>";
loadingGifHTML += "<td valign='middle' align='center'>";
loadingGifHTML += "<img alt='' src='/_imgs/AdvFind/progress.gif'/>";
loadingGifHTML += "<div/><b>Loading View...</b>";
loadingGifHTML += "</td></tr></table>";
m_iframeDoc.body.innerHTML = loadingGifHTML;
if (parseInt("0" + tabIndex) == 0) {
Instance.Refresh();
}
else {
Instance.Iframe.attachEvent("onreadystatechange", RefreshOnReadyStateChange);
}
}
RefreshOnReadyStateChange = function() {
if (Instance.Iframe.readyState != 'complete') {
return;
}
Instance.Refresh();
}
Instance.Refresh = function() {
if (!Instance.Iframe) {
return alert("Iframe " + iframeId + " is undefined");
}
m_iframeDoc = getIframeDocument();
Instance.Iframe.detachEvent("onreadystatechange", RefreshOnReadyStateChange);
var create = m_iframeDoc.createElement;
var append1 = m_iframeDoc.appendChild;
vDynamicForm = create("<FORM name='vDynamicForm' method='post'>");
var append2 = vDynamicForm.appendChild;
append2(create("<INPUT type='hidden' name='FetchXml'>"));
append2(create("<INPUT type='hidden' name='LayoutXml'>"));
append2(create("<INPUT type='hidden' name='EntityName'>"));
append2(create("<INPUT type='hidden' name='DefaultAdvFindViewId'>"));
append2(create("<INPUT type='hidden' name='ViewType'>"));
append1(vDynamicForm);
vDynamicForm.action = "/" + ORG_UNIQUE_NAME + "/AdvancedFind/fetchData.aspx";
vDynamicForm.FetchXml.value = Instance.FetchXml;
vDynamicForm.LayoutXml.value = Instance.LayoutXml;
vDynamicForm.EntityName.value = Instance.Entity;
vDynamicForm.DefaultAdvFindViewId.value = Instance.QueryId;
vDynamicForm.ViewType.value = 1039;
vDynamicForm.submit();
Instance.Iframe.attachEvent("onreadystatechange", OnViewReady);
}
OnViewReady = function() {
if (Instance.Iframe.readyState != 'complete') {
return;
}
Instance.Iframe.style.border = 0;
Instance.Iframe.detachEvent("onreadystatechange", OnViewReady);
if (Instance.WithParentContext == true) {
getIframeWindow().open = OnWindowOpen;
}
if (m_iframeShowModalDialogFunc == null) {
m_iframeShowModalDialogFunc = getIframeWindow().showModalDialog;
getIframeWindow().showModalDialog = OnIframeShowModalDialog;
}
if (Instance.EntityCode > 0) {
if (m_windowAutoFunc == null) {
m_windowAutoFunc = window.auto;
window.auto = OnWindowAuto;
}
}
m_iframeDoc = getIframeDocument();
m_iframeDoc.body.scroll = "no";
m_iframeDoc.body.style.padding = "0px";
}
OnWindowOpen = function(url, name, features) {
//new window
if (url.indexOf('?') == -1) {
if (url.indexOf('userdefined') == -1) {
url = url + "?_CreateFromType=" + crmForm.ObjectTypeCode + "&_CreateFromId=" + crmForm.ObjectId;
}
else {
url = url + "?_CreateFromType=" + crmForm.ObjectTypeCode + "&_CreateFromId=" + crmForm.ObjectId + "&etc=" + Instance.EntityCode + "#";
}
}
return window.open(url, name, features);
}
OnIframeShowModalDialog = function(sUrl, vArguments, sFeatures) {
m_iframeShowModalDialogFunc(sUrl, vArguments, sFeatures);
Instance.Refresh();
}
OnWindowAuto = function(otc) {
if (otc == Instance.EntityCode) {
getIframeDocument().all.crmGrid.Refresh();
}
m_windowAutoFunc(otc);
}
getIframeDocument = function() {
return getIframeWindow().document;
}
getIframeWindow = function() {
return Instance.Iframe.contentWindow;
}
}
// Ejecutar la configuración del IFRAME
ConfigFetchIFrame("IFRAME_test", 2, "contact", 0, getFetchXml(), getLayoutXml());

Aplicando este código obtenemos el aspecto mostrado en la figura 1. En el formulario mostramos el resultado de una búsqueda avanzada incluso con el botón de refrescar.

Anuncios




CRM 2011: Disponible el Rollup 6

13 01 2012

Ya està disponible el Rollup 6 para CRM 2011.

El enlace para descargarlo es: http://www.microsoft.com/downloads/es-es/details.aspx?familyid=e35f3e66-42ea-46af-9e79-4b4f7fa55cfe&displaylang=es

Podéis encontrar toda la información sobre la actualización en el KB: El paquete acumulativo de actualizaciones 6 para Microsoft Dynamics CRM 2011 está disponible

Esta actualización resuelve bastantes bugs si bien no aporta ninguna novedad, a diferencia del Rollup 5 (en la que se añadió el Activity Feed) o por lo menos no se informa de ello en ninguno de los links anteriores. Seguiremos a la espera pues de novedades tan necesarias como la compatibilidad con otros navegadores, prevista inicialmente para el Q1 2012.





Los números de 2011

1 01 2012

Los duendes de las estadísticas de WordPress.com prepararon un reporte para el año 2011 de este blog.

Aqui es un extracto

La sala de conciertos de la Ópera de Sydney contiene 2.700 personas. Este blog fue visto cerca de 18.000 veces en 2011. Si fuese un concierto en la Ópera, se necesitarían alrededor de 7 actuaciones agotadas para que toda esa gente lo viera.

Haz click para ver el reporte completo.