mirror of
https://github.com/DioxusLabs/dioxus
synced 2024-11-26 14:10:20 +00:00
feat: form works in web
This commit is contained in:
parent
add21d5f9d
commit
d758dc6065
2 changed files with 31 additions and 25 deletions
|
@ -1,6 +1,7 @@
|
||||||
//! Example: README.md showcase
|
//! Forms
|
||||||
//!
|
//!
|
||||||
//! The example from the README.md.
|
//! Dioxus forms deviate slightly from html, automatically returning all named inputs
|
||||||
|
//! in the "values" field
|
||||||
|
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
|
@ -13,7 +14,7 @@ fn app(cx: Scope) -> Element {
|
||||||
div {
|
div {
|
||||||
h1 { "Form" }
|
h1 { "Form" }
|
||||||
form {
|
form {
|
||||||
oninput: move |ev| println!("{:?}", ev),
|
oninput: move |ev| println!("{:?}", ev.values),
|
||||||
input { r#type: "text", name: "username" }
|
input { r#type: "text", name: "username" }
|
||||||
input { r#type: "text", name: "full-name" }
|
input { r#type: "text", name: "full-name" }
|
||||||
input { r#type: "password", name: "password" }
|
input { r#type: "password", name: "password" }
|
||||||
|
|
|
@ -41,7 +41,7 @@ impl WebsysDom {
|
||||||
Some(Ok(id)) => {
|
Some(Ok(id)) => {
|
||||||
break Ok(UserEvent {
|
break Ok(UserEvent {
|
||||||
name: event_name_from_typ(&typ),
|
name: event_name_from_typ(&typ),
|
||||||
data: virtual_event_from_websys_event(event.clone()),
|
data: virtual_event_from_websys_event(event.clone(), target.clone()),
|
||||||
element: Some(ElementId(id)),
|
element: Some(ElementId(id)),
|
||||||
scope_id: None,
|
scope_id: None,
|
||||||
priority: dioxus_core::EventPriority::Medium,
|
priority: dioxus_core::EventPriority::Medium,
|
||||||
|
@ -57,7 +57,10 @@ impl WebsysDom {
|
||||||
} else {
|
} else {
|
||||||
break Ok(UserEvent {
|
break Ok(UserEvent {
|
||||||
name: event_name_from_typ(&typ),
|
name: event_name_from_typ(&typ),
|
||||||
data: virtual_event_from_websys_event(event.clone()),
|
data: virtual_event_from_websys_event(
|
||||||
|
event.clone(),
|
||||||
|
target.clone(),
|
||||||
|
),
|
||||||
element: None,
|
element: None,
|
||||||
scope_id: None,
|
scope_id: None,
|
||||||
priority: dioxus_core::EventPriority::Low,
|
priority: dioxus_core::EventPriority::Low,
|
||||||
|
@ -144,7 +147,10 @@ unsafe impl Sync for DioxusWebsysEvent {}
|
||||||
|
|
||||||
// todo: some of these events are being casted to the wrong event type.
|
// todo: some of these events are being casted to the wrong event type.
|
||||||
// We need tests that simulate clicks/etc and make sure every event type works.
|
// We need tests that simulate clicks/etc and make sure every event type works.
|
||||||
fn virtual_event_from_websys_event(event: web_sys::Event) -> Arc<dyn Any + Send + Sync> {
|
fn virtual_event_from_websys_event(
|
||||||
|
event: web_sys::Event,
|
||||||
|
target: Element,
|
||||||
|
) -> Arc<dyn Any + Send + Sync> {
|
||||||
use dioxus_html::on::*;
|
use dioxus_html::on::*;
|
||||||
use dioxus_html::KeyCode;
|
use dioxus_html::KeyCode;
|
||||||
|
|
||||||
|
@ -177,9 +183,6 @@ fn virtual_event_from_websys_event(event: web_sys::Event) -> Arc<dyn Any + Send
|
||||||
// todo: these handlers might get really slow if the input box gets large and allocation pressure is heavy
|
// todo: these handlers might get really slow if the input box gets large and allocation pressure is heavy
|
||||||
// don't have a good solution with the serialized event problem
|
// don't have a good solution with the serialized event problem
|
||||||
"change" | "input" | "invalid" | "reset" | "submit" => {
|
"change" | "input" | "invalid" | "reset" | "submit" => {
|
||||||
let evt: &web_sys::Event = event.dyn_ref().unwrap();
|
|
||||||
|
|
||||||
let target: web_sys::EventTarget = evt.target().unwrap();
|
|
||||||
let value: String = (&target)
|
let value: String = (&target)
|
||||||
.dyn_ref()
|
.dyn_ref()
|
||||||
.map(|input: &web_sys::HtmlInputElement| {
|
.map(|input: &web_sys::HtmlInputElement| {
|
||||||
|
@ -217,28 +220,29 @@ fn virtual_event_from_websys_event(event: web_sys::Event) -> Arc<dyn Any + Send
|
||||||
|
|
||||||
let mut values = std::collections::HashMap::new();
|
let mut values = std::collections::HashMap::new();
|
||||||
|
|
||||||
|
// try to fill in form values
|
||||||
if let Some(form) = target.dyn_ref::<web_sys::HtmlFormElement>() {
|
if let Some(form) = target.dyn_ref::<web_sys::HtmlFormElement>() {
|
||||||
let elements = form.elements();
|
let elements = form.elements();
|
||||||
for x in 0..elements.length() {
|
for x in 0..elements.length() {
|
||||||
let element = elements.item(x).unwrap();
|
let element = elements.item(x).unwrap();
|
||||||
if let Some(name) = element.get_attribute("name") {
|
if let Some(name) = element.get_attribute("name") {
|
||||||
let value: String = (&element)
|
let value: String = (&element)
|
||||||
.dyn_ref()
|
.dyn_ref()
|
||||||
.map(|input: &web_sys::HtmlInputElement| {
|
.map(|input: &web_sys::HtmlInputElement| {
|
||||||
match input.type_().as_str() {
|
match input.type_().as_str() {
|
||||||
"checkbox" => {
|
"checkbox" => {
|
||||||
match input.checked() {
|
match input.checked() {
|
||||||
true => "true".to_string(),
|
true => "true".to_string(),
|
||||||
false => "false".to_string(),
|
false => "false".to_string(),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => input.value()
|
_ => input.value()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.or_else(|| target.dyn_ref().map(|input: &web_sys::HtmlTextAreaElement| input.value()))
|
.or_else(|| target.dyn_ref().map(|input: &web_sys::HtmlTextAreaElement| input.value()))
|
||||||
.or_else(|| target.dyn_ref().map(|input: &web_sys::HtmlSelectElement| input.value()))
|
.or_else(|| target.dyn_ref().map(|input: &web_sys::HtmlSelectElement| input.value()))
|
||||||
.or_else(|| target.dyn_ref::<web_sys::HtmlElement>().unwrap().text_content())
|
.or_else(|| target.dyn_ref::<web_sys::HtmlElement>().unwrap().text_content())
|
||||||
.expect("only an InputElement or TextAreaElement or an element with contenteditable=true can have an oninput event listener");
|
.expect("only an InputElement or TextAreaElement or an element with contenteditable=true can have an oninput event listener");
|
||||||
|
|
||||||
values.insert(name, value);
|
values.insert(name, value);
|
||||||
}
|
}
|
||||||
|
@ -337,6 +341,7 @@ fn virtual_event_from_websys_event(event: web_sys::Event) -> Arc<dyn Any + Send
|
||||||
| "playing" | "progress" | "ratechange" | "seeked" | "seeking" | "stalled" | "suspend"
|
| "playing" | "progress" | "ratechange" | "seeked" | "seeking" | "stalled" | "suspend"
|
||||||
| "timeupdate" | "volumechange" | "waiting" => Arc::new(MediaData {}),
|
| "timeupdate" | "volumechange" | "waiting" => Arc::new(MediaData {}),
|
||||||
"toggle" => Arc::new(ToggleData {}),
|
"toggle" => Arc::new(ToggleData {}),
|
||||||
|
|
||||||
_ => Arc::new(()),
|
_ => Arc::new(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue