How to create a Django form in 2mins using Alpine.js ποΈ
Published: July 27, 2023
There will be 4 steps. Each takes under 30 seconds.
We'll assume that you've already setup your Django
project
and created an app (I'll be using one I named sim
). You don't need to
know anything about
Alpine.js
. I'll walk you through.
My video follows the guide below. Let's get to it!
1. Create template
- create a folder called
templates
in yoursim
app - add an html file, we'll call it example.html
- add your form html to the template
<div>
<form>
<div>
<input name="email" type="email" />
<input name="codename" type="text" />
<input name="dress_color" type="color" />
<button>Submit</button>
</div>
<div>
<p>Successfully submitted form β
</p>
</div>
<div>
<p>Error submitting your form β</p>
</div>
</form>
</div>
2. Add your Django view
- Add your view, update your urls, and check that a template is rendered at the right url.
# views.py
from django.shortcuts import render
def example(request):
return render(request, 'templates/example.html', context={})
def sample_post(request):
data = request.POST
print(f'{data = }')
return JsonResponse({'status': 'success'})
# urls.py
from . import views
from django.urls import path
urlpatterns = [
path('example', views.example, name='example'),
path('sample-post/', views.sample_post, name='sample_post')
]
3. Add alpine js to template
- Add Alpine js submit function
- include the Django CSRF token
- add your specific view url path
- Add Alpine js syntax to control the form and manage the form's state
- Add Alpine js loader script using a CDN (very fast and light)
<div>
<form @submit.prevent="submit" x-data="{ status: 'normal', errors: {} }">
<div x-show="status === 'normal'">
<input name="email" type="email" />
<input name="codename" type="text" />
<input name="dress_color" type="color" />
<button>Submit</button>
</div>
<div x-show="status === 'success'">
<p>Successfully submitted form β
</p>
</div>
<div x-show="status === 'error'">
<p>Error submitting your form β</p>
</div>
</form>
</div>
<script>
function submit(event) {
event.preventDefault()
const formData = new FormData(event.target)
// Update the `endpointUrl` to your specific url below.
const endpointUrl = '/sample-post/'
fetch(endpointUrl, {
method: 'post',
body: formData,
headers: {
'X-CSRFToken': '{{ csrf_token }}',
},
})
.then((response) => {
this.status = response.ok ? 'success' : 'error'
return response.json()
})
.then((data) => {
this.errors = data.errors || {}
})
}
</script>
<script
defer=""
src="https://cdn.jsdelivr.net/npm/alpinejs@3.12.3/dist/cdn.min.js"
></script>
4. Check that the view works as expected
- Submit something.
- Check in the Django run console that you see something like:
data = {"email": ..., "codename": ..., "dress_color":...}
Bonus: Prevent form flickering due to alpine loading
- Add x-cloak to the form. This will hide the form until it's finished loading (avoiding flicker).
- Add x-cloak into the style tag (or add a similar line to any stylesheet that you are using)
<div>
<form
x-cloak
@submit.prevent="submit"
x-data="{ status: 'normal', errors: {} }"
>
<div x-show="status === 'normal'">
<input name="email" type="email" />
<input name="codename" type="text" />
<input name="dress_color" type="color" />
<button>Submit</button>
</div>
<div x-show="status === 'success'">
<p>Successfully submitted form β
</p>
</div>
<div x-show="status === 'error'">
<p>Error submitting your form β</p>
</div>
</form>
</div>
<script>
function submit(event) {
event.preventDefault()
const formData = new FormData(event.target)
// Update the `endpointUrl` to your specific url below.
const endpointUrl = '/sample-post/'
fetch(endpointUrl, {
method: 'post',
body: formData,
headers: {
'X-CSRFToken': '{{ csrf_token }}',
},
})
.then((response) => {
this.status = response.ok ? 'success' : 'error'
return response.json()
})
.then((data) => {
this.errors = data.errors || {}
})
}
</script>
<script
defer=""
src="https://cdn.jsdelivr.net/npm/alpinejs@3.12.3/dist/cdn.min.js"
></script>
<style>
[x-cloak] {
display: none !important;
}
</style>
Congratulations! Using Alpine.js is a neat, clean way to add simple JavaScript, including managing state, to your Django templates.