Algunas de las nuevas funcionalidades de CRM 2011 lo son los Ribbons y el poder re-utilizar bibliotecas de JavaScript en diferentes entidades y múltiples formas. Sin embargo, existe un inconveniente cuando queremos utilizar más de una biblioteca de JavaScript para realizar alguna acción desde un botón del HomepageGrid o el Subgrid de una entidad. Por defecto, el Ribbon solo carga las bibliotecas que esten definidas en las acciones y/o reglas de activar de la entidad. Por tanto, ¿qué podemos hacer si necesitamos utilizar más de una biblioteca en el HomepageGrid o SubGrid? A continuación les explico cómo poder hacerlo.
Por ejemplo, queremos añadir un nuevo botón en el HomepageGrid de la entidad Account , que el mismo muestre una alerta con el nombre de la cuenta seleccionada al presionar el botón. El mismo solo se habilitara cuando se seleccione un solo record.
Para esto vamos a utilizar dos bibliotecas de Javascript, que para este ejemplo ya hemos cargado al sistema como un recurso web. La primera biblioteca, la llamaremos accountLibrary.js. En esta biblioteca tenemos definido la siguiente función:
function accountLibrary_getAccountName(recordId, selectedRecordCount) {
if (selectedRecordCount == 1 && recordId != null ) {
var oDataSetName = "AccountSet";
var selectAttributes = "Name";
var record = jQuery_retrieveRecord(recordId, oDataSetName, selectAttributes);
if (record != null && record.Name != null) {
alert("El nombre de la cuenta es: " + record.Name);
}
else {
alert("El nombre de la cuenta es: No tiene nombre");
}
}
else {
alert("Solo puede realizar esta operación al seleccionar un solo record.");
}
}
Como pueden observar, estamos utilizando una función llamada jQuery_retrieveRecord para obtener por medio de un OData query el nombre de la cuenta. Esa función, la hemos definido en otra biblioteca llamada jQuery.js:
function jQuery_retrieveRecord(id, odataSetName, selectAttributes) {
//id is required
if (!id) {
alert("record id is required.");
return;
}
//odataSetName is required, i.e. "AccountSet"
if (!odataSetName) {
alert("odataSetName is required.");
return;
}
//odataSetName is required, i.e. "AccountName,AccountNumber"
if (!selectAttributes) {
alert("selectAttributes is required.");
return;
}
var serverUrl = Xrm.Page.context.getServerUrl();
var oDataEndpointUrl = serverUrl + "/XRMServices/2011/OrganizationData.svc/" + odataSetName + "(guid%27" + id + "%27)" + "?$select=" + selectAttributes;
var record = getRequestObject();
if (record != null) {
record.open("GET", oDataEndpointUrl, false);
record.setRequestHeader("X-Requested-Width", "XMLHttpRequest");
record.setRequestHeader("Accept", "application/json, text/javascript, */*");
record.send(null);
var requestResults = eval('(' + record.responseText + ')').d;
if (requestResults == undefined) {
alert("OData query error: " + record.responseText);
}
else {
if (requestResults != null) {
return requestResults;
}
}
}
return;
}
Ahora, la gran pregunta: ¿Cómo podemos hacer para que en el Ribbon del HomepageGrid se cargen las dos bibliotecas? Bueno para esto, declaramos en nuestro CommandDefinition para el botón, como normalmente lo hacemos la función accountLibrary_getAccountName, como lo pueden ver a continuación:
<CommandDefinition Id="Ngn.HomepageGrid.account.GetAccountName"> <EnableRules> <EnableRule Id="Ngn.HomepageGrid.account.GetAccountName.EnableRule"/> </EnableRules> <DisplayRules> <DisplayRule Id="Ngn.HomepageGrid.account.GetAccountName.DisplayRule"/> </DisplayRules> <Actions> <JavaScriptFunction FunctionName="accountLibrary_getAccountName" Library="$webresource:accountLibrary.js"> <CrmParameter Value="FirstSelectedItemId"/> <CrmParameter Value="SelectedControlSelectedItemCount"/> </JavaScriptFunction> </Actions> </CommandDefinition>
Ahora sí, para cargar esa otra biblioteca (jQuery.js) debemos referenciar la misma en algún CommandDefinition o RuleDefinition, en nuestro caso hemos decidido utilizar el CommandDefinition de un grupo, que normalmente no tiene un Action definido y ahí colocar una acción incorrecta, en la cual referenciaremos la biblioteca que necesitamos, como lo pueden observar a continuación:
<CommandDefinition Id="Ngn.HomepageGrid.account.GetAccountNameGroup"> <EnableRules> <EnableRule Id="Mscrm.EnableRule"/> </EnableRules> <DisplayRules> <DisplayRule Id="Ngn.HomepageGrid.account.GetAccountNameGroup.DisplayRule"/> </DisplayRules> <Actions> <JavaScriptFunction FunctionName="isNaN" Library="$webresource:jQuery.js"> </JavaScriptFunction> </Actions> </CommandDefinition>
Como pueden notar, hemos declarado en el CommandDefinition del Grupo, los EnableRules y DisplayRules reales, sin embargo definimos un Action, de tipo JavaScriptFunction, que utiliza una biblioteca existente pero declaramos una función que no existe (isNaN). De esta forma nos aseguramos de que se cargue la biblioteca requerida por la función accountLibrary_getAccountName. Si necesitáramos más de una biblioteca, podemos añadir otras acciones y realizamos el mismo ejercicio.
Espero que esto les sirva de ayuda a muchos de ustedes. Espero sus comentarios. ¡Hasta pronto!


