Dynamic input fields using Alpine

In this tutorial we’ll use Alpine.js in order to achieve dynamic input fields functionality. In previous article we used Vue to have the same functionality. Alpine is similar to Vue syntax-wise, however, it’s very lightweight as compared to Vue. Sometimes Alpine is regarded as modern replacement to jQuery and it forms an integral part of TALL (Tailwind, Alpine, Laravel, Livewire) stack of Laravel ecosystem.

So, let’s open the editor of your choice and enter following code;

<html>
	<head>
		<meta charset="UTF-8">
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<title>AlpineJS Dynamic Input Fields</title>
		<script defer src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"></script>
		<script src="https://cdn.tailwindcss.com"></script>
	</head>
	<body>
		<div x-data="{
			rows: [{item: '', quantity: '', rate: ''}],
			addRow() {
				this.rows.push({
					item: '',
					quantity: '',
					rate: ''
					});
				},
			deleteRow(index) {
				this.rows.splice(index, 1);
				}
			  }">
			<div class="bg-gray-100 rounded-lg shadow m-4">
				<div class="grid grid-cols-8 text-gray-500">
					<div class="col-span-2">
						<label class="p-2 m-2">Item</label>
					</div>
					<div class="col-span-2">
						<label class="p-2 m-2">Quantity</label>
					</div>
					<div class="col-span-2">
						<label class="p-2 m-2">Rate</label>
					</div>
				</div>
				<template x-for="(row, index) in rows" :key="index">
					<div class="grid grid-cols-8">
						<div class="col-span-2 m-1">
							<input x-model="row.item" type="text" class="p-1 w-full rounded-md border border-gray-300"/>
						</div>
						<div class="col-span-2 m-1">
							<input x-model="row.quantity" type="text" class="p-1 w-full rounded-md border border-gray-300"/>
						</div>
						<div class="col-span-2 m-1">
							<input x-model="row.rate" type="text" class="p-1 w-full rounded-md border-solid border border-gray-300"/>
						</div>
						<div class="col-span-2 m-1">
							<button x-show="index > 0" @click="deleteRow(index)" class="border bg-red-600 hover:bg-red-700 text-white rounded-md px-2 py-1 ml-2 inline-block">X</button>
						</div>
					</div>
				</template>
				<div class="p-4">
					<button class="bg-indigo-600 hover:bg-indigo-700 text-white text-center text-sm rounded-md px-4 py-1"  @click="addRow()" >Add Row</button>
				</div>
			</div>
		</div>
	</body>
</html>

Save it as an HTML file and then open it in the browser.

Leave a Comment