<form action="#" method="POST" class="space-y-6" x-data="dynamicForm()">
<div>
<label for="name" class="block text-sm font-medium text-gray-700">Name</label>
<input type="text" id="name" name="name" class="mt-1 block w-full p-2 border border-gray-300 rounded-md shadow-sm" required>
</div>
<div>
<label for="email" class="block text-sm font-medium text-gray-700">Email</label>
<input type="email" id="email" name="email" class="mt-1 block w-full p-2 border border-gray-300 rounded-md shadow-sm" required>
</div>
<!-- Placeholder for dynamic fields -->
<template x-for="(field, index) in fields" :key="index">
<div class="flex items-center space-x-4">
<div class="flex-grow">
<label :for="'field-' + index" class="block text-sm font-medium text-gray-700">Field</label>
<input :id="'field-' + index" type="text" class="mt-1 block w-full p-2 border border-gray-300 rounded-md shadow-sm" x-model="field.value" required>
</div>
<button type="button" class="bg-red-500 text-white p-2 rounded" @click="removeField(index)">Remove</button>
</div>
</template>
<button type="button" class="bg-blue-500 text-white p-2 rounded" @click="addField()">Add New Field</button>
<div>
<button type="submit" class="bg-green-500 text-white p-2 rounded">Submit</button>
</div>
</form>
- The
x-data="dynamicForm()"
attribute tells Alpine.js to initialize a local component with the dynamicForm()
function (which we’ll define soon). - There are static form fields for name and email.
- The dynamic fields will be added inside the
<template>
using x-for
, which will loop through an array of fields. - We have an Add New Field button that adds a new dynamic field and a Remove button next to each field.