State & DOM Manipulation with AlpineJS

State & DOM Manipulation with AlpineJS

's avatar
Semir Teskeredzic ・August 24, 2021
3 minute read ・Updated August 29, 2021

In my previous post I introduced this great lightweight JavaScript framework - AlpineJS. You can read about it here. In this post I will go through some of the concepts that AlpineJS uses for state management and DOM manipulation.

State

You can say that the State is the magic ingredient and I will agree with you, but essentially State is a data object that enables us to do many things on the frontend side. Alpine lets you provide data within specific HTML element(s) or make it accessible from anywhere on your page. Let's start with the local one.

x-data

This attribute is simple and straightforward, you declare it inside the HTML element and the entire block has the access to it. In the example below h1 and p will have no problem accessing toggle value and additionally if they depend on it, they will react automatically.

<div x-data="{ toggle: true }">
...
  <h1></h1>
  <p></p>
...
</div>

You can also nest data and access parent data from the child. Let's see that in the example

<div x-data="{ toggle: false }">
  <div x-data="{ title: 'I am the title' }">
    <h1 x-text="title"></h1>
    <p x-show="toggle">Paragraph</p>
  </div>
</div>

Data can also be used within the same element, you can also pass only the x-data directive without expression if you need to.

<button x-data="{ label: 'Buy Now' }" x-text="label"></button>
<button x-data @click="alert('Button is clicked')">Alert</button>

Alpine.store(...)

When you need your data to be available to every component on the page, you can use Alpine.store that stands for global store on the page level. You are registering it with Alpine.store(...) and referencing it with the $store() method. First we will register the store:

Alpine.store('tabs', {
  current: 'overview',
  items: ['overview','description','specification'],
})

We can now access it or modify it anywhere on the page

<div x-data>
  <template x-for="tab in $store.tabs.items">
    ...
  </template>
</div>

<div x-data>
  <button @click="$store.tabs.current = 'overview'">Overview</button>
  <button @click="$store.tabs.current = 'description'">Description</button>
  <button @click="$store.tabs.current = 'spoecification'">Specification</button>
</div>

DOM Manipulation

Alpine makes DOM manipulation available through the use of various directives. We will go through some of the most common ones here.

Text content

We can use directive x-text to essentially control the text content of the element:

Checkout our latest product - the ultimate tailwindcss page creator πŸš€
<div x-data="{ paragraph: 'This is the paragraph' }">
  <p x-text="paragraph"></p>
</div>

With this directive you can use any JavaScript expression and it will evaluate as the content of the element.

<div x-data="{a: 1, b: 4}">
  <p x-text="b > a"></p>
</div>

This will output true

Toggling elements

You will require this directive when you create modals, dropdowns and similar content that has 'on-off' logic. We can use x-show and x-if here to toggle elements on the page. Behind the scenes Alpine is adding display: none to the element it needs to hide

<div x-data="{ toggle: false }">
    <button @click="toggle = ! toggle">Show More</button>
    <div x-show="toggle">
        My Content...
    </div>
</div>

We can use x-if to achieve the same goal

<div x-data="{ toggle: false }">
    <button @click="toggle = ! toggle">Show More</button>
    <template x-if="toggle">
      <div>
        My Content...
      </div>
    </template>
</div>

Binding attributes

We can add HTML attributes to elements using x-bind directive

<button
    x-data="{ green: false }"
    x-bind:class="green ? 'bg-green' : ''"
    @click="green = !green"
>
    Toggle Green
</button>

You can use syntax without x-bind only on class bindings like so:

<div x-data="{ open: true }">
  <p :class="{ 'hidden': !open }">...</p>
</div>

Here we will have hidden class added to the p element whenever open is false.

Looping elements

We've seen x-for earlier when we iterated through tabs in Alpine.store(...) example. As you've seen there, x-for allows us to iterate through our data. Note that it has to be applied within <template> tag though.

<div x-data="{ seasons: ['spring', 'summer', 'autumn', 'winter'] }">
    <template x-for="season in seasons">
        <div x-text="season"></div>
    </template>
</div>

Inner HTML

You can also control HTML content with the x-html directive like so:

<div x-data="{ title: '<h1>I am the Title</h1>' }">
    <div x-html="title"></div>
</div>

Hope some of the examples will help you in your work, hobbies, and projects. Thank you for reading and stay safe.

Comments (0)