Made number text field generic

This commit is contained in:
Franklin 2023-04-25 19:48:03 -04:00
parent 145c062734
commit 65395552e0
2 changed files with 29 additions and 16 deletions

View File

@ -2,32 +2,31 @@
use wasm_bindgen::{JsCast, UnwrapThrowExt};
use web_sys::{HtmlInputElement};
use yew::prelude::*;
use std::{str::FromStr, num::ParseFloatError};
use std::{str::FromStr, fmt::{Display}};
#[derive(Properties, PartialEq, Clone)]
pub struct NumberTextFieldProps {
pub struct NumberTextFieldProps<T: PartialEq + Clone + Display + Default + FromStr> {
pub label: String,
pub value: UseStateHandle<f64>,
pub value: UseStateHandle<T>,
#[prop_or_default]
pub required: bool,
pub onchange: Option<Callback<f64>>,
pub onchange: Option<Callback<T>>,
}
#[function_component(NumberTextField)]
pub fn number_textfield(props: &NumberTextFieldProps) -> Html {
pub fn number_textfield<T: PartialEq + Clone + Display + Default + FromStr + 'static>(props: &NumberTextFieldProps<T>) -> Html {
let on_input_changed = {
let handle = props.value.clone();
let onchange = props.onchange.clone();
Callback::from(move |e: InputEvent| {
let value = match get_number_value_from_input_event(e) {
let value = match get_number_value_from_input_event::<T>(e) {
Ok(float) => float,
Err(error) => {
log::error!("Error ocurred attempting to parse float on input type number. This only happens in firefox browsers. {error}");
0.0
Err(_) => {
log::error!("Error ocurred attempting to parse number on input type number. This only happens in firefox browsers.");
T::default()
}};
match onchange.clone() {
Some(onchange) => onchange.emit(value),
Some(onchange) => onchange.emit(value.clone()),
None => {}
};
handle.set(value);
@ -41,9 +40,12 @@ pub fn number_textfield(props: &NumberTextFieldProps) -> Html {
}
}
pub fn get_number_value_from_input_event(e: InputEvent) -> Result<f64, ParseFloatError> {
pub fn get_number_value_from_input_event<T: FromStr>(e: InputEvent) -> Result<T, ()> {
let event: Event = e.dyn_into().unwrap_throw();
let event_target = event.target().unwrap_throw();
let target: HtmlInputElement = event_target.dyn_into().unwrap_throw();
f64::from_str(&target.value())
match T::from_str(&target.value()) {
Ok(t) => Ok(t),
Err(_) => Err(()),
}
}

View File

@ -1,4 +1,4 @@
use jl_types::domain::unit::Unit;
use jl_types::domain::{unit::Unit, unit_type::UnitType};
use uuid::Uuid;
use yew::prelude::*;
use yew_router::prelude::use_navigator;
@ -19,7 +19,18 @@ pub fn unit_fields(props: &UnitFieldsProps) -> Html {
// Fields
let price_usd = use_state(|| 0.0);
let unit_type_handle: UseStateHandle<Option<UnitType>> = use_state(|| None);
let rooms_handle: UseStateHandle<i16> = use_state(|| 0);
let bathrooms_handle: UseStateHandle<i16> = use_state(|| 0);
let area_handle: UseStateHandle<f32> = use_state(|| 0.0);
let a = 0.0;
let b = a as i32;
html! {
<NumberTextField label={String::from("Precio en USD")} required={true} value={price_usd.clone()}/>
<>
<NumberTextField<f64> label={String::from("Precio en USD")} required={true} value={price_usd.clone()}/>
<NumberTextField<f32> label={String::from("Area en m^2")} required={true} value={area_handle.clone()}/>
<NumberTextField<i16> label={String::from("Cant. de habitaciones")} required={true} value={rooms_handle.clone()}/>
<NumberTextField<i16> label={String::from("Cant. de baños")} required={true} value={bathrooms_handle.clone()}/>
</>
}
}
}