Skip to content

Instantly share code, notes, and snippets.

@bpeterso2000
Created May 18, 2025 22:25
Show Gist options
  • Save bpeterso2000/ab80e8abe733590a795b52d031b98ef2 to your computer and use it in GitHub Desktop.
Save bpeterso2000/ab80e8abe733590a795b52d031b98ef2 to your computer and use it in GitHub Desktop.
from fasthtml.common import *
from fastlite import Database, Table
from typing import List, Dict, Any
# Initialize FastLite database
db = Database("users.db")
Users = db.t.users
if not Users.exists():
Users.create(id=int, name=str, email=str, pk="id")
# FastHTML app setup
app = FastHTML(hdrs=(picolink, Script(src="https://code.jquery.com/jquery-3.6.0.min.js"),
Link(rel="stylesheet", href="https://cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid.min.css"),
Link(rel="stylesheet", href="https://cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid-theme.min.css"),
Script(src="https://cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid.min.js")))
# Helper to convert database rows to list of dicts for jsGrid
def users_to_list() -> List[Dict[str, Any]]:
return [dict(id=user.id, name=user.name, email=user.email) for user in Users()]
# Main route: Render the datagrid
@app.get("/")
def home():
return Title("User Management"), Main(
H1("User Management"),
# Form for adding new users
Form(
Input(type="text", name="name", placeholder="Name", required=True),
Input(type="email", name="email", placeholder="Email", required=True),
Button("Add User", type="submit"),
hx_post="/add",
hx_target="#grid",
hx-swap="outerHTML"
),
# Div for jsGrid
Div(id="grid"),
# Initialize jsGrid with HTMX response
Script("""
function loadGrid(data) {
$("#grid").jsGrid({
width: "100%",
height: "400px",
editing: true,
sorting: true,
paging: true,
data: data,
fields: [
{ name: "name", type: "text", width: 150, validate: "required" },
{ name: "email", type: "text", width: 200, validate: "required" },
{ type: "control", width: 100 }
],
onItemUpdating: function(args) {
htmx.ajax('POST', '/update/' + args.item.id, {
values: { name: args.item.name, email: args.item.email }
});
},
onItemDeleting: function(args) {
htmx.ajax('DELETE', '/delete/' + args.item.id, {
target: '#grid',
swap: 'outerHTML'
});
}
});
}
// Initial load
htmx.ajax('GET', '/data', {
target: '#grid',
swap: 'outerHTML'
});
""")
)
# Route to fetch data for jsGrid
@app.get("/data")
def get_data():
return Div(id="grid", hx_trigger="load", hx_get="/data", Script(f"loadGrid({users_to_list()!r});"))
# Route to add a new user
@app.post("/add")
def add_user(name: str, email: str):
user = Users.insert(dict(name=name, email=email))
return Div(id="grid", hx_trigger="load", hx_get="/data", Script(f"loadGrid({users_to_list()!r});"))
# Route to update a user
@app.post("/update/{id}")
def update_user(id: int, name: str, email: str):
Users.update(dict(id=id, name=name, email=email))
return "" # Empty response since jsGrid updates client-side
# Route to delete a user
@app.delete("/delete/{id}")
def delete_user(id: int):
Users.delete(id)
return Div(id="grid", hx_trigger="load", hx_get="/data", Script(f"loadGrid({users_to_list()!r});"))
# Run the app
if __name__ == "__main__":
serve()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment