State & DOM Manipulation with AlpineJS
Tags: javascript, tutorial
Published: 2021-09-16 19:07:48

In my previous post I introduced this great lightweight JavaScript framework - AlpineJS. You can read about it [here](https://dev.to/semirteskeredzic/fancy-a-modern-alternative-to-jquery-meet-alpinejs-1lap). 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.