nova_forms/components/
input.rs1use crate::{Datatype, QueryStringPart, FieldWiring};
2use leptos::*;
3
4#[component]
7pub fn Input<T>(
8 #[prop(into)] label: TextProp,
10 #[prop(into)] bind: QueryStringPart,
12 #[prop(optional, into)] placeholder: Option<T>,
14 #[prop(optional, into)] value: MaybeProp<T>,
16 #[prop(optional, into)] change: Option<Callback<Result<T, T::Error>, ()>>,
18 #[prop(optional, into)] error: MaybeProp<TextProp>,
20) -> impl IntoView
21where
22 T: Datatype,
23{
24 let FieldWiring {
25 qs,
26 raw_value,
27 error,
28 set_raw_value,
29 render_mode,
30 disabled,
31 ..
32 } = FieldWiring::wire(bind, value, change, error, label.clone());
33
34 let node_ref = NodeRef::new();
36 node_ref.on_load(move |element| {
37 let element: &web_sys::HtmlInputElement = &*element;
38 let value = element.value();
39 if !value.is_empty() {
40 set_raw_value.call(value);
41 }
42 });
43
44 let input_elem = T::attributes()
45 .into_iter()
46 .fold(html::input(), |el, (name, value)| el.attr(name, value))
47 .attr("id", qs.to_string())
48 .attr("name", qs.to_string())
49 .attr("placeholder", placeholder.as_ref().map(T::to_string))
50 .prop("value", move || raw_value.get())
51 .prop("disabled", move || disabled.get())
52 .node_ref(node_ref)
53 .on(ev::input, move |ev| {
54 set_raw_value.call(event_target_value(&ev));
55 });
56
57 view! {
58 <div
59 class="field"
60 class:error=move || error.get().is_some()
61 class:ok=move || error.get().is_none()
62 >
63 {move || {
64 if render_mode.get() {
65 view!{
66 <span class="label">{label.clone()}</span>
67 <span class="value">{raw_value.get()}</span>
68 }.into_view()
69 } else {
70 view! {
71 <label for=qs.to_string()>{label.clone()}</label>
72 {input_elem.clone()}
73 {move || {
74 if let Some(error) = error.get() {
75 view! { <span class="error-message">{error}</span> }
76 .into_view()
77 } else {
78 View::default()
79 }
80 }}
81 }.into_view()
82 }
83 }}
84 </div>
85 }
86}