Skip to content

Instantly share code, notes, and snippets.

@thesubhendu
Created October 19, 2024 06:50
Show Gist options
  • Save thesubhendu/8274e196e464ab0112883a864cf216e7 to your computer and use it in GitHub Desktop.
Save thesubhendu/8274e196e464ab0112883a864cf216e7 to your computer and use it in GitHub Desktop.
Multi step form ALpine js
<x-guest-layout>
<div x-data="jobApplication()" class="max-w-2xl mx-auto p-6">
<h2 class="text-2xl font-bold mb-6">Developer Job Application</h2>
<div x-show="Object.keys(errors).length > 0" class="mb-4 p-4 bg-red-100 border border-red-400 text-red-700 rounded">
<h4 class="font-bold mb-2">Please correct the following errors:</h4>
<ul class="list-disc list-inside">
<template x-for="(error, key) in errors" :key="key">
<li x-text="error[0]"></li>
</template>
</ul>
</div>
<section x-show="step === 1">
<h3 class="text-xl font-semibold mb-4">Step 1: Professional Information</h3>
<form @submit.prevent="nextStep">
<div class="mb-4">
<label for="area" class="block mb-2">Choose Area:</label>
<select id="area" x-model="formData.area" @change="updateTechnologies" class="w-full p-2 border rounded" required>
<option value="">Select an area</option>
<option value="frontend">Frontend</option>
<option value="backend">Backend</option>
<option value="ui-ux">UI/UX</option>
</select>
</div>
<div x-show="formData.area" class="mb-4">
<label class="block mb-2">Choose Technologies:</label>
<div class="space-y-2">
<template x-for="tech in technologies" :key="tech">
<div>
<input type="checkbox"
:id="tech" :value="tech"
x-model="formData.selectedTechnologies"
@change="updateExperienceFields" class="mr-2">
<label :for="tech" x-text="tech"></label>
</div>
</template>
</div>
</div>
<div x-show="formData.selectedTechnologies.length > 0" class="mb-4">
<label class="block mb-2">Years of Experience:</label>
<div class="space-y-2">
<template x-for="tech in formData.selectedTechnologies" :key="tech">
<div class="flex items-center">
<label :for="'exp_' + tech" x-text="tech + ':'" class="w-1/3"></label>
<input type="number" :id="'exp_' + tech" x-model="formData.experience[tech]" class="w-2/3 p-2 border rounded" min="0" required>
</div>
</template>
</div>
</div>
<button type="submit"
class="inline-flex items-center px-4 py-2 bg-gray-800 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-gray-700 focus:bg-gray-700 active:bg-gray-900 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 transition ease-in-out duration-150 ms-3"
>Next</button>
</form>
</section>
<section x-show="step === 2">
<h3 class="text-xl font-semibold mb-4">Step 2: Personal Information</h3>
<form @submit.prevent="submitForm">
<div class="mb-4">
<label for="name" class="block mb-2">Full Name:</label>
<input type="text" id="name" x-model="formData.name" class="w-full p-2 border rounded" required>
</div>
<div class="mb-4">
<label for="email" class="block mb-2">Email:</label>
<input type="email" id="email" x-model="formData.email" class="w-full p-2 border rounded" required>
</div>
<div class="mb-4">
<label for="phone" class="block mb-2">Phone:</label>
<input type="tel" id="phone" x-model="formData.phone" class="w-full p-2 border rounded" required>
</div>
<button type="button" @click="prevStep" >Previous</button> ||
<button
type="submit"
class="inline-flex items-center px-4 py-2 bg-gray-800 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-gray-700 focus:bg-gray-700 active:bg-gray-900 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 transition ease-in-out duration-150 ms-3"
:disabled="loading"
>Submit Application</button>
</form>
</section>
</div>
<script>
function jobApplication() {
return {
step: 1,
totalSteps: 2,
loading: false,
formData: {
area: '',
selectedTechnologies: [],
experience: {},
name: '',
email: '',
phone: ''
},
errors: [],
technologies: [],
init() {
addEventListener('popstate', (e) => {
const params = new URLSearchParams(window.location.search);
if(params.get('step')) {
this.step = parseInt(params.get('step'))
}else{
this.step = 1;
}
})
},
updateTechnologies() {
this.formData.selectedTechnologies = [];
this.formData.experience = {};
switch (this.formData.area) {
case 'frontend':
this.technologies = ['React', 'Vue', 'Angular', 'Svelte'];
break;
case 'backend':
this.technologies = @json($backendTechnologies);
break;
case 'ui-ux':
this.technologies = ['Figma', 'Sketch', 'Adobe XD', 'InVision'];
break;
default:
this.technologies = [];
}
},
updateExperienceFields() {
let newExperience = {};
this.formData.selectedTechnologies.forEach(tech => {
newExperience[tech] = this.formData.experience[tech] || '';
});
this.formData.experience = newExperience;
},
nextStep() {
if(this.step < this.totalSteps){
this.step++;
window.history.pushState(null, '', `?step=${this.step}`);
}
},
prevStep() {
if(this.step > 1){
this.step--;
window.history.pushState(null, '', `?step=${this.step}`);
}
},
submitForm() {
// Submit form data to the backend
this.loading = true;
fetch('/submit-application', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
},
body: JSON.stringify(this.formData)
})
.then(response => response.json())
.then(data => {
this.loading=false
// alert('Application submitted successfully!');
if(data.errors){
this.errors = data.errors;
}
// Reset form or redirect to a thank you page
})
.catch(error => {
console.error('Errorddd:', error);
// alert('An error occurred while submitting your application. Please try again.');
});
}
}
}
</script>
</x-guest-layout>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment