use crate::common::ValueType; use leptos::ev::{Event, Targeted}; use leptos::prelude::*; use leptos::web_sys::HtmlSelectElement; use std::collections::HashMap; use crate::components::{use_validation_context, InputState, ValidationState}; fn validate(required: bool, value: String) -> ValidationState { if required && (value.is_empty()) { ValidationState::Invalid("This input is required.".to_string()) } else { ValidationState::Valid } } /// A custom-styled select input. /// /// Takes a `Vec` as the set of inputs. Only one value may be selected, which is indicated /// by the `value` prop of the component. #[component] pub fn Select( #[prop(into)] value_list: Signal>, #[prop(into)] data_member: Signal, #[prop()] data_map: RwSignal>, #[prop(optional, into)] label: String, #[prop(optional, into)] disabled: Signal, #[prop(optional, into)] required: Signal ) -> impl IntoView { //#region Value Logic let value = Memo::new(move |_| { data_map.with(|map| { map.get(&data_member.get_untracked()) .and_then(|v| v.as_string().ok().flatten()) .unwrap_or_default() }) }); //#endregion //#region Validation Logic let error = Memo::new(move |_| validate(required.get(), value.get())); let dirty = RwSignal::new(false); let show_errors = Signal::derive(move || dirty.get() && matches!(error.get(), ValidationState::Invalid(_))); let input_state = RwSignal::new(InputState::new(data_member.get(), error.clone(), dirty.clone())); let validation_context = use_validation_context() .expect("Could not find FormValidationRegistry context"); validation_context.validators.update(|list| list.push(input_state)); on_cleanup(move || { validation_context.validators.update(|list| { list.retain(|v| *v.get_untracked().input_name != *input_state.get_untracked().input_name) }); }); //#endregion //#region Event Logic let on_change = move |e: Targeted| { let value = e.target().value(); dirty.set(true); data_map.update(|map| { map.insert(data_member.get(), ValueType::String(Some(value))); }); }; //#endregion view! {
{move || { match error.get() { ValidationState::Invalid(msg) => msg, _ => "There is no error - should not see this message.".to_string(), } }}
} }