FluidFrameDev/tutorials/02-data-tables.md

127 lines
3.0 KiB
Markdown
Raw Normal View History

**`tutorials/02-data-tables.md`**
````markdown
# 02 — Data Tables: Storing Greetings Like a Responsible Adult
**Goal:** Save each greeting into Anvils built-in database (Data Tables) and show them in a list.
---
## 1. What Youll Build
- TextBox + Button → Server
- Server saves greeting in a table
- Client displays all saved greetings in a table view (RepeatingPanel)
---
## 2. Set Up Data Tables
1. In your Anvil app → **Data Tables** (left sidebar) → **+ Add Table**
- Name: `greetings`
- Columns:
- `name` (Text)
- `message` (Text)
- `ts` (Datetime, Default: `now()`)
2. Click **Publish Changes**.
---
## 3. Server-Side Code
Edit `ServerModule1`:
```python
from anvil import tables as t, tables
import anvil.server
from datetime import datetime
@anvil.server.callable
def save_greeting(name, message):
"""Saves a greeting into the Data Table."""
tables.app_tables.greetings.add_row(
name=name,
message=message,
ts=datetime.now()
)
return f"Greeting saved for {name} at {datetime.now().strftime('%H:%M:%S')}"
@anvil.server.callable
def get_greetings():
"""Returns all greetings, newest first."""
return tables.app_tables.greetings.search(
tables.order_by("ts", ascending=False)
)
````
---
## 4. Client-Side Code
Modify `Form1` from Tutorial 01:
### a) Add a RepeatingPanel
1. Drag a **RepeatingPanel** onto `Form1` (ID: `repeating_panel_1`).
2. Bind its `items` property in code.
### b) Update Button Click
```python
def button_1_click(self, **event_args):
self.button_1.enabled = False
try:
name = self.text_box_1.text or "World"
message = anvil.server.call('hello_server', name)
Notification(message, timeout=2).show()
# Save greeting
save_status = anvil.server.call('save_greeting', name, message)
print("[Client] Save status:", save_status)
# Refresh list
self.refresh_greetings()
finally:
self.button_1.enabled = True
def refresh_greetings(self):
greetings = anvil.server.call('get_greetings')
self.repeating_panel_1.items = greetings
```
---
## 5. Create a Row Template for RepeatingPanel
1. Double-click the RepeatingPanel → Create **FormTemplate1**.
2. Add three Labels:
* `label_name` → Bind text: `self.item['name']`
* `label_message` → Bind text: `self.item['message']`
* `label_ts` → Bind text: `self.item['ts']`
3. Style it so it doesnt look like a 90s spreadsheet.
---
## 6. Bonus Challenge (Optional)
* Add a “Clear All” button (server function to delete all rows).
* Add pagination (limit query results, add “Load More” button).
* Highlight greetings from the last minute in green.
---
## 7. Assets
* **GIF:** Show saving multiple greetings and the list updating.
* Save as `/assets/data-tables-demo.gif`
* Reference here:
```markdown
![Data Tables Demo](../assets/data-tables-demo.gif)
```
---
## 8. Takeaways
* Data Tables are like SQLite without the SQLite drama.
* Always validate server inputs before saving.
* Query ordering matters — newest first keeps users happy.
---