Turbo Frame Basics
Objective
- Learn what is Turbo Frame
- Understand how Turbo Frame works
What is Turbo Frame
Turbo Frame can help us treat part of our page like HTML iframe
element.
Turbo Frames allow predefined parts of a page to be updated on request. Any links and forms inside a frame are captured, and the frame contents automatically updated after receiving a response.
With Turbo Frame, we can update segment of our page without reloading the whole page.
Simple Example
Let's first create an index
page in the turbo_frame
Django app.
View
Update hotwire_django_app/turbo_frame/views.py
def index_view(request):
return render(request, 'turbo_frame/index.html')
We added a index_view
Template
Create hotwire_django_app/templates/turbo_frame/index.html
{% extends "turbo_frame/base.html" %}
{% block content %}
<div class="w-full max-w-7xl mx-auto px-4">
<h1 class="text-4xl sm:text-6xl lg:text-7xl mb-6">Turbo Frame Index Page</h1>
</div>
{% endblock %}
We create a simple index page, we will update it in a bit.
Update hotwire_django_app/templates/turbo_frame/navbar.html to add {% url 'turbo-frame:index' %}
link
<nav class="flex items-center justify-between flex-wrap bg-teal-500 p-6 mb-4">
<div class="w-full">
<a href="{% url 'turbo-frame:task-list' %}" class="inline-block mt-0 text-teal-200 hover:text-white mr-4">
List
</a>
<a href="{% url 'turbo-frame:task-create' %}" class="inline-block mt-0 text-teal-200 hover:text-white mr-4">
Create
</a>
<a href="{% url 'turbo-frame:index' %}" class="inline-block mt-0 text-teal-200 hover:text-white mr-4">
Turbo Frame Index
</a>
</div>
</nav>
We add Turbo Frame Index
link to the top navbar.
URL
Update hotwire_django_app/turbo_frame/urls.py
from django.urls import path
from .views import list_view, create_view, update_view, delete_view, detail_view, index_view # update
app_name = 'turbo-frame'
urlpatterns = [
path('', index_view, name='index'), # new
path('list/', list_view, name='task-list'),
path('create/', create_view, name='task-create'),
path('<int:pk>/', detail_view, name='task-detail'),
path('<int:pk>/update/', update_view, name='task-update'),
path('<int:pk>/delete/', delete_view, name='task-delete'),
]
Test
Test on http://127.0.0.1:8000/turbo-frame/, we can see an empty page.
Add Turbo Frame
Update hotwire_django_app/templates/turbo_frame/index.html
{% extends "turbo_frame/base.html" %}
{% block content %}
<div class="w-full max-w-7xl mx-auto px-4">
<h1 class="text-4xl sm:text-6xl lg:text-7xl mb-6">Turbo Frame Index Page</h1>
<turbo-frame id="task-list"> <!-- new -->
<a class="btn-blue" href="{% url 'turbo-frame:task-list' %}">Click me to load</a>
</turbo-frame>
</div>
{% endblock %}
Notes:
- We add
turbo-frame
element to the index page. - It contains a link, if we click the link, Turbo will capture the event, and load the url to update the content of the frame
If we click the link on http://127.0.0.1:8000/turbo-frame/
In the browser devtool, we can see http request has been sent to visit http://127.0.0.1:8000/turbo-frame/list/
, but the content of the turbo-frame is not updated.
We can also see The response (200) did not contain the expected <turbo-frame id="task-list"> and will be ignored.
from the console of the devtool.
Each turbo frame must have a unique ID, which is used to match the content being replaced when requesting new pages from the server
Let's update hotwire_django_app/templates/turbo_frame/list_page.html
{% extends "turbo_frame/base.html" %}
{% block content %}
<div class="w-full max-w-7xl mx-auto px-4">
<h1 class="text-4xl sm:text-6xl lg:text-7xl mb-6">Task List</h1>
<turbo-frame id="task-list"> <!-- new -->
<div class="md:w-2/3 bg-white rounded-lg border mb-4">
<ul class="divide-y-2 divide-gray-100" id="task-list-ul">
{% for instance in object_list %}
<li class="p-3 flex items-center">
{% include 'turbo_frame/task_detail.html' with instance=instance only %}
</li>
{% endfor %}
</ul>
</div>
</turbo-frame>
</div>
{% endblock %}
- We use
turbo-frame id="task-list"
to wrap the list div.
Now test again.
- If we click the link, Turbo will send request to fetch the list page.
- After getting the response, Turbo will update the content of the
<turbo-frame id="task-list">
Notes
Actually, this feature can also be done using valina Javascript, but turbo-frame
helps us get things done in a more clean way.