122 lines
2.5 KiB
Markdown
122 lines
2.5 KiB
Markdown
---
|
||
|
||
**`tutorials/01-hello-fluid-frame.md`**
|
||
|
||
````markdown
|
||
# 01 — Hello, Fluid Frame
|
||
|
||
**Goal:** Click a button in your Anvil app → run a server function → get greeted in style.
|
||
|
||
---
|
||
|
||
## 1. What You’ll Build
|
||
A web app that:
|
||
- Takes your name
|
||
- Sends it to the server
|
||
- Returns a personalized greeting
|
||
- Shows it in a popup notification
|
||
|
||
Yes, it’s “Hello, World” — but with a *fluid frame*.
|
||
|
||
---
|
||
|
||
## 2. Create the App
|
||
1. Go to [Anvil](https://anvil.works) → **New App** → **Blank App** (Material Design).
|
||
2. On **Form1**:
|
||
- Drag a **TextBox** (ID: `text_box_1`, placeholder: “Enter your name”).
|
||
- Drag a **Button** (ID: `button_1`, text: “Say hi”).
|
||
3. Open **Code** view for `Form1`.
|
||
|
||
---
|
||
|
||
## 3. Client-Side Code
|
||
```python
|
||
from anvil import *
|
||
import anvil.server
|
||
|
||
class Form1(Form1Template):
|
||
def __init__(self, **properties):
|
||
self.init_components(**properties)
|
||
|
||
def button_1_click(self, **event_args):
|
||
"""This method is called when the button is clicked"""
|
||
self.button_1.enabled = False
|
||
try:
|
||
name = self.text_box_1.text or "World"
|
||
msg = anvil.server.call('hello_server', name)
|
||
Notification(msg, timeout=2).show()
|
||
finally:
|
||
self.button_1.enabled = True
|
||
````
|
||
|
||
---
|
||
|
||
## 4. Server-Side Code
|
||
|
||
1. In your Anvil app, create a **Server Module** called `ServerModule1`.
|
||
2. Paste:
|
||
|
||
```python
|
||
import anvil.server
|
||
|
||
@anvil.server.callable
|
||
def hello_server(name):
|
||
return f"Hello from the server, {name} 👋"
|
||
```
|
||
|
||
---
|
||
|
||
## 5. Run It
|
||
|
||
* Click **Run ▶**.
|
||
* Type a name and click “Say hi”.
|
||
* You should see a friendly greeting in the top-right corner.
|
||
* If not, check:
|
||
|
||
* You spelled the server function name exactly the same.
|
||
* `anvil.server.call` arguments match.
|
||
* Your internet is not powered by squirrels.
|
||
|
||
---
|
||
|
||
## 6. Bonus: Debug Like a Pro
|
||
|
||
Add print statements in both client and server code to watch the flow:
|
||
|
||
```python
|
||
print(f"[Client] Sending: {name}")
|
||
```
|
||
|
||
```python
|
||
print(f"[Server] Received: {name}")
|
||
```
|
||
|
||
Watch the logs when you run the app.
|
||
|
||
---
|
||
|
||
## 7. Assets
|
||
|
||
* **GIF:** Record a short (10–15s) clip showing:
|
||
|
||
* Typing in name
|
||
* Clicking button
|
||
* Popup greeting
|
||
* Save it to `/assets/hello-fluid-frame.gif`
|
||
* Reference in this file:
|
||
|
||
```markdown
|
||

|
||
```
|
||
|
||
---
|
||
|
||
## 8. Takeaways
|
||
|
||
* `anvil.server.call` is your client → server bridge.
|
||
* Keep UI responsive: disable buttons while waiting.
|
||
* Always match callable names exactly.
|
||
* You now have the skeleton for any input/output pattern.
|
||
|
||
---
|