A continuación encontrarás la segunda parte del tutorial que nos muestra lo fácil que resulta crear renderizadores de celda personalizados para los controles WebListBox con Xojo, y que ha sido escrito por Ricardo Cruz. ¡Seguro que lo vas a disfrutar!
Existe algo que es incluso mejor que utilizar Renderizadores de Celdas de terceros: ¡crearlos! En esta segunda parte del tutorial aprenderás cómo crear tus propios controles utilizando el WebSDK de Xojo.
En el caso de que aún no lo hayas leído, en el anterior artículo se explica en detalle qué son los Renderizadores de Celda y cómo podemos utilizarlos en nuestros WebListBox
.
Puedes hacer cualquier cosa que puedas imaginar como parte de las celdas (filas) del control WebListView
. Para ello, has de estar preparado para escribir algo de código JavaScript. En esta segunda parte vamos a crear un ejemplo muy básico de un Renderizador de Celda personalizado, capaz de mostrar etiquetas de Bootstrap.
Si pensamos en ello, de forma resumida, lo que queremos hacer es inyectar en nuestras celdas este HTML (proveniente directamente de la documentación de Bootstrap):
<span class="badge badge-pill badge-primary">Primary</span>
El primer paso consiste en crear una nueva clase en nuestro proyecto de Xojo. Vamos a llamarla BadgeColumn. Será una subclase de la clase WebListboxCellRenderer
.
Ampliando WebListBoxCellRenderer
permitirá que nuestra clase pueda recibir algunos eventos emitidos por Xojo, y que utilizaremos para crear nuestras etiquetas en las celdas de la tabla. Dichos eventos son:
- Deserialize
- JavascriptClassCode
- Serialize
Ignoremos por ahora dichos eventos, excepto JavascriptClassCode
. Pero es importante saber que Serialize debe de devolver una instancia de una clase JSONItem
; de lo contrario obtendrás una NilObjectException
tan pronto como añadas una fila utilizando este renderizador de celda.
Añadamos el siguiente código al evento Serialize
de nuestra subclase. Volveremos a este evento un poco más tarde:
Return New JSONItem
El evento JavascriptClassCode
sólo se ejecutará una vez, no importa cuál sea la cantidad de instancias que creemos a partir de nuestro renderizador. Debe devolver una String
que se corresponda con una clase Javascript que amplíe XojoWeb.ListboxCellRenderer
y que contenga el método render()
.
En render()
simplemente sustituiremos los contenidos del elemento DOM de la celda con el código HTML proporcionado por la documentación de Bootstrap, y que se corresponde a la etiqueta.
Para que sea lo más legible posible, personalmente prefiero hacerlo creando una Constante de tipo String llamada kJavascriptClass
(el nombre es arbitrario, puedes utilizar cualquier otro que desees), y que tiene asignado el siguiente código Javascript:
class BadgeColumn extends XojoWeb.ListboxCellRenderer { render(controlID, row, data, rowIndex, columnIndex, cell) { cell.innerHTML = '<span class="badge badge-pill badge-primary">Primary'; } }
Con nuestro código Javascript ya en una constante de String
, el evento JavascriptClassCode
simplemente se limita a devolver dicho valor:
Return kJavascriptClass
¡Enhorabuena! Este es tu primer renderizador de Celda. No hace mucho, pero proporciona los fundamentos básicos necesarios para comenzar a crear muchas más.
Con esta nueva clase y siguiendo los pasos que ya aprendiste en la primera parte de este tutorial, podrás comenzar a usarla en tus tablas.
Añade un WebListView
en tu WebPage
y añade un manejador de evento para el evento Opening
. Añade a continuación el siguiente código:
Me.AddRow("Hello, World!") Me.CellValueAt(0, 0) = New BadgeColumn
Este añadirá una fila al control haciendo a continuación uso de nuestro nuevo Renderizador de Celda para dibujar la primera celda de la primera fila.
si ejecutas tu proyecto, verás un sitio web con un aspecto muy similar al de la siguiente captura de pantalla:
Si bien es prometedor, y como puedes comprobar, la etiqueta dice “Primary” en vez del mensaje “Hello, World!” que queremos mostrar.
Si echas un vistazo al método render()
de nuestro código Javascript, verás que “data” es uno de los parámetros recibidos. Es un objeto JSON
que proviene del evento Serialize
que hemos visto unos párrafos más arriba.
Edita el manejador de evento Serialize
de nuestra subclase. En esta ocasión no devolveremos un JSONItem
vacío, sino que le proporcionaremos algunos datos.
Var json As New JSONItem json.Value("content") = "Test" json.Value("appearance") = "success" Return json
A continuación, actualiza la constante kJavascriptClass
con el siguiente fragmento de código. Observa cómo ahora estamos utilizando los valores recibidos en el parámetro data y que llega como un objeto Javascript:
class BadgeColumn extends XojoWeb.ListboxCellRenderer { render(controlID, row, data, rowIndex, columnIndex, cell) { cell.innerHTML = '<span class="badge badge-pill badge-' + data.appearance + '">' + data.content + '</span>'; } }
Si ejecutamos de nuevo la aplicación web, te arrancará una sonrisilla:
¡Casi estamos! Ahora que sabemos cómo comunicar Xojo con la celda que se está ejecutando en nuestro navegador, sólo necesitamos encontrar un modo de crear instancias de estas clases BadgeColumn
utilizando contenido real.
Mi preferencia personal consiste en crear un Constructor
con los parámetros que necesito, y algunas propiedades de clase.
Añade unas cuantas propiedades para tu clase BadgeColumn
:
- Content As String
- Appearance As String
Y luego un Constructor
con los siguientes parámetros:
- content As String
- appearance As String
Dentro del nuevo Constructor
tendrás que llamar al Constructor
de su Superclase, conectando a continuación las propiedades internas de la instancia con los parámetros recibidos, tal y como se ve aquí:
Super.Constructor Self.Content = content Self.Appearance = appearance
Debemos actualizar el manejador de evento Serialize
para hacer uso de las nuevas propiedades, en vez de escribir directamente los datos:
Var json As New JSONItem json.Value("content") = Content json.Value("appearance") = Appearance Return json
Por último, necesitamos actualizar el manejador de evento Opening
utilizado en nuestro ListBox
. Sólo has de recordar que BadgeColumn
necesita ser instanciado ahora con algunos parámetros:
Me.AddRow("") Me.CellValueAt(0, 0) = New BadgeColumn("Hello, World!", "warning")
Ejecuta de nuevo la aplicación y veamos qué ocurre:
¡Whoops! No tiene buena pinta, ¿verdad? Nos hemos olvidado de un paso muy importante.
La comunicación entre Xojo y el control que reside dentro del Javascript es bidireccional. De este modo, “Data” puede ser modificado mientras se ejecuta en tu navegador, y también puede ser devuelto a Xojo.
Para solucionar el problema, sólo tenemos que ocuparnos del manejador de evento Deserialize
y que habíamos ignorado por completo hasta ahora. Escribe el siguiente código para dicho evento:
Content = js.Value("content") Appearance = js.Value("appearance")
Esto creará nuestra instancia utilizando los datos recibidos desde Javascript. Ejecuta el proyecto de nuevo y ¡voilà!, ahora tu tabla se ve perfecta:
Este no es el final, sino el inicio de tu viaje. Con esta pequeña receta ya has adquirido los conocimientos suficientes y muchas horas de diversión por delante para crear tus propios Renderizadores de Celda.
Una vez te sientas cómodo, el siguiente paso que te recomiendo es aprender a emitir acciones de celda personalizadas desde tu Javascript, y que puedes recoger y tratar en el evento CustomCellAction
de tus controles WebListBox
.
Para ver cómo funciona esto, puedes revisar algunos de los ejemplos que se proporcionan con Xojo en Web > WebSDK > WebListBox Cell Renderers.
El repositorio de código abierto indicado en el anterior artículo, también hace uso de este evento para algunos de los renderizadores de celda incluidos.
Conclusión
Si bien tenemos que ensuciarnos las manos con Javascript, es realmente divertido crear Renderizadores de Celda para nuestros proyectos. Son súper fáciles de compartir y reutilizar, y lograrán que tus tablas tengan un aspecto mucho mejor.
Puedes descargar el código fuente correspondiente a este proyecto de ejemplo desde aquí.
Espero que hayas encontrado este tutorial de utilidad y, si tienes alguna duda, no dudes en contactar conmigo o preguntar en el foro de Xojo.