On this occasion I want to share about how I create a popup with dynamic data based on a certain index in a laravel and alpinejs project.
Immediately, for example we have product data, In controller, we pass data from model to views app.
return view('app', [
'products' => Product::isPublished(0)->get()
]);
Then on the blade app page, we convert the collection model to json like this.
@php
$products = $products->toJson();
@endphp
That way we can set the state value with the json.
<body x-data="{ products : {{ $products }}, detailData : '' }">
-----
-----
</body>
Based on the above code, we have defined two state products and detailData. detailData is useful for storing data based on a certain index used in the modal component.
Next we will make a list of products, the code is like this.
<div class="divide-y mt-5">
<template x-for="(product,i) in products" :key="product.id">
<div class="flex flex-row w-full px-6 py-6 mx-auto bg-white rounded-lg sm:px-4 sm:py-5">
<div class="ml-2 mr-4">
<a href="#" type="button" @click="detailData = products[i]" data-modal-toggle="defaultModal">
<img class="rounded-lg" src="https://storage.googleapis.com/public-listee-menu-items/77_eb66ceac-7d52-443e-b96a-d2ee1db522b1_thumbnail.png" alt="product image" />
</a>
</div>
<div>
<h3 class="text-lg font-bold text-purple-500 sm:text-xl md:text-2xl" x-text="product.name"></h3>
<p class="mt-2 text-base text-gray-400 sm:text-sm md:text-normal" x-text="product.description"></p>
<p class="mt-2 text-base font-semibold text-gray-700 sm:text-lg md:text-normal" x-text="product.price"></p>
</div>
</div>
</template>
</div>
A little explanation, in the code above we iterate the data using x-for alpinejs.
x-for="(product,i) in products" :key="product.id"
Then set the text using x-text
Then we also have the directive @click="detailData = products[i]", which assigns a value to the detailData variable when clicked, so detailData now has data based on the index clicked.
Modal
<div id="defaultModal" aria-hidden="true" class="hidden overflow-y-auto overflow-x-hidden fixed right-0 left-0 top-4 z-50 justify-center items-center h-modal md:h-full md:inset-0">
<div class="relative px-4 w-full max-w-2xl h-full md:h-auto">
<!-- Modal content -->
<div class="relative bg-white rounded-lg shadow dark:bg-gray-700">
<!-- Modal header -->
<div class="flex justify-between items-start p-3 rounded-t border-b dark:border-gray-600">
<h3 class="text-xl font-semibold text-gray-900 lg:text-2xl dark:text-white">
Menu Item
</h3>
<button type="button" class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm p-1.5 ml-auto inline-flex items-center dark:hover:bg-gray-600 dark:hover:text-white" data-modal-toggle="defaultModal">
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg>
</button>
</div>
<!-- Modal body -->
<div class="p-3 space-y-6">
<div class="divide-y">
<div class="flex flex-row w-full px-6 py-3 mx-auto bg-white rounded-lg sm:px-4 sm:py-5 ">
<div class="ml-2 mr-4">
<a href="#" type="button" data-modal-toggle="defaultModal">
<img class="rounded-lg" src="https://storage.googleapis.com/public-listee-menu-items/77_eb66ceac-7d52-443e-b96a-d2ee1db522b1_thumbnail.png" alt="product image" />
</a>
</div>
<div>
<h3 class="text-lg font-bold text-purple-500 sm:text-xl md:text-1xl" x-text="detailData.name"></h3>
<p class="text-base text-gray-400 sm:text-sm md:text-normal" x-text="detailData.description"></p>
<p class="text-base font-semibold text-gray-700 sm:text-lg md:text-normal" x-text="detailData.price"></p>
</div>
</div>
</div>
<div class="px-6 mb-2">
<label for="large-input" class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300">Special Instructions (Optional)</label>
<textarea type="text" id="large-input" placeholder="food description" class="block p-4 w-full text-gray-900 bg-gray-50 rounded-lg border border-gray-300 sm:text-md focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"></textarea>
</div>
<div class="flex items-center justify-center p-6 space-x-2 rounded-b border-t border-gray-200 dark:border-gray-600">
<button data-modal-toggle="defaultModal" type="button" class="text-black text-2xl bg-gray-200 hover:bg-gray-400 focus:ring-4 focus:ring-blue-300 font-medium rounded-full text-sm px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">-</button>
<p class="px-6 text-base leading-relaxed text-gray-500 font-bold text-2xl dark:text-gray-400">8</p>
<button data-modal-toggle="defaultModal" type="button" class="text-black text-2xl text-center bg-gray-200 hover:bg-gray-400 focus:ring-4 focus:ring-blue-300 font-medium rounded-full text-sm px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">+</button>
</div>
</div>
<!-- Modal footer -->
<div class="flex justify-center items-center p-6 space-x-2 rounded-b border-t border-gray-200 dark:border-gray-600">
<button data-modal-toggle="defaultModal" type="button" class="w-full h-12 px-6 text-indigo-100 transition-colors duration-150 bg-indigo-700 rounded-lg focus:shadow-outline hover:bg-indigo-800">Add to Order - Rp. 85,000</button>
</div>
</div>
</div>
</div>
In the modal, we set the text by x-text="detailData.name".
That's the steps hopefully useful. Thank You