rooting_forms/
impl_option.rs1use std::marker::PhantomData;
2use rooting::{
3 El,
4 el,
5};
6use wasm_bindgen::JsCast;
7use web_sys::HtmlInputElement;
8use crate::{
9 css::{
10 ATTR_LABEL,
11 CSS_CLASS_HIDDEN,
12 CSS_CLASS_OPTION_ENABLE,
13 },
14 FormElements,
15 FormState,
16 FormWith,
17};
18
19struct OptionFormState<C, T> {
20 checked_el: El,
21 subform: Box<dyn FormState<T>>,
22 _pd: PhantomData<C>,
23}
24
25impl<C, T: FormWith<C>> FormState<Option<T>> for OptionFormState<C, T> {
26 fn parse(&self) -> Result<Option<T>, ()> {
27 let checked = self.checked_el.raw().dyn_ref::<HtmlInputElement>().unwrap().checked();
28 if checked {
29 return Ok(Some(self.subform.parse()?));
30 } else {
31 return Ok(None);
32 }
33 }
34}
35
36impl<C: 'static, T: FormWith<C> + 'static> FormWith<C> for Option<T> {
37 fn new_form_with_(
38 context: &C,
39 field: &str,
40 from: Option<&Self>,
41 depth: usize,
42 ) -> (FormElements, Box<dyn FormState<Self>>) {
43 let (subform_elements, subform) = T::new_form_with_(context, field, from.and_then(|x| x.as_ref()), depth);
44 let mut additional = vec![];
45 additional.extend(subform_elements.error.iter().cloned());
46 additional.extend(subform_elements.elements);
47 let check = el("input")
48 .classes(&[CSS_CLASS_OPTION_ENABLE])
50 .attr(ATTR_LABEL, &format!("{} - Enabled", field))
51 .attr("type", "checkbox")
52 .on("click", {
53 let additional = additional.clone();
54 move |ev| {
55 let checked = ev.target().unwrap().dyn_ref::<HtmlInputElement>().unwrap().checked();
56 for e in &additional {
57 e.ref_modify_classes(&[(CSS_CLASS_HIDDEN, checked)]);
58 }
59 }
60 });
61 if from.map(|x| x.is_some()).unwrap_or(false) {
62 check.ref_attr("checked", "checked");
63 } else {
64 for e in &additional {
65 e.ref_modify_classes(&[(CSS_CLASS_HIDDEN, true)]);
66 }
67 }
68 let mut elements = vec![check.clone()];
69 elements.extend(additional);
70 return (FormElements {
71 error: None,
72 elements: elements,
73 }, Box::new(OptionFormState {
74 checked_el: check,
75 subform: subform,
76 _pd: Default::default(),
77 }));
78 }
79}