diff --git a/packages/html/src/events/form.rs b/packages/html/src/events/form.rs
index d22a5219f..75cc51978 100644
--- a/packages/html/src/events/form.rs
+++ b/packages/html/src/events/form.rs
@@ -1,5 +1,6 @@
use crate::file_data::FileEngine;
use crate::file_data::HasFileData;
+use std::ops::Deref;
use std::{collections::HashMap, fmt::Debug};
use dioxus_core::Event;
@@ -19,6 +20,37 @@ pub enum FormValue {
VecText(Vec),
}
+impl From for Vec {
+ fn from(value: FormValue) -> Self {
+ match value {
+ FormValue::Text(s) => vec![s],
+ FormValue::VecText(vec) => vec,
+ }
+ }
+}
+
+impl Deref for FormValue {
+ type Target = [String];
+
+ fn deref(&self) -> &Self::Target {
+ self.as_slice()
+ }
+}
+
+impl FormValue {
+ /// Convenient way to represent Value as slice
+ pub fn as_slice(&self) -> &[String] {
+ match self {
+ FormValue::Text(s) => std::slice::from_ref(s),
+ FormValue::VecText(vec) => vec.as_slice(),
+ }
+ }
+ /// Convert into Vec
+ pub fn to_vec(self) -> Vec {
+ self.into()
+ }
+}
+
/* DOMEvent: Send + SyncTarget relatedTarget */
pub struct FormData {
inner: Box,
diff --git a/packages/web/src/event.rs b/packages/web/src/event.rs
index 2e9632eae..e79b55fe8 100644
--- a/packages/web/src/event.rs
+++ b/packages/web/src/event.rs
@@ -389,7 +389,25 @@ impl HasFormData for WebFormData {
}
fn values(&self) -> HashMap {
- let mut values = std::collections::HashMap::new();
+ let mut values = HashMap::new();
+
+ fn insert_value(map: &mut HashMap, key: String, new_value: String) {
+ match map.entry(key) {
+ std::collections::hash_map::Entry::Occupied(mut o) => {
+ let first_value = match o.get_mut() {
+ FormValue::Text(data) => std::mem::take(data),
+ FormValue::VecText(vec) => {
+ vec.push(new_value);
+ return;
+ }
+ };
+ let _ = o.insert(FormValue::VecText(vec![first_value, new_value]));
+ }
+ std::collections::hash_map::Entry::Vacant(v) => {
+ let _ = v.insert(FormValue::Text(new_value));
+ }
+ }
+ }
// try to fill in form values
if let Some(form) = self.element.dyn_ref::() {
@@ -398,20 +416,18 @@ impl HasFormData for WebFormData {
if let Ok(array) = value.dyn_into::() {
if let Some(name) = array.get(0).as_string() {
if let Ok(item_values) = array.get(1).dyn_into::() {
- let item_values: Vec =
- item_values.iter().filter_map(|v| v.as_string()).collect();
-
- values.insert(name, FormValue::VecText(item_values));
+ item_values
+ .iter()
+ .filter_map(|v| v.as_string())
+ .for_each(|v| insert_value(&mut values, name.clone(), v));
} else if let Ok(item_value) = array.get(1).dyn_into::() {
- values.insert(name, FormValue::Text(item_value.as_string().unwrap()));
+ insert_value(&mut values, name, item_value.as_string().unwrap());
}
}
}
}
- }
-
- // try to fill in select element values
- if let Some(select) = self.element.dyn_ref::() {
+ } else if let Some(select) = self.element.dyn_ref::() {
+ // try to fill in select element values
let options = get_select_data(select);
values.insert("options".to_string(), FormValue::VecText(options));
}
@@ -536,19 +552,7 @@ export function get_form_data(form) {
const formData = new FormData(form);
for (let name of formData.keys()) {
- const fieldType = form.elements[name].type;
- console.log(fieldType);
-
- switch (fieldType) {
- case "select-multiple":
- values.set(name, formData.getAll(name));
- break;
-
- // add cases for fieldTypes that can hold multiple values here
- default:
- values.set(name, formData.get(name));
- break;
- }
+ values.set(name, formData.getAll(name));
}
return values;