macro_rules! set_on {
($event:ident, $self:expr, $($element:ident),*) => { ... };
}Expand description
UI macro: set event callback for UI elements.
Given an event (for instance change or click) and assuming that there
are methods called element_onevent for each element, this macro sets the
event callbacks of each of the elements to the closures returned by these
methods.
ยงExample
use maia_wasm::{onchange_apply_noprefs, set_on, ui_elements,
ui::input::{InputElement, TextInput}};
use std::rc::Rc;
use wasm_bindgen::{closure::Closure, JsCast, JsValue};
use web_sys::{Document, HtmlButtonElement, HtmlInputElement, Window};
#[derive(Clone)]
struct Ui {
window: Rc<Window>,
elements: Elements,
}
ui_elements! {
my_text_field_a: HtmlInputElement => TextInput,
my_text_field_b: HtmlInputElement => TextInput,
my_button_a: HtmlButtonElement => Rc<HtmlButtonElement>,
my_button_b: HtmlButtonElement => Rc<HtmlButtonElement>,
}
impl Ui {
fn new(window: Rc<Window>, document: &Document) -> Result<Ui, JsValue> {
let elements = Elements::new(document)?;
let ui = Ui { window, elements };
ui.set_callbacks();
Ok(ui)
}
fn set_callbacks(&self) -> Result<(), JsValue> {
set_on!(change, self, my_text_field_a, my_text_field_b);
set_on!(click, self, my_button_a, my_button_b);
Ok(())
}
fn my_text_field_a_onchange(&self) -> Closure<dyn Fn()> {
let element = self.elements.my_text_field_a.clone();
let window = self.window.clone();
Closure::new(move || {
if let Some(text) = element.get() {
window.alert_with_message(&format!("my_text_field_a changed: value = {text}"));
}
})
}
fn my_text_field_b_onchange(&self) -> Closure<dyn Fn()> {
let element = self.elements.my_text_field_b.clone();
let window = self.window.clone();
Closure::new(move || {
if let Some(text) = element.get() {
window.alert_with_message(&format!("my_text_field_b changed: value = {text}"));
}
})
}
fn my_button_a_onclick(&self) -> Closure<dyn Fn()> {
let window = self.window.clone();
Closure::new(move || {
window.alert_with_message("my_button_a has been clicked");
})
}
fn my_button_b_onclick(&self) -> Closure<dyn Fn()> {
let window = self.window.clone();
Closure::new(move || {
window.alert_with_message("my_button_b has been clicked");
})
}
}