La llegada de la nueva versión de SharePoint obliga en cierto modo a que los desarrolladores de anteriores versiones tengan que adaptarse a los cambios del desarrollo en la Web y a familiarizarse con un lenguaje de programación que no levanta las simpatías de la comunidad .NET. Este lenguaje como se deduce es JavaScript. En este artículo se va a introducir el framework JavaScript Kendo UI de Telerik y en un artículo posterior ExtJS de Sencha para facilitar nuestro trabajo en los desarrollos a realizar y sobre todo otorgarles una mayor calidad.
¿Qué es un Framework?
Según la Wikipedia es una estructura conceptual y tecnológica de soporte definido, normalmente con artefactos o módulos de software concretos, que puede servir de base para la organización y desarrollo de software. Típicamente, puede incluir soporte de programas, bibliotecas, y un lenguaje interpretado, entre otras herramientas, para así ayudar a desarrollar y unir los diferentes componentes de un proyecto. Representa una arquitectura de software que modela las relaciones generales de las entidades del dominio, y provee una estructura y una especial metodología de trabajo, la cual extiende o utiliza las aplicaciones del dominio.
¿Por qué utilizar un Framework JavaScript?
Si analizamos el uso que anteriormente hacíamos de JavaScript en nuestros desarrollos casi siempre se basaban en utilizar alguna librería bien para dotarnos de un efecto que nos gustaba (ejemplo del típico banner slider que está en muchísimas web), bien hacer uso del patrón MVVM haciendo uso de la librería KnockoutJS como introdujo Edin Kapic en números anteriores de la revista. O bien hacer uso de JQuery para añadir una funcionalidad especifica (validar campos, ocultar los mismos, refrescar datos, etc...).
El utilizar JavaScript sin entender realmente lo que estamos desarrollando hace que nuestros desarrollos tengan falta de calidad y bugs relativos a este uso. Es decir vamos concatenando funcionalidades JavaScript a nuestros desarrollos sin saber bien que acciones estamos realizando dentro de nuestro desarrollo. Esto hace que mezclemos diferentes versiones de las librerías que estamos utilizando y da lugar a que se produzcan muchos fallos en nuestros desarrollos. Estos errores son debidos al desconocimiento sobre JavaScript como lenguaje de programación. Y lo que dentro de un desarrollo en .NET ni siquiera nos lo planteamos, en JavaScript dado que es un lenguaje muy vivo y permisivo (en tiempo de desarrollo) no dudamos en realizarlo. El uso de un Framework JavaScript aporta como valor añadido que nos olvidemos de estos problemas a la vez que introduce una serie de patrones para otorgarle más calidad a nuestro software. Eso sí, esto no implica que no tengamos que conocer JavaScript como lenguaje de programación. Nos proporciona una abstracción de código común que provee funcionalidades genéricas que pueden ser utilizadas para desarrollar aplicaciones de manera rápida, fácil, modular y sencilla, ahorrando tiempo y esfuerzo. Estas funcionalidades se traducen en la forma de diversos tipos de Grid, Combos, Formularios, efectos en las imágenes y distintos gráficos de barras. Aunque este tipo de componentes también los tenemos disponibles en desarrollos en .NET, la gran ventaja del uso de estos Frameworks es que están basadas en los estándares web y que son compatibles con todos los dispositivos móviles/tabletas (IOS, Android, Windows Phone, Surface) y todos los navegadores modernos (IE8 o superior, Chrome, Mozilla). Además aportan unos patrones para realizar nuestros desarrollos lo que repercute directamente en la calidad del software.
Otra gran ventaja es que generan una interfaz de usuario muy intuitiva y con gran variedad de gráficos de barras, gauges, y diversos indicadores muy interesantes para incluir en nuestros desarrollos
Manos a la obra
A continuación, nos centraremos en introducir estos frameworks dentro de nuestros desarrollos utilizándolos en una aplicación de SharePoint. A modo de ejemplo, crearemos un típico mantenimiento de datos maestros que permite mostrar aspectos muy útiles de estas herramientas. El resultado sería el siguiente mockup:
En concreto, la aplicación permite mostrar en un Grid el contenido de una lista de SharePoint que contiene los máximos anotadores de la NBA, y con la posibilidad de añadir, editar y eliminar cualquiera de estos registros y a la vez visualizamos una gráfica en la que se realiza una comparación de los mismos.
Utilizando el Framework Kendo UI Telerik
Kendo es un framework JavaScript creado por Telerik (cuyos componentes dentro del mundo .NET son muy populares) con menos de un año de vida. Su funcionamiento consiste extender de forma sencilla las capacidades que están disponibles en jQuery. Desde Kendo se puede bien usar el modelo de objetos de cliente (CSOM) JavaScript de SharePoint o bien consumir directamente la API REST. En este ejemplo vamos a utilizar la API REST por dos motivos:
Empezando el desarrollo
Este desarrollo se va a implementar por medio de una APP de tipo SharePoint-Hosted, (aunque se podría portar sin ningún problema en WebParts clásicos):
1 <link rel="Stylesheet" type="text/css" href="../Content/App.css" />2 <link href="../Content/kendo.common.min.css" rel="stylesheet" />3 <link href="../Content/kendo.default.min.css" rel="stylesheet" />4 <script type="text/javascript" src="../Scripts/kendo.all.min.js"></script>5 <script type="text/javascript" src="../Scripts/App.js"></script>6
1 dataSource = new kendo.data.DataSource({2 type: "odata",3 transport: {4 read: {5 url: listUrl,6 type: "GET",7 dataType: "json",8 contentType: "application/json;odata=verbose",9 headers: {10 "accept": "application/json;odata=verbose"11 }12 }13 },14 pageSize: 5,15 schema: {16 data: "d.results",17 model: {18 id: "ID",19 fields: {20 ID: { editable: false, nullable: false },21 Title: { validation: { required: true } },22 Scores: { type: "number" },23 Team: { type: "string" }24 }25 }26 }27 });28
1<div id="grid"></div>2
1$("#grid").kendoGrid({2 dataSource: dataSource,3 pageable: true,4 height: 430,5 columns: [6 { field: "ID", title: "ID" },7 { field: "Title", title: "Player" },8 { field: "Scores", title: "Scores" },9 { field: "Team", title: "Team" }]10 });11
A este tipo de grid se les puede otorgar mucho más complejidad, como agrupar por equipos, mostrar totales, etc, y solo añadiendo unas pocas de opciones, para ello consultar la propia documentación de Kendo y podéis obtener todas las posibilidades que nos blinda la herramienta. Si ejecutamos y desplegamos la APP, obtendremos el siguiente resultado:
1dataSource = new kendo.data.DataSource({2 type: "odata",3 transport: {4 read: {5 url: listUrl,6 type: "GET",7 dataType: "json",8 contentType: "application/json;odata=verbose",9 headers: {10 "accept": "application/json;odata=verbose"11 }12 },13 create: {14 url: listUrl,15 type: "POST",16 dataType: "json",17 contentType: "application/json;odata=verbose",18 headers: {19 "accept": "application/json;odata=verbose",20 "X-RequestDigest": $("#__REQUESTDIGEST").val(),21 }22 },23 update: {24 url: function (data) {25 return listUrl + "(" + data.ID + ")";26 },27 beforeSend: function (jqXhr, options) {28 var data = JSON.parse(options.data);29 jqXhr.setRequestHeader("If-Match", data.__metadata.etag);30 },31 type: "POST",32 dataType: "json",33 contentType: "application/json;odata=verbose",34 headers: {35 "accept": "application/json;odata=verbose",36 "X-RequestDigest": $("#__REQUESTDIGEST").val(),37 "X-HTTP-Method": "MERGE"38 },39 },40 destroy: {41 url: function (data) {42 return listUrl + "(" + data.ID + ")";43 },44 type: "DELETE",45 dataType: "json",46 contentType: "application/json;odata=verbose",47 headers: {48 "accept": "application/json;odata=verbose",49 "X-RequestDigest": $("#__REQUESTDIGEST").val(),50 "X-HTTP-Method": "MERGE",51 "If-Match": "*"52 }53 },54 parameterMap: function (data, type) {55 if (type === "update" && data["__deferred"]){56 delete data["__deferred"];57 }58 return kendo.stringify(data);59 }60 },61 pageSize: 100,62 schema: {63 data: "d.results",64 model: {65 Id:"ID",66 fields: {67 Title: { type: "string" },68 Scores: { type: "number" },69 Team: { type: "string" }70 }71 }72 }73 }); });74
De esta forma, estamos consiguiendo añadirle a nuestro origen de datos que permita realizar operaciones CRUD. Para ellos hemos añadido la opción "créate","update", "destroy" y "parameterMap". Esta última sirve para indicar que parámetros queremos enviar o no a SharePoint utilizando la API REST. Debido a que si enviamos los datos tal y como lo genera Kendo da un error indicando que hay un valor "__deferred" que no es admitido. Por este motivo lo que hacemos antes de enviar los datos es eliminar este valor para evitar cualquier fallo al enviar los datos.
1$("#grid").kendoGrid({2 dataSource: dataSource,3 pageable: {4 refresh: true,5 pageSizes: true6 },7 height: 430,8 toolbar: ["create"],9 columns: [10 { field: "Title"},11 { field: "Scores" },12 { field: "Team" },13 { command: ["edit","destroy"], title: " ", width: "45px" }],14 editable: "popup"15 });16
Como se deduce, hemos modificado las columnas del grid para añadir una nueva columna command en la que podremos editar y eliminar el registro automáticamente. Adicionalmente, en la parte superior hemos creado un botón para añadir nuevos registros. Este botón puede tener dos funcionalidades bien añadir el registro directamente en el grid, o bien mostrar una ventana modal en la que en la que introducir el nuevo registros. En este caso se ha optado por la segunda opción. Una de las grandes ventajas que tiene es que cuando realizamos cualquier opción de edición de los registros estos formularios son inteligentes, en el sentido que ya incorporan la propia validación de los campos obligatorios y del formato de los mismos.
El resultado se muestra a continuación:
Cuando pulsamos sobre el botón de “Add new record” vemos como se muestra la pantalla modal:
Una vez realizado las operaciones básicas vamos a mostrar como con el mismo datasource se pude visualizar una gráfica relativamente simple y muy sencilla de implementar. Para ello tenemos que hacer uso del Widget “Bar Char”. Antes de ponernos con el JavaScript retocamos un poco el HTML para ello añadimos las siguientes líneas de código dentro de la página default.aspx:
1<div class="chart-wrapper" style="margin: auto;">2 <div id="chart"> </div>3 </div>4
A continuación, modificamos el archive App.js de la siguiente forma:
1$("#chart").kendoChart({2 dataSource: dataSource,3 title: {4 text: "Promedio Puntos Jugadores"5 },6 legend: {7 position: "top"8 },9 seriesDefaults: {10 type: "column"11 },12 series:13 [{14 field: "Scores",15 name: "Scores"16 }],17 categoryAxis: {18 field: "Title",19 labels: {20 rotation: -9021 },22 majorGridLines: {23 visible: false24 }25 },26 valueAxis: {27 labels: {28 format: "N0"29 },30 majorUnit: 10000,31 line: {32 visible: false33 }34 },35 tooltip: {36 visible: true,37 format: "N0"38 }39 });40
Una vez añadido estas modificaciones ya tenemos el grafico listo en nuestra aplicación como mostramos en la siguiente pantalla:
Conclusiones
Todo esto es una pequeña parte de la que contiene este Framework que es muy completo y merece la pena cuanto menos probar su utilidad. También tiene incluido la funcionalidad KnockoutJS para incluir patrones Model View View Model, incluye muchas más utilidades sencillas de utilizar y que da un salto de calidad a nuestros desarrollos y con menor esfuerzo.
Existen multitud de frameworks JavaScript, cada desarrollador puede tener preferencia por uno u por otro. Mi opinión personal es que no podría indicar cuál es el mejor framework JavaScript que hay en el mercado, cada desarrollador tiene su preferido. Pero al final lo que tenemos que tener claro es que hay que realizar el software con la mayor calidad posible y para ello el uso de cualquiera de estos frameworks es prácticamente una obligación.
Referencias:
Adrián Diaz Cervera Sharepoint Architect at Encamina MCPD SharePoint 2010 MAP y MCC 2012 http://blogs.encamina.com/desarrollandosobresharepoint adiaz@encamina.com @AdrianDiaz81