-
Notifications
You must be signed in to change notification settings - Fork 25
Expand file tree
/
Copy pathpart4_ex1_solution_app.py
More file actions
60 lines (51 loc) · 1.65 KB
/
part4_ex1_solution_app.py
File metadata and controls
60 lines (51 loc) · 1.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# PART 4 - Exercise 1 - Solution
# //////////////////////////////
from shiny import App, ui, reactive, render, req
import pandas as pd
from datetime import datetime
app_ui = ui.page_fluid(
ui.card(
ui.card_header("Create Task"),
ui.input_text("task", "Description", width="auto"),
ui.input_action_button("add", "Add task", width="150px"),
),
ui.card(
ui.card_header("ToDo list"),
ui.output_data_frame("tbl"),
ui.input_action_button(
"completed", "Mark selected task as complete", width="300px"
),
),
)
def server(input, output, session):
# Start with empty data frame
todos = reactive.value(pd.DataFrame())
# Render the todos in the table
@render.data_frame
def tbl():
return render.DataTable(todos(), selection_mode="row", width="100%")
# Add a new todo
@reactive.effect
@reactive.event(input.add)
def _():
req(input.task().strip())
newTask = pd.DataFrame(
{
"created": [datetime.now().strftime("%Y-%m-%d %H:%M:%S")],
"task": [input.task()],
"completed": [None],
}
)
todos.set(pd.concat([todos(), newTask], ignore_index=True))
ui.update_text("task", value="")
# Mark as completed based on selected row
@reactive.effect
@reactive.event(input.completed)
def _():
req(tbl.cell_selection()["rows"])
updates = todos().copy()
updates.at[tbl.cell_selection()["rows"][0], "completed"] = (
datetime.now().strftime("%Y-%m-%d %H:%M:%S")
)
todos.set(updates)
app = App(app_ui, server)