Macro set_on

Source
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");
       })
   }
}