Loading | Django LiveView

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.