Update State Variables Automatically

Update State Variables Automatically

How to update state variable, $store, on input element change without the need to listen to input event listeners

AlpineJS has a global state management system through its global variable named store.

We can store a variable named total for a page loaded in the browser like this :

document.addEventListener('alpine:init', () =>
{
    Alpine.store('global_data',
    {
        total: 0,
    });
});

(Note: This is not localStorage, so the store variable will be reset once you navigate to another page)

If you're looking to assign and update a variable stored in $store with change in input elements' values, you don't need to attach event listeners to the respective input elements at all.

Let's have 2 input elements, one for the quantity (text field) and one for the size of the product (select), where each of the 3 sizes has pre-defined prices.

So for the quantity we can bind the value of the input to a local AlpineJS variable like <input x-model="quantity"> and a <select x-model="price">

And have a total assigned and displayed as :

x-text="$store.global_data.total = calcTotal(quantity, price)"

Here is the entire code :

<!DOCTYPE html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />    
    <title>AlpineJS onchange update store variable</title>
</head>
<body>
<script>
document.addEventListener('alpine:init', () =>
{
    Alpine.store('global_data',
    {
        total: 0,
    });
});

let calcTotal = (quantity, price) =>
{
    return quantity * price;
}
</script>

<div x-data="{ quantity:0, price:0 }">
    Quantity : <input type="text" x-model="quantity"/>
    <select x-model="price">
        <option value="0">Select Size</option>
        <option value="150">Small ($150)</option>
        <option value="360">Medium ($360)</option>
        <option value="890">Large ($890)</option>
    </select>    
    <p>Total : <span x-text="$store.global_data.total = calcTotal(quantity, price)"></span></p>
</div>

<script defer src="https://unpkg.com/alpinejs@3.12.3/dist/cdn.min.js"></script>
</body>
</html>