55 lines
1.7 KiB
Rust
55 lines
1.7 KiB
Rust
use std::str::FromStr;
|
|
|
|
use chrono::NaiveDate;
|
|
use yew::prelude::*;
|
|
|
|
use crate::components::textfield::get_value_from_input_event;
|
|
|
|
/// The input type date field in html will always guarantee a valid date string.
|
|
#[function_component(DatePicker)]
|
|
pub fn datepicker(props: &DatePickerProps) -> Html {
|
|
let date_handle = props.value.clone();
|
|
let optional_cb = props.onchange.clone();
|
|
let cb = Callback::from(move |e: InputEvent| {
|
|
match parse_date(get_value_from_input_event(e)) {
|
|
Ok(date) => {
|
|
match optional_cb.clone() {
|
|
Some(callback) => callback.emit(Some(date.clone())),
|
|
None => {}
|
|
};
|
|
date_handle.set(Some(date));
|
|
}
|
|
Err(_) => {}
|
|
};
|
|
});
|
|
let date_handle = props.value.clone();
|
|
html! {
|
|
<div class={"textfield-container"}>
|
|
<div class={if props.required {"textfield-label-required"} else {"textfield-label"}}>{props.label.clone()}</div>
|
|
<input class={"datepicker"} type="date" oninput={cb} value={match (*date_handle).clone() {
|
|
Some(date) => date.to_string(),
|
|
None => NaiveDate::default().to_string()
|
|
}}/>
|
|
</div>
|
|
}
|
|
}
|
|
|
|
#[derive(PartialEq, Clone, Properties)]
|
|
pub struct DatePickerProps {
|
|
pub label: String,
|
|
pub value: UseStateHandle<Option<NaiveDate>>,
|
|
#[prop_or_default]
|
|
pub required: bool,
|
|
pub onchange: Option<Callback<Option<NaiveDate>>>,
|
|
}
|
|
|
|
pub fn parse_date(date_str: String) -> Result<NaiveDate, ()> {
|
|
match NaiveDate::from_str(&date_str) {
|
|
Ok(date) => Ok(date),
|
|
Err(error) => {
|
|
log::error!("Falied to parse Date in DatePicker: {error}");
|
|
Err(())
|
|
}
|
|
}
|
|
}
|