It is very useful when the database access is slow or you access external services like APIs. You can make a loading animation while the page is being rendered.
For example, first create a template called loading.html
.
<div
style="
position: fixed;
inset: 0;
z-index: 9999;
backdrop-filter: blur(3px);
"
></div>
This code will blur the entire page. You can customize it as you like.
Add a tag with #loading
to your main layout, or HTML fragment that all templates share.
<section id="loading"></section>
Now you can make tools_template.py
in the app or root folder with the following content.
from django.template.loader import render_to_string
from liveview.context_processors import get_global_context
async def toggle_loading(consumer, show=False):
"""Toogle Loading template."""
data = {
"action": ("Show" if show else "Hide") + " loading",
"selector": "#loading",
"html": render_to_string(
"loading.html", get_global_context(consumer=consumer)
)
if show
else "",
}
await consumer.send_html(data)
def loading(func):
"""Decorator: Show loading."""
async def wrapper(*args, **kwargs):
await toggle_loading(args[0], True)
result = await func(*args, **kwargs)
await toggle_loading(args[0], False)
return result
return wrapper
And in the action file, you can use the @loading
decorator.
from app.tools_template import loading
@loading
async def send_page(consumer, client_data, lang=None):
my_context = await get_context(consumer=consumer)
html = await get_html(template, my_context)
data = {
"action": client_data["action"],
"selector": "#main",
"html": html,
}
data.update(my_context)
await consumer.send_html(data)
This will render the loading HTML in #loading
before running the action and clear all the HTML when finished.