from fastapi import FastAPI, Request from fastapi.responses import HTMLResponse from fastapi.staticfiles import StaticFiles import random import asyncio app = FastAPI() app.mount("/static", StaticFiles(directory="static"), name="static") @app.get("/", response_class=HTMLResponse) async def read_root(): return """ HTMX Demo

Dynamic Filters with Infinite Scroll

""" def generate_fake_data(page: int, category: str, color: str): return [{"name": f"Item {i}", "category": category or f"Category{i % 3 + 1}", "color": color or random.choice(["Red", "Blue", "Green"])} for i in range(page * 10, (page + 1) * 10)] @app.get("/filter", response_class=HTMLResponse) async def filter(request: Request, category: str = "", color: str = "", page: int = 0): await asyncio.sleep(0.5) filtered_data = generate_fake_data(page, category, color) next_page = page + 1 hx_load_more_attrs = f""" hx-get="/filter?page={next_page}&category={category}&color={color}" hx-target="#results" hx-swap="beforeend" hx-trigger="revealed" hx-indicator="#indicator" """ return ''.join( f"""
  • {item["name"]} - {item["category"]} - {item["color"]}
  • """ for item in filtered_data )