Skip to content

Commit a69e9d5

Browse files
committed
wip
1 parent 9d29023 commit a69e9d5

5 files changed

Lines changed: 280 additions & 293 deletions

File tree

examples/form_disabling/model.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
class FormData(BaseModel):
77
"""Pydantic model for the form data."""
88

9+
num_banks: int = Field(default=1, ge=1, le=10, title="Number of Banks [1, 10]")
910
wavelength: float = Field(default=0.1, ge=0.1, le=1.0, title="Wavelength [0.1, 1.0]")
1011

1112

examples/form_disabling/view.py

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
from nova.mvvm.trame_binding import TrameBinding
44
from nova.trame import ThemedApp
55
from nova.trame.view.components import InputField
6-
from nova.trame.view.layouts import VBoxLayout
7-
from trame.widgets import client
6+
from nova.trame.view.layouts import GridLayout, VBoxLayout
87
from trame.widgets import vuetify3 as vuetify
98

109
from .model import Model
@@ -20,34 +19,33 @@ def __init__(self) -> None:
2019
self.create_vm()
2120
# If you forget to call connect, then the application will crash when you attempt to update the view.
2221
self.view_model.form_data_bind.connect("data")
23-
self.view_model.view_state_bind.connect("state")
2422

2523
self.create_ui()
2624

2725
def create_ui(self) -> None:
28-
with super().create_ui() as layout:
29-
# This instructs the user interface to reset itself to the most recent valid state when a browser connects
30-
# to the tool or the browser is refreshed. This is not appropriate for all situations, so it is not a
31-
# default behavior at this time. You can disable this line and then refresh your browser while the user
32-
# interface is in an error state to see the difference between the two behaviors.
33-
client.ClientTriggers(mounted=self.view_model.init_view)
26+
self.set_theme("CompactTheme")
3427

28+
with super().create_ui() as layout:
3529
with layout.pre_content:
3630
vuetify.VBanner(
3731
"The form is in an error state.",
38-
v_if="state.errors?.length > 0",
32+
v_if="errors.data?.length > 0",
3933
color="error",
4034
icon="mdi-close",
4135
)
4236

4337
with layout.content:
44-
with VBoxLayout(classes="mb-2"):
38+
with GridLayout(classes="mb-2", columns=2, gap="0.5em"):
39+
InputField(v_model="data.num_banks")
4540
InputField(v_model="data.wavelength")
4641
with VBoxLayout(halign="center"):
47-
vuetify.VBtn("{{ state.button_text }}", disabled=("state.errors?.length > 0",))
42+
vuetify.VBtn(
43+
"{{ errors.data?.length > 0 ? 'Errors Present' : 'No Errors' }}",
44+
disabled=("errors.data?.length > 0",),
45+
)
4846

4947
with layout.post_content:
50-
vuetify.VAlert("{{ state.errors }}", v_if="state.errors?.length > 0", color="error")
48+
vuetify.VAlert("{{ errors.data }}", v_if="errors.data?.length > 0", color="error")
5149

5250
def create_vm(self) -> None:
5351
binding = TrameBinding(self.state)
Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,19 @@
11
"""View model implementation for form disabling example."""
22

3-
from typing import Any, Dict, List
4-
53
from nova.mvvm.interface import BindingInterface
6-
from pydantic import BaseModel, Field, computed_field
74

85
from .model import Model
96

107

11-
class ViewState(BaseModel):
12-
"""View state Pydantic model."""
13-
14-
errors: List[str] = Field(default=[])
15-
16-
@computed_field
17-
@property
18-
def button_text(self) -> str:
19-
return "Errors Present, Button Disabled" if self.errors else "No Errors, Button Enabled"
20-
21-
228
class ViewModel:
239
"""View model implementation for form disabling example."""
2410

2511
def __init__(self, model: Model, binding: BindingInterface) -> None:
2612
self.model = model
27-
self.view_state = ViewState()
2813

2914
# self.on_update is called any time the view updates the binding.
30-
self.form_data_bind = binding.new_bind(self.model.form, callback_after_update=self.on_update)
31-
self.view_state_bind = binding.new_bind(self.view_state)
32-
33-
def on_update(self, results: Dict[str, Any]) -> None:
34-
self.view_state.errors = []
35-
errors = results.get("errored", [])
36-
for error in errors:
37-
self.view_state.errors.append(f"{error} is invalid")
38-
39-
self.update_view_state()
15+
self.form_data_bind = binding.new_bind(self.model.form)
4016

4117
def update_form_data(self) -> None:
4218
# This will fail if you haven't called connect on the binding!
4319
self.form_data_bind.update_in_view(self.model.form)
44-
45-
def update_view_state(self) -> None:
46-
# This will fail if you haven't called connect on the binding!
47-
self.view_state_bind.update_in_view(self.view_state)
48-
49-
def init_view(self) -> None:
50-
self.view_state.errors = []
51-
52-
self.update_form_data()
53-
self.update_view_state()

0 commit comments

Comments
 (0)