FluidFrameDev/tutorials/02-data-tables.md

3.0 KiB
Raw Blame History

tutorials/02-data-tables.md

# 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

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:
![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.