Using AlpineJS to make things pretty

arafel

Paul Walker

Posted on April 13, 2021

Using AlpineJS to make things pretty

I had a revelation the other day.

In the beginning…

I had this idea that to make your UI pretty and reactive you needed to be using Vue, Svelte, or some other web framework. Otherwise the page just sat there until you clicked a button, then reloaded. Silly, I now know.

Then I discovered AlpineJS, and realised I was completely wrong.

Using AlpineJS to make things pretty
Example animation of Alpine

That animation above is the result of the markup below. Literally, that’s it.

<html>
  <head>
    <title>Alpine demo page</title>
    <script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.8.2/dist/alpine.min.js"></script>
  </head>
  <body>
    <div x-data="{ show: false }">
      <label for="name">Please enter your name: </label>
      <input type="text" name="name" x-ref="name">
      <button
        @click="show = !show"
        x-text="show ? 'Stop saying hello' : 'Say hello'"
      ></button>
      <div x-show="show">
        <p x-text="'Hello ' + $refs.name.value"></p>
      </div>
    </div>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

The magic happens with the x- tags:

  • x-data declares a variable - you can only use the variable within the scope of that block
  • x-show decides visibility
  • x-text controls the innerText of the element it’s on.
  • @click can be used as a shorthand for listening to events. It’s a shortcut for x-on.
  • x-ref adds a reference to the element, making it accessible later through $refs.

Put those together and you can do some amazing things.

Using it

On most of my projects I’ve had a separate page for deleting items. The flow wasn’t as smooth as I’d have liked, but it worked.

Then I had a Gru moment.

Using AlpineJS to make things pretty
Lightbulb

Why a whole separate page? All I actually need is a POST request to the right URL. I can do that with a form. We already know Alpine can show and hide the form.

Since there’s no data that has to be conveyed the form only actually has to surround the submit buttons.

<form action="/people/<%= person.id %>/delete" method="POST">
  <div>
    <button>Cancel</button>
    <button type="submit" >Delete</button>
  </div>
</form>
Enter fullscreen mode Exit fullscreen mode

If we’re going to use Alpine then we need to tweak the form ever so slightly, replacing the cancel button.

<button @click.prevent="showDelete = false">Cancel</button>
Enter fullscreen mode Exit fullscreen mode

The .prevent stops the click event from being propagated up - if that wasn’t there then the button would register the click, and as well as hiding the delete dialogue it would actually submit the form and delete the item.

Let’s go along to the (really useful) Alpine toolbox, and we see that in fact there are already multiple modal examples that we can derive from.

This excellent post makes a good starting point. We replace the body of it with the tweaked form above and we get the following effect:

Using AlpineJS to make things pretty

I took the chance to improve the look of the buttons slightly, since we’ve pulled in Tailwind from the example. Much better than having to click through to a separate page!

💖 💪 🙅 🚩
arafel
Paul Walker

Posted on April 13, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related