nova_forms/components/
checkbox.rs

1use crate::{Datatype, QueryString, FieldWiring};
2use leptos::*;
3
4/// A component that renders a checkbox.
5#[component]
6pub fn Checkbox<T>(
7    /// The label of the input field.
8    #[prop(into)] label: TextProp,
9    /// The query string that binds the input field to the form data.
10    #[prop(into)] bind: QueryString,
11    /// The initial value of the input field.
12    #[prop(optional, into)] value: MaybeProp<T>,
13    /// A write signal that is updated with the parsed value of the input field.
14    #[prop(optional, into)] change: Option<Callback<Result<T, T::Err>, ()>>,
15    /// Set a custom error message for the input field.
16    #[prop(optional, into)] error: MaybeProp<TextProp>,
17) -> impl IntoView
18where
19    T: Datatype<Inner = bool>
20{    
21    let FieldWiring {
22        qs,
23        raw_value,
24        value,
25        error,
26        set_raw_value,
27        render_mode,
28        ..
29    } = FieldWiring::<T>::wire(bind, value, change, error);
30
31    // Get value on load from the input field.
32    let node_ref = NodeRef::new();
33    node_ref.on_load(move |element| {
34        let element: &web_sys::HtmlInputElement = &*element;
35        let value = element.checked();
36        set_raw_value.call(value.to_string());
37    });
38
39    let input_elem = html::input()
40        .attr("type", "checkbox")
41        .attr("id", qs.to_string())
42        .attr("name", qs.to_string())
43        .attr("checked", move || raw_value.get())
44        .attr("value", true.to_string())
45        .node_ref(node_ref)
46        .on(ev::input, move |ev| {
47            set_raw_value.call(event_target_checked(&ev).to_string());
48        });
49
50
51    view! {
52        <div
53            class="field checkbox"
54            class:error=move || error.get().is_some()
55            class:ok=move || error.get().is_none()
56        >
57        {move || {
58            if render_mode.get() {
59                // TODO
60                view! {
61                    <label for=qs.to_string()>
62                        {input_elem.clone()}
63                        <span class="custom-checkbox"></span>
64                        <span class="custom-checkbox-label">{label.clone()}</span>
65                    </label>
66                    {move || {
67                        if let Some(error) = error.get() {
68                            view! { <span class="error-message">{error}</span> }
69                                .into_view()
70                        } else {
71                            View::default()
72                        }
73                    }}
74                }.into_view()
75            } else {
76                view! {
77                    <label for=qs.to_string()>
78                        {input_elem.clone()}
79                        <span class="custom-checkbox"></span>
80                        <span class="custom-checkbox-label">{label.clone()}</span>
81                    </label>
82                    {move || {
83                        if let Some(error) = error.get() {
84                            view! { <span class="error-message">{error}</span> }
85                                .into_view()
86                        } else {
87                            View::default()
88                        }
89                    }}
90                }.into_view()
91            }
92        }}
93           
94        </div>
95    }
96}