Alpine number clamp
Simple demo to show an element with with Alpine.js
by James Doyle
HTML
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/cdn.min.js"></script>
<script>
// has to be defined here in order to work
window.Alpine.magic("clamp", () => {
return (number, min, max) => {
// Ensure min is the lower bound and max is the upper bound, regardless of input order
const lower = Math.min(min, max)
const upper = Math.max(min, max)
// Clamp the number
return Math.min(Math.max(Number(number), lower), upper)
}
})
</script>
<!-- default value is 4 -->
<!-- when letters are entered (nan) we set it to the min -->
<div
x-data="{ value: 4, min: 1, max: 11 }"
x-effect="value = isNaN(value) ? min : $clamp(value, min, max)"
class="~px-1/3 flex items-stretch justify-center"
>
<button
title="Increase product quantity"
type="button"
class="px-1 disabled:cursor-not-allowed disabled:opacity-50"
x-on:click="value = value + 1"
x-bind:disabled="value === max"
>
+
</button>
<input
name="quantity"
title="Product quantity"
type="text"
inputmode="numeric"
pattern="[1-9]{1,2}"
x-model.number="value"
x-bind:min="min"
x-bind:max="max"
step="1"
class="h-full w-8 appearance-none border-none p-0 text-center"
/>
<button
title="Decrease product quantity"
type="button"
class="px-1 disabled:cursor-not-allowed disabled:opacity-50"
x-on:click="value = value - 1"
x-bind:disabled="value === min"
>
-
</button>
</div>