Comment utiliser Alpine.js avec Rails et Turbo

Alpine.js est l’une de mes bibliothèques JavaScript préférées. Elle est simple, rapide et facile à intégrer sans écrire trop de code JavaScript.

Pour les applications Ruby on Rails où je ferai la plupart du rendu côté serveur, comme via Turbo, et où je ne veux pas utiliser React ou Vue.js (ni même Stimulus), Alpine.js offre la juste quantité de JavaScript.

Dans ce tutoriel, nous verrons comment utiliser Alpine.js avec votre application Rails, et comment ajouter les éléments d’interface suivants :

  • Messages flash (disparition automatique)
  • Modal

Le code de démonstration pour ce tutoriel se trouve sur https://github.com/Code-With-Rails/alpinejs-demo.

Installation d’Alpine.js avec Rails

Pour notre application de base, nous utiliserons Rails 7 qui supporte les import maps.

bin/rails new rails-alpinejs-demo
cd rails-alpinejs-demo

bin/rails importmap:install
bin/importmap pin alpinejs
bin/importmap pin alpine-turbo-drive-adapter

Ajoutez à votre application.js :

import '@hotwired/turbo-rails'
import 'alpine-turbo-drive-adapter'
import Alpine from 'alpinejs'

window.Alpine = Alpine
Alpine.start()

Un Exemple Rapide

<div x-data="{ open: false }">
  <button x-on:click="open = ! open">Basculer</button>
  <span x-show="open">Je suis là !</span>
</div>

La beauté d’Alpine.js est qu’il n’y a pas de code JavaScript supplémentaire à écrire ailleurs. Vous pouvez déclarer comment les éléments répondent aux événements initiés par l’utilisateur et modifier l’état des données en conséquence.

Construction des Messages Flash

Les messages flash avec Alpine.js peuvent disparaître automatiquement en utilisant x-init et setTimeout :

<%# app/views/layouts/_flash_message.html.erb %>
<%= turbo_frame_tag 'flash' do %>
  <% unless flash[:notice].blank? %>
    <div x-init="() => { flashShown = true; setTimeout(() => { flashShown = false }, 4000) };">
      <%= flash[:notice] %>
    </div>
  <% end %>
<% end %>

Construction d’un Modal

Pour les modals, combinez Turbo Streams avec les transitions Alpine.js :

<div x-init="$nextTick(() => { isModalOpen = true })"
     x-show="isModalOpen"
     x-transition:enter="ease-out duration-300"
     x-transition:enter-start="opacity-0"
     x-transition:enter-end="opacity-100">
  <!-- Contenu du modal -->
</div>

Conclusion

Alpine.js me permet de me concentrer sur le rendu côté serveur et de minimiser la quantité de code JavaScript dont j’ai besoin. Quand j’utilise Alpine.js et travaille dans ce pour quoi il est conçu (petites interactions légères nécessitant du JS), mon application et sa base de code semblent plus légères.

Je vous encourage à consulter le dépôt de l’application de démonstration sur https://github.com/Code-With-Rails/alpinejs-demo et de voir par vous-même.

Derniere mise a jour le 27 février 2024