AlpineJS
ActiveAdmin + AlpineJS
AlpineJS es una excelente alternativa para agregar algo de inteligencia a nuestras vistas de ActiveAdmin. En la mayoría de los casos podemos definir todo lo que usamos directamente en nuestro recurso de ActiveAdmin, sin necesidad de archivos JS externos.
Instalando AlpineJS
Después tenemos que agregar lo siguiente al archivo donde ActiveAdmin se inicializa, normalmente el que tiene la linea import '@activeadmin/activeadmin';
Si estás usando Alpine 2 (por Webpacker), tienes que usar lo siguiente:
💡 Todos los ejemplos en esta guía y el repositorio asociado usan AlpineJS 3 pero deberían funcionar en AlpineJS 2.
Intro
Un componente de AlpineJS es un elemento HTML con el atributo (también llamado directiva) x-data
con todas las variables que vamos a usar dentro de un objeto de javascript.
Para que esto funcione en ActiveAdmin, tenemos que agregar el atributo x-data
a inputs
, input
o cualquier otro elemento "wrapper"
💡 Tenemos que usar
CGI.escapeHTML
para evitar que el objeto producido por Rails no escape del atributox-data
, lo que normalmente pasa por una comilla doble.
💡
f.resource.attributes
nos da acceso a todos los atributos del modelo. En vez de usarlo, también puedes declarar los valores a mano, siempre recordando que el resultado final debe ser un objeto válido de javascript.
💡 Si un ejemplo en la guía no incluye el atributo
x-data
, de todas maneras se asume que fue declarado
Una vez que hemos inicializado el componente con x-data
podemos empezar a usar las otras directivas de AlpineJS.
Formatear el valor de un campo al escribir
Casos de uso: Números de teléfono, valores en formato de moneda local, números de cédula de identidad, etc.
Para empezar tenemos que agregar la función para formatear en el mismo archivo donde inicializamos Alpine y exponer la función a la página en ActiveAdmin.
Después, dentro de nuestro recurso en ActiveAdmin, podemos usar x-on-input
(o @input
) para formatear el valor cada vez que escribimos un valor en el campo de texto.
💡 Para este ejemplo en especifico, tenemos que limpiar el número (para obtener
1000
en vez de1.000
), asi que ejecutamosnumberCleaner
antes de `format.
Si actualizamos la página el monto no estará formateado porque el formateador solo se ejecuta con el evento input
. Para arreglar esto tenemos que editar el valor iniciar en x-data
.
En el caso que el atributo del modelo sea un integer
en la base de datos, no podremos guardar el valor formateado. Para lograr guardar el valor actualizado pero mantener el formato al editarlo tenemos que agregar un par de cosas para tener dos campos: el campo formateador y el campo "real" que se guarda en la base de datos.
En el modelo agregamos:
💡
attr_accessor
es necesario ya que ActiveAdmin no permite mostrar valores que no existen como campos en su formulario.
Después, en el archivo de ActiveAdmin, agregamos amount
directamente y además agregamos el campo active_admin_amount
formateado a x-data
.
Reemplazamos el campo amount
por active_admin_amount
y en el evento x-on:input
agregamos que también se actualice amount
.
Finalmente agregamos un campo oculto con el amount
real para que se guarde en la base de datos como número.
Validar un campo
Casos de uso: Prevenir que un formulario se pueda guardar si un valor no es válido, mostrar cuando un campo es obligatorio o tiene un valor inválido.
Al igual que en el ejemplo anterior, tenemos que agregar la función de validación a la variable window
para que esté disponible en la página de ActiveAdmin.
En este ejemplo queremos cambiar la clase CSS del campo cuando el valor no es válido. Para esto necesitamos usar x-bind:class
(o :class
) para que la clase error
sea agregada dinámicamente cuando validators.rut(rut)
sea false
:
Si también queremos desactivar el botón para guardar, podemos editar la acción submit
para agregar el atributo disabled
. x-bind:disabled
(o :disabled
) automáticamente agregan el atributo cuando la validación falla.
Esconder y mostrar un campo
Para poder mostrar y esconder un campo podemos usar la directiva x-show
.
Primero necesitamos un campo con x-model
para tener acceso a su valor.
Después agregamos la directiva x-show
al campo que queremos mostrar o esconder dependiendo del valor que tenga el campo has_description
.
💡 Tenemos que usar
wrapper_html
en vez deinput_html
para esconder toda la fila, tanto ellabel
como elinput
.
Campos Select2
ActiveAdmin Addons transforma todos los select
para que usen Select2, para facilitar el uso de colección grandes o tags. Sin embargo, AlpineJS no tiene idea qué hacer con los elementos de Select2 y viceversa.
Para que funcionen los elementos select
con atributos x-model
tenemos que instalar active-admin-alpine-fixes.
Después tenemos que agregar el fix a la variable window
para que esté disponible en la página de ActiveAdmin
Finalmente agregamos el fix a nuestro component agregando la directiva x-init
para que ejecute el fix apenas el componente sea evaluado por el navegador.
Has Many
ActiveAdmin nos permite tener formularios anidados cuando un recurso tiene un has_many
. Pero cuando hacemos click en el botón para crear un recurso nuevo en este formulario anidado ActiveAdmin usa jQuery para crear los campos nuevos y AlpineJS se confunde.
Para que funcionen tenemos que instalar active-admin-alpine-fixes.
Después tenemos que agregar el fix a la variable window
para que esté disponible en la página de ActiveAdmin
En nuestro componente tenemos que agregar el fix a la directiva x-init
y en nuestro x-data
tenemos que agregar explícitamente el recurso anidado. Dentro del has_many
tenemos que usar x-model
con el índice que nos da para que AlpineJS sepa a qué campo corresponde qué elemento en el arreglo.
Formularios Complejos (Solo AlpineJS 3 - Alpine.data)
Si nuestro formulario es muy complejo o tiene funcionalidad que puede ser fácilmente re-usada, podemos usar Alpine.data
en nuestro javascript para declarar un objeto que puede ser usado en nuestro formulario sin tener que usar window
. En otras palabras, podemos tener un archivo JS separado con todo lo que necesitamos.
Una vez hecho lo anterior, podemos usar complexExample
en nuestro x-data
, el que recibe los atributos que necesitamos para inicializar el objeto que usa Alpine.
💡 Como complexExample todavía no se ejecuta, currencyFormat todavía no está disponible para ser usado en x-data. Puedes agregar la función a la variable window, procesar los atributos dentro de complexExample o, como en este caso, usar Ruby para lograr el mismo resultado.
Última actualización