In this video we will assume this Flask app:
import time
from flask import Flask, render_template, request
app = Flask(__name__)
numbers = list(range(1, 1001))
@app.route("/")
def index():
return render_template("02-index.html", numbers=numbers)
@app.route("/search")
def search():
time.sleep(1) # Simulate a slow query
query = request.args.get("query", "").lower()
filtered_numbers = [num for num in numbers if query in str(num)]
# Generate HTML string directly
html = "<ul>"
for number in filtered_numbers:
html += f"<li>{number}</li>"
html += "</ul>"
return html
if __name__ == "__main__":
app.run(debug=True)
This app assumes that there is a folder called templates
with an 02-index.html
file that looks like this:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Number Filter</title>
<script src="https://unpkg.com/htmx.org"></script>
</head>
<body>
<h1>Number Filter</h1>
<input type="text" name="query" placeholder="Search numbers..."
hx-get="/search"
hx-trigger="keyup changed delay:500ms"
hx-target="#number-list"
hx-indicator="#spinner">
<div id="spinner" class="htmx-indicator">Searching...</div>
<div id="number-list">
</div>
</body>
</html>
This app is similar to the previous one but we are no longer dealing with a mere button press. In this case we have a text bar and we respond every time that a user starts typing. The backend still returns HTML to the user, but makes sure that we only return a subset of numbers.
One very interesting thing is that the hx-trigger
attribute has extra contents that modifies the behavior. We don't respond to every single character that is typed, but instead we wait for a few milliseconds after the last key press before sending a request to the backend. This is a very powerful feature of HTMX that allows you to control the behavior of your app in a very fine-grained way.