Skip to content

Instantly share code, notes, and snippets.

@rebo
Created July 26, 2020 20:29
Show Gist options
  • Save rebo/e45458c1cf1bdf4bb9cba510e04b2a0f to your computer and use it in GitHub Desktop.
Save rebo/e45458c1cf1bdf4bb9cba510e04b2a0f to your computer and use it in GitHub Desktop.
#[derive(Debug, Default, Validate,Clone)]
struct Form {
#[validate(length(min = 1))]
name: String,
#[validate(length(min = 1))]
color: String,
#[validate(range(min = 18, max = 45))]
age: i32
}
#[atom]
fn form(id:Local) -> Atom<Form> {
Form {
name: "".to_string(),
color: "".to_string(),
age: 0,
}
}
#[reaction]
fn form_ui<Ms:'static>(id : Local) -> Reaction<Node<Ms>>{
let data = form(id).observe();
div![
name_ui( &data.name, move |inp| form(id).update(|f| f.name = inp)),
color_ui(id, crate::Impure(move |inp| form(id).update(|f| f.color = inp))).observe(),
]
}
// doesnt need to be a reaction as contains no observed state
// receives the value of the input field, and a generic setter responsible for setting state
// completely agnostic of the data type so is reusbale elsewhere in the application
fn name_ui<Ms:'static, F: FnOnce(String)->() +Clone +'static>(value: &String , setter: F ) -> Node<Ms> {
div![
label!["Name:"],
input![
s().b_color("gray").b_style_solid().b_width(px(2)),
attrs!{At::Value => value},
input_ev(Ev::Input, move |inp| setter(inp))
]
]
}
// observes its internal color picker so needs to be a reaction
// receives a generic setter responsible for setting state
// completely agnostic of the data type so is reusbale elsewhere in the application
#[reaction]
fn color_ui<Ms:'static, F: FnOnce(String)->() +Clone +'static>(id: Local , setter: crate::Impure<F> ) -> Reaction<Node<Ms>>{
div![
label!["Color:"],
crate::observable_color_picker(
input_ev(Ev::Input, move |inp| setter.0(inp))
).observe()
]
}
#[reaction]
fn validate_form(id: Local) -> Reaction<Result<(), ValidationErrors>> {
form(id).observe().validate()
}
// Actual View
#[topo::nested]
pub fn view() -> Node<Msg> {
let form_id = Local::new();
let form_data = form(form_id).get();
div![
h1![s().font_weight_v900(), "Form Data"],
p![format!("name: {}", form_data.name)],
p![format!("color: {}", form_data.color)],
h1![s().font_weight_v900(), "Form"],
form_ui(form_id).get(),
h1![s().font_weight_v900(), "Errors"],
pre![format!("{:#?}", validate_form(form_id).get()),]
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment