jl-frontend/src/components/datepicker.rs

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(())
}
}
}