Estilando UI5 dinámicamente: CustomData
Pues sí. En UI5 se puede tocar el CSS de la aplicación. Otro asunto es discernir qué cosas podemos o debemos cambiar. Es muy fácil venirse arriba y empezar a escribir muchas líneas de CSS, ya que puede resultar sencillo obtener un cambio en la interfaz rápidamente. El problema generado de hacerlo sin control probablemente no lo viva el mismo desarrollador que lo escribe. Lo sufrirá (o no, si se hace bien) el futuro encargado de hacer el upgrade a una versión superior de las librerías de UI5.
En este artículo no voy a entrar a ver qué cosas se deben o no hacer, ni que cosas están bien o mal. Me voy a centrar en dar una posible solución a un problema o limitación que tiene UI5:
La propiedad class de los controles UI5 no es bindable
Esto implica que no podemos utilizar clases CSS dinámicamente. Lo podemos ver con un ejemplo: un listado de materiales con sus respectivos stocks:
- 20 Ordenadores
- 40 Teclados
- 10 Ratones
Partiendo de la base de que utilizaremos un derivado de sap.m.ListBase
, si necesitamos marcar en rojo los materiales con stock < 15
, en UI5 tenemos distintas posibilidades:
- Utilizar la propiedad
highlight
de cadaListItem
, bindándola y utilizando Error en los casos que cumplan la condición. - Añadir un
sap.m.Icon
en rojo en cadaListItem
que cumpla la condición. - Utilizar
CustomData
en el número y ponerle un valor dinámico.
En este artículo vamos a comentar la tercera opción, pero: ¿qué es un CustomData
?
Los controles UI5 pueden guardar datos internamente en n parejas de clave/valor. Podemos hacer que estas parejas se pinten como un atributo del elemento del DOM. Si la combinamos con una clase css, podemos hacer distintos selectores css para una misma clase
Tienes mas informacion sobre CustomData en la api de UI5.
CustomData en HTML
Bien, esto con HTML + CSS lo podemos ver de la siguiente manera:
CustomData en UI5
Pues en una vista XML de UI5 vendría a ser así (el ejemplo obvia partes del código de la Table):
Con key indicamos el nombre del atributo y en value podemos bindar el valor como en cualquier otra propiedad. Con esto sería suficiente para almacenar el valor en ese control, pero lo que necesitamos es que exponga un atributo en el DOM. Para ello marcamos el flag writeToDom
.
Por otro lado, quizás te has fijado que no he utilizado directamente el carácter <
en la condición. Hay que ir con cuidado en los XML ya que hay ciertos carácteres que se han de utilizar codificados:
<
➡️<
&
➡️&
La sap.m.Table con los materiales que hemos mencionado y el CustomData en el stock quedaría así:
También podemos hacerlo con javascript
de la siguiente manera. Utilizaremos una función factory para generar los items de la tabla (en el ejemplo también estoy obviando el resto de celdas):
Si en algún momento necesitamos leer el valor de un CustomData
de cualquier control, podemos utilizar la misma función data(), indicando únicamente en el primer parámetro la clave a recuperar:
En conclusión, se puede sortear la limitación que tiene UI5 en la propiedad class
de una manera mas o menos elegante. Ahora bien, no hay que abusar de esto ni llenar las aplicaciones UI5 con CSS 😂.
Si te ha parecido interesante el artículo, agradecería que lo compartieras. ¡Hasta el próximo!