State & DOM Manipulation with AlpineJS
Semir Teskeredzic
Posted on September 16, 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:
<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.
Posted on September 16, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 28, 2024