diff --git a/packages/html/src/events/form.rs b/packages/html/src/events/form.rs index 1303dc209..2e2fc5934 100644 --- a/packages/html/src/events/form.rs +++ b/packages/html/src/events/form.rs @@ -20,6 +20,8 @@ pub struct FormData { pub values: HashMap>, + pub value_types: HashMap, + #[cfg_attr( feature = "serialize", serde( @@ -53,6 +55,17 @@ impl FormData { let mut parsed_values: HashMap = HashMap::new(); for (fieldname, values) in raw_values.into_iter() { + // check if the fieldname can hold multiple values based on its types + let field_type = self + .value_types + .get(&fieldname) + .expect("Provided invalid field"); + + let is_multi_valued_input = match field_type.as_str() { + "select" | "checkbox" => true, + _ => false, + }; + /* case 1 - multiple values, example { driving_types: ["manual", "automatic"] } In this case we want to return the values as it is, NO point in making @@ -64,7 +77,7 @@ impl FormData { */ parsed_values.insert( fieldname, - if values.len() > 1 { + if is_multi_valued_input { // handling multiple values - case 1 ValueType::VecText(values) } else { diff --git a/packages/rink/src/hooks.rs b/packages/rink/src/hooks.rs index f8c4500d2..47efc9e7e 100644 --- a/packages/rink/src/hooks.rs +++ b/packages/rink/src/hooks.rs @@ -63,6 +63,8 @@ pub struct FormData { pub values: HashMap>, + pub value_types: HashMap, + pub files: Option, } @@ -71,6 +73,7 @@ impl FormData { dioxus_html::FormData { value: self.value, values: self.values, + value_types: self.value_types, files: None, } } diff --git a/packages/rink/src/widgets/button.rs b/packages/rink/src/widgets/button.rs index 523b2392a..41be40da5 100644 --- a/packages/rink/src/widgets/button.rs +++ b/packages/rink/src/widgets/button.rs @@ -93,6 +93,7 @@ impl Button { let data = FormData { value: self.value.to_string(), values: HashMap::new(), + value_types: HashMap::new(), files: None, }; ctx.send(crate::Event { diff --git a/packages/rink/src/widgets/checkbox.rs b/packages/rink/src/widgets/checkbox.rs index fab809ed2..ea5a0ba53 100644 --- a/packages/rink/src/widgets/checkbox.rs +++ b/packages/rink/src/widgets/checkbox.rs @@ -129,6 +129,7 @@ impl CheckBox { .then(|| self.value.to_string()) .unwrap_or_default(), values: HashMap::new(), + value_types: HashMap::new(), files: None, }; { diff --git a/packages/rink/src/widgets/slider.rs b/packages/rink/src/widgets/slider.rs index 7080b6c12..dd1b50a7b 100644 --- a/packages/rink/src/widgets/slider.rs +++ b/packages/rink/src/widgets/slider.rs @@ -198,6 +198,7 @@ impl Slider { let data = FormData { value: self.value.to_string(), values: HashMap::new(), + value_types: HashMap::new(), files: None, }; ctx.send(Event { diff --git a/packages/rink/src/widgets/text_like.rs b/packages/rink/src/widgets/text_like.rs index 6521073d0..c9dacb74e 100644 --- a/packages/rink/src/widgets/text_like.rs +++ b/packages/rink/src/widgets/text_like.rs @@ -171,6 +171,7 @@ impl TextLike { let data: FormData = FormData { value: self.text.clone(), values: HashMap::new(), + value_types: HashMap::new(), files: None, }; let ctx: UniqueView = world.borrow().expect("expected widget context"); diff --git a/packages/web/src/dom.rs b/packages/web/src/dom.rs index f45d6558a..556d9ab9a 100644 --- a/packages/web/src/dom.rs +++ b/packages/web/src/dom.rs @@ -15,7 +15,7 @@ use dioxus_interpreter_js::{get_node, minimal_bindings, save_template, Channel}; use futures_channel::mpsc; use js_sys::Array; use rustc_hash::FxHashMap; -use std::{any::Any, rc::Rc}; +use std::{any::Any, collections::HashMap, rc::Rc}; use wasm_bindgen::{closure::Closure, prelude::wasm_bindgen, JsCast, JsValue}; use web_sys::{Document, Element, Event}; @@ -365,6 +365,21 @@ fn read_input_to_data(target: Element) -> Rc { }) .expect("only an InputElement or TextAreaElement or an element with contenteditable=true can have an oninput event listener"); + let mut value_types = HashMap::new(); + + // to get the input_type for the corresponding input + for input_el in target.dyn_ref::().into_iter() { + for index in 0..input_el.length() { + if let Some(element) = input_el.get_with_index(index as u32) { + if let Some(input) = element.dyn_into::().ok() { + let name = input.name(); + let input_type = input.type_(); + value_types.insert(name, input_type); + } + } + } + } + let mut values = std::collections::HashMap::new(); // try to fill in form values @@ -400,6 +415,7 @@ fn read_input_to_data(target: Element) -> Rc { Rc::new(FormData { value, values, + value_types, files, }) }