<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="ie=edge" />
<title>Sandbox - RJ</title>
<meta name="description" content="" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script src="https://unpkg.com/@tailwindcss/browser@4"></script>
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
</head>
<body>
<!-- Code here ... -->
</body>
</html>
let button = document.querySelector('button')
let span = document.querySelector('span')
let proxy = Alpine.reactive({ color: ‘blue’ })
Alpine.effect(() => {
span.textContent = proxy.color
})
button.addEventListener('click', () => {
proxy.color = (proxy.color == ‘blue’) ? ‘green’ : ‘blue’
})
async function getItems() {
let response = await fetch('/api/items/all')
let json = await response.json()
return json
}
<div x-text="JSON.stringify(getItems())"></div>
// or alternatively:
<div
x-data="{
items: {},
async getItems() {
this.items = await (await fetch('/api/items/all')).json();
}
}"
x-init="getItems">
</div>
// https://github.com/markmead/alpinejs-overlap/blob/main/src/index.js
export default function (Alpine) {
Alpine.magic('overlap', (el, {}) => (targetId) => {
const targetEl = document.querySelector(targetId)
return checkOverlap(
targetEl.getBoundingClientRect(),
el.getBoundingClientRect()
)
})
function checkOverlap(targetBounding, elBounding) {
return !(
targetBounding.top > elBounding.bottom ||
targetBounding.right < elBounding.left ||
targetBounding.bottom < elBounding.top ||
targetBounding.left > elBounding.right
)
}
}
// https://github.com/markmead/alpinejs-slug
import slugify from 'slugify'
export default function (Alpine) {
Alpine.directive('slug', (el, { expression }, { evaluateLater, effect }) => {
let setInputValue = evaluateLater(expression)
effect(() => {
setInputValue((string) => {
el.value = slugify(string, {
lower: true,
})
})
})
})
}
<!-- https://codepen.io/ryangjchandler/pen/qBOEgjg -->
<div x-data="toDoList()" class="max-w-2xl mx-auto px-12 py-8 rounded-lg shadow-lg bg-gray-200">
<div class="flex flex-col items-center justify-center mb-8">
<h1 class="text-3xl font-bold mb-8">
To Do List
</h1>
<input type="text" x-model="newTodo" placeholder="I need to..." class="mx-auto px-4 py-2 rounded shadow text-lg min-w-full" @keydown.enter="addToDo">
</div>
<div class="bg-white w-full rounded shadow mb-8">
<template x-for="(todo, index) in todos" :key="index">
<div class="flex items-center py-4" :class="{ 'border-b border-gray-400': ! isLastToDo(index) }">
<div class="w-1/12 text-center">
<input type="checkbox" @change="toggleToDoCompleted(index)" :checked="todo.completed">
</div>
<div class="w-10/12">
<p x-text="todo.todo" :class="{ 'line-through': todo.completed }"></p>
</div>
<div class="w-1/12 text-center">
<button class="bg-red-600 text-white px-2 py-1 rounded hover:bg-red-700" @click="deleteToDo(index)">
✗
</button>
</div>
</div>
</template>
</div>
<div>
<span x-text="numberOfToDosCompleted()"></span> / <span x-text="toDoCount()"></span> to dos completed
</div>
</div>
<script>
function toDoList() {
return {
newTodo: "",
todos: [],
addToDo() {
this.todos.push({
todo: this.newTodo,
completed: false
});
this.newTodo = "";
},
toggleToDoCompleted(index) {
this.todos[index].completed = !this.todos[index].completed;
},
deleteToDo(index) {
this.todos = this.todos.filter((todo, todoIndex) => {
return index !== todoIndex
})
},
numberOfToDosCompleted() {
return this.todos.filter(todo => todo.completed).length;
},
toDoCount() {
return this.todos.length
},
isLastToDo(index) {
return this.todos.length - 1 === index
}
};
}
</script>
<!-- 1. Automatic init function calls -->
<div x-data="{
init() {
console.log('Here we go!')
}
}"></div>
<!-- 2. Clean up after yourself with destroy -->
<div x-data="{
init() {
carouselLibrary.create();
},
destroy() {
carouselLibrary.delete();
}
}"></div>
<!-- 3. Interact with global stores from external JavaScript -->
Alpine.store('counter', {
count: 0
})
// In a different file or area.
Alpine.store('counter').count += 1
<!-- 4. Independent x-init directives -->
<div x-data>
<p x-init="console.log('I am ready!')"></p>
</div>
<img src="..." x-init="doSomeMagicHere()">
<!-- 5. Unfurl / unwrap Proxy with Alpine.raw -->
<div x-data="{ user: { name: 'Ryan' } }" x-init="console.log(user)">
<!-- This produces a `Proxy` in the console -->
</div>
<div x-data="{ user: { name: 'Ryan' } }" x-init="console.log(Alpine.raw(user))">
<!-- This produces the "real" `user` object in the console -->
</div>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Alpine Examples</title>
<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js"
defer
></script>
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css"
rel="stylesheet"
>
</head>
<body class="p-12">
<!-- Flash -->
<div
x-data="{ show: false, message: '' }"
x-show.transition.opacity.scale.75.duration="show"
@flash.window="
show = true;
message = $event.detail;
setTimeout(() => show = false, 3000);
"
x-text="message"
class="fixed bottom-0 right-0 mb-4 mr-4 bg-blue-500 text-white p-4 rounded"
>
</div>
<script>
// Additionally, any component can call $dispatch('flash', 'A flash message');
window.flash = message => window.dispatchEvent(new CustomEvent('flash', {detail: message}));
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<script src="//unpkg.com/alpinejs" defer></script>
</head>
<body>
<div x-data>
<button @click="$el.remove()">remove me 1</button>
<button @click="$event.target.remove()">remove me 2</button>
</div>
</body>
</html>