Skip to content

Commit bd5885f

Browse files
New handler for adding todo
Co-authored-by: Audrey Roy Greenfeld <[email protected]>
1 parent ef181b4 commit bd5885f

File tree

1 file changed

+39
-16
lines changed

1 file changed

+39
-16
lines changed

examples/adv_app2.py

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,23 @@ class Todo:
1515
db.users = db.create(User, transform=True, pk='name')
1616
db.todos = db.create(Todo, transform=True)
1717

18+
@patch
19+
def __ft__(self:Todo):
20+
# Some FastHTML tags have an 'X' suffix, which means they're "extended" in some way.
21+
# For instance, here `AX` is an extended `A` tag, which takes 3 positional arguments:
22+
# `(text, hx_get, target_id)`.
23+
# All underscores in FT attrs are replaced with hyphens, so this will create an `hx-get` attr,
24+
# which HTMX uses to trigger a GET request.
25+
# Generally, most of your route handlers in practice (as in this demo app) are likely to be HTMX handlers.
26+
# For instance, for this demo, we only have two full-page handlers: the '/login' and '/' GET handlers.
27+
show = AX(self.title, f'/todos/{self.id}', 'current-todo')
28+
edit = AX('edit', f'/edit/{self.id}' , 'current-todo')
29+
dt = '✅ ' if self.done else ''
30+
# FastHTML provides some shortcuts. For instance, `Hidden` is defined as simply:
31+
# `return Input(type="hidden", value=value, **kwargs)`
32+
cts = (dt, show, ' | ', edit, Hidden(id="id", value=self.id), Hidden(id="priority", value="0"))
33+
# Any FT object can take a list of children as positional args, and a dict of attrs as keyword args.
34+
return Li(*cts, id=f'todo-{self.id}')
1835

1936
def user_auth_before(req, sess):
2037
auth = req.scope['auth'] = sess.get('auth', None)
@@ -25,26 +42,11 @@ def user_auth_before(req, sess):
2542
user_auth_before,
2643
skip=[r'/favicon\.ico', r'/static/.*', r'.*\.css', r'.*\.js', '/login']
2744
)
28-
29-
3045
app, rt = fast_app(hdrs=Theme.blue.headers(),before=beforeware)
3146

47+
# Authentication
3248
login_redir = Redirect('/login')
3349

34-
35-
@rt
36-
def index(auth):
37-
top = Grid(Div(A('logout', href=logout), style='text-align: right'))
38-
new_inp = Input(id="new-title", name="title", placeholder="New Todo")
39-
add = Form(Group(new_inp, Button("Add")),
40-
hx_post="/", target_id='todo-list', hx_swap="afterbegin")
41-
frm = Form(*db.todos(order_by='priority'),
42-
id='todo-list', cls='sortable', hx_post="/reorder", hx_trigger="end")
43-
44-
card = Card(Ul(frm), header=add, footer=Div(id='current-todo'))
45-
return Titled(f"{auth}'s Todo list", Container(top, card))
46-
47-
4850
@rt('/login')
4951
def get():
5052
frm = Form(
@@ -71,4 +73,25 @@ def logout(sess):
7173
del sess['auth']
7274
return login_redir
7375

76+
# Dashboard and control handlers
77+
@rt
78+
def index(auth):
79+
top = Grid(Div(A('logout', href=logout), style='text-align: right'))
80+
new_inp = Input(id="new-title", name="title", placeholder="New Todo")
81+
add = Form(Group(new_inp, Button("Add")),
82+
hx_post=add_todo, target_id='todo-list', hx_swap="afterbegin")
83+
frm = Form(*db.todos(order_by='priority'),
84+
id='todo-list', cls='sortable', hx_post="/reorder", hx_trigger="end")
85+
86+
card = Card(Ul(frm), header=add, footer=Div(id='current-todo'))
87+
return Titled(f"{auth}'s Todo list", Container(top, card))
88+
89+
@rt
90+
def add_todo(todo:Todo, auth):
91+
new_inp = LabelInput('Title', id="new-title", name="title", placeholder="New Todo", hx_swap_oob='true')
92+
# `insert` returns the inserted todo, which is appended to the start of the list, because we used
93+
# `hx_swap='afterbegin'` when creating the todo list form.
94+
return db.todos.insert(todo), new_inp
95+
96+
7497
serve()

0 commit comments

Comments
 (0)