sábado, enero 10, 2015

Y II, mejorar y extender el diseño de cualquier cliente de Dynamics NAV

Siguiendo con el post anterior, que recomiendo su lectura, de cómo mejorar y extender el diseño de Dynamics NAV, se nos plantea la necesidad evidente de permitir que el control Add-in sea accesible desde cualquier cliente, incluido Web y Tablet. Para ello seguí la siguiente documentación de MSDN.

Las diferencias con el control Windows Forms indicado en el post anterior es que aquí sólo utilizaremos el código C# como interfase para, desde C/AL, ejecutar el código Java Script que, éste sí, es ejecutable desde los clientes que no son nativos Windows.

Creando un Add-in para cualquier cliente

Empezaremos creando un proyecto C# desde Visual Studio de tipo Biblioteca de clases y añadiremos la referencia a la librería del cliente NAV que encontraras en el directorio donde tengas instalado el cliente:

Microsoft.Dynamics.Framework.UI.Extensibility

Ahora deberemos referenciarla en el código de la clase:

using Microsoft.Dynamics.Framework.UI.Extensibility;

Y empezamos a definir el interfase:

namespace CEDARTjs500x150
{
    [ControlAddInExport("CEDART.controls.labelJs500x150")]
    public interface CDRTlabelJs500x150
    {
        [ApplicationVisible]
        event ApplicationEventHandler ControlAddInReady;
 
        [ApplicationVisible]
        void SetHtml(string value);
        [ApplicationVisible]
        void SetImage(string name);
    }
}

Una vez definido el interfase, necesitamos dotar de código al control para que haga ciertas cosas, en nuestro caso, muy básico, lo que hace es que visualiza cualquier código HTML con la función SetHtml o visualiza una imagen con la función SetImage.

Siguiendo este ejemplo de MSDN podrás ver que es necesario crear una estructura de carpetas en el proyecto:


Me refiero a la carpeta Resources en la que podremos poner, básicamente 3 carpetas más, una con imágenes, otra con el código Java Script y otra con hojas de estilo. Fijaros también que en la carpeta Resources deberemos tener un fichero Manifest.xml que es el que indica donde está cada cosa.

Como veremos más adelante esta carpeta y su contenido empaquetado en un archivo .zip se deberá incluir al registrar el control en Dynamics NAV.

<?xml version="1.0" encoding="utf-8"?>
<Manifest>
  <ScriptUrls>
    <ScriptUrl>http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.3.min.js</ScriptUrl>
  </ScriptUrls>

  <Resources>
    <Image>LogoCEDART150.png</Image>
    <Script>Script.js</Script>
    <StyleSheet>Stylesheet.css</StyleSheet>
  </Resources>

  <Script>
    <![CDATA[
        $(document).ready(
           function() {
               InitializeLabel();
               Microsoft.Dynamics.NAV.InvokeExtensibilityMethod('ControlAddInReady', null);
           });
    ]]>
  </Script>

  <RequestedHeight>150</RequestedHeight>
  <RequestedWidth>500</RequestedWidth>
  <VerticalStretch>true</VerticalStretch>
  <HorizontalStretch>true</HorizontalStretch>
</Manifest>

En ScriptUrls podremos indicar scripts externos, que como podeis suponer podemos utilizar cualquiera de las librerías externas existentes, en mi caso he utilizado la conocidísima jQuery.

En Resources definiremos todos nuestros archivos utilizados en el proyecto, posteriormente lo veremos más en profundidad.

La parte Script es el código JavaScript que se va a ejecutar (jQuery en nuestro caso). Evidentemente que podríamos poner todo el código en esta sección, pero por cuestiones de Readability es preferible ponerlo en los archivos de script externos.

Como veies, en mi caso, lo que hace es que cuando el documento está "ready" se ejecuta una función para inicializar el control y acto seguido se dispara el evento ControlAddInReady. Fijaos que con la función InvokeExtensibilityMethod podemos disparar cualquier evento en NAV, previamente definido en el interfase en C#.

Finalmente en las 4 últimas propiedades definimos las dimensiones mínimas que debe tener el control y si debe permitir Stretch. Vuelvo a insistir en este punto que las capacidades de resizing tienen mucho por mejorar.

Es importante destacar que los controles diseñados en JavaScript no pueden disponer de propiedades, sólo métodos.

Contenido del paquete .zip de la carpeta Resources

Vamos ahora a centrarnos en los 3 tipos de ficheros que podemos incluir.

El primer tipo de contenido que podemos incluir en Resources son imágenes que podremos recuperar desde el código, tal como veremos más adelante.

El segundo tipo de contenido es Script que evidentemente contiene las funciones. Veamos un ejemplo:

function InitializeLabel() {
    SetHtml("controlId");
}

function SetHtml(value) {
    $('#controlAddIn').html(value);
}

function SetImage(name) {
    var imageURL = Microsoft.Dynamics.NAV.GetImageResource(name);
    $('#controlAddIn').html("<div><img src='" + imageURL + "'/></div>");
}

La primera función es la que se llama desde el Manifest.xml y es la encargada de inicializar el control.
La segunda es la que inserta cualquier texto o código HTML en el control.

La tercera nos permite tener acceso a cualquier imagen, que hayamos incluido en el paquete, mediante la función GetImageResource.

El tercer tipo de contenido son hojas de estilo. En StyleSheet incluiremos las hojas de estilo que vayamos a utilizar, creadas por nosotros o conseguidas de los numerosos recursos externos. Un ejemplo:

body
{
    font-family: Verdana;
    color: black;
    background-color: white;
}

p
{
    padding: 10px;
}

.title
{
    font-size: 14;
    font-weight: bold;
}

.normal
{
    font-size: 12;
    font-weight: normal;
}

.forbr
{
    font-size: 6;
}

Esto es todo lo que necesitamos para nuestro sencillo ejemplo. Vamos a compilarlo y a registrarlo en Navision.

Compilar el control Add-in y registrarlo en Dynamics NAV

Para compilar, deberéis seguir el ejemplo propuesto en el post anterior, toda la parte que explica cómo firmar y compilar el proyecto.

La parte donde explica como registrar el control hay que hacer lo mismo y adicionalmente lo siguiente: Como los controles Add-in pueden replicarse desde el servidor al cliente deberemos cargar la carpeta Resources para que pueda descargarse y ejecutarse localmente.

Para ello lo que haremos será empaquetarla en un archivo .zip y al registrar el control, mediante la acción de Importar importaremos el archivo.

Diseñar utilizando nuestro control Add-in

Diseñaremos una Page en la que incluiremos un Field que incluirá el control Add-in diseñado anteriormente:


Ya añadiremos el siguiente código en el evento Label3::ControlAddInReady()

CurrPage.Label3.SetHtml(
  '<p>' +
  '<span class="title">Ratios de liquidez</span>' +
  '<span class="forbr"><br /><br /></span>' +
  '<span class="normal">' +
  'La liquidez es la capacidad potencial que tiene la empresa para pagar sus obligaciones. ' +
  'La comparación entre la cantidad de riqueza disponible (activo circulante) y las deudas ' +
  'que habrá que atender a corto plazo ' +
  '(pasivo circulante) proporciona una medida de esta liquidez.</span>' +
  '<span class="forbr"><br /><br /></span>' +
  '<span class="normal">' +
  'Dependerá del grado de realización de los elementos del activo, ' +
  'es decir, si están cerca de su conversión en liquidez (derechos de cobro que venzan ' +
  'a corto plazo, existencias que se vayan a vender, etc.), y del grado de exigibilidad del pasivo, ' +
  'es decir, vencimiento de las deudas y necesidad de su devolución.</span>' +
  '</p>');

Compilamos y ejecutamos. Este es el resultado:


Y probamos desde el cliente Web, en mi caso: http://localhost/DynamicsNAV80/WebClient/list.aspx?page=60199 y este es el resultado:


Y desde el cliente tablet:


Vamos a probar ahora la visualización de una imagen incluida en el paquete, para ello vamos a sustuir el código de la Page por este:

CurrPage.Label3.SetImage('LogoCEDART150.png');

Compilamos y ejecutamos en los diferentes clientes:




Objetivo conseguido

Ahora somos capaces de visualizar cualquier contenido, utilizando comandos Html5, programando en JavaScript utilizando librerías como jQuery y hojas de estilos en cualquiera de los clientes de Dynamics NAV.

No hay comentarios:

Publicar un comentario