wip: pass form data between web and desktop

This commit is contained in:
Jonathan Kelley committed 2022-01-22 14:53:59 -05:00
1 parent 63b06b7977
commit f66d17ca84
6 files changed
+68 -8

No files matched your search

+23
View File
@@ -0,0 +1,23 @@
//! Example: README.md showcase
//!
//! The example from the README.md.
use dioxus::prelude::*;
fn main() {
dioxus::desktop::launch(app);
}
fn app(cx: Scope) -> Element {
cx.render(rsx! {
div {
h1 { "Form" }
form {
oninput: move |ev| println!("{:?}", ev),
input { r#type: "text", name: "username" }
input { r#type: "text", name: "full-name" }
input { r#type: "password", name: "password" }
}
}
})
}
+3
View File
@@ -3,6 +3,8 @@ use dioxus_core::exports::bumpalo;
use dioxus_core::*; use dioxus_core::*;
pub mod on { pub mod on {
use std::collections::HashMap;
use super::*; use super::*;
macro_rules! event_directory { macro_rules! event_directory {
( $( ( $(
@@ -484,6 +486,7 @@ pub mod on {
#[derive(Debug)] #[derive(Debug)]
pub struct FormData { pub struct FormData {
pub value: String, pub value: String,
pub values: HashMap<String, String>,
/* DOMEvent: Send + SyncTarget relatedTarget */ /* DOMEvent: Send + SyncTarget relatedTarget */
} }
+18
View File
@@ -231,6 +231,23 @@ export class Interpreter {
} }
} }
} }
if (target.tagName == "FORM") {
let formTarget = target;
for (let x = 0; x < formTarget.elements.length; x++) {
let element = formTarget.elements[x];
let name = element.getAttribute("name");
if (name != null) {
if (element.getAttribute("type") == "checkbox") {
// @ts-ignore
contents.values[name] = element.checked ? "true" : "false";
}
else {
// @ts-ignore
contents.values[name] = element.value ?? element.textContent;
}
}
}
}
if (realId == null) { if (realId == null) {
return; return;
} }
@@ -316,6 +333,7 @@ function serialize_event(event) {
} }
return { return {
value: value, value: value,
values: {}
}; };
} }
case "click": case "click":
+20 -4
View File
@@ -244,7 +244,6 @@ export class Interpreter {
break; break;
case "NewEventListener": case "NewEventListener":
// this handler is only provided on desktop implementations since this // this handler is only provided on desktop implementations since this
// method is not used by the web implementation // method is not used by the web implementation
let handler = (event: Event) => { let handler = (event: Event) => {
@@ -286,6 +285,23 @@ export class Interpreter {
} }
} }
if (target.tagName == "FORM") {
let formTarget = target as HTMLFormElement;
for (let x = 0; x < formTarget.elements.length; x++) {
let element = formTarget.elements[x];
let name = element.getAttribute("name");
if (name != null) {
if (element.getAttribute("type") == "checkbox") {
// @ts-ignore
contents.values[name] = element.checked ? "true" : "false";
} else {
// @ts-ignore
contents.values[name] = element.value ?? element.textContent;
}
}
}
}
if (realId == null) { if (realId == null) {
return; return;
} }
@@ -385,6 +401,8 @@ function serialize_event(event: Event) {
case "invalid": case "invalid":
case "reset": case "reset":
case "submit": { case "submit": {
let target = event.target as HTMLFormElement; let target = event.target as HTMLFormElement;
let value = target.value ?? target.textContent; let value = target.value ?? target.textContent;
@@ -394,6 +412,7 @@ function serialize_event(event: Event) {
return { return {
value: value, value: value,
values: {}
}; };
} }
@@ -643,8 +662,6 @@ const bool_attrs = {
truespeed: true, truespeed: true,
}; };
type PushRoot = { type: "PushRoot", root: number }; type PushRoot = { type: "PushRoot", root: number };
type AppendChildren = { type: "AppendChildren", many: number }; type AppendChildren = { type: "AppendChildren", many: number };
type ReplaceWith = { type: "ReplaceWith", root: number, m: number }; type ReplaceWith = { type: "ReplaceWith", root: number, m: number };
@@ -661,7 +678,6 @@ type SetText = { type: "SetText", root: number, text: string };
type SetAttribute = { type: "SetAttribute", root: number, field: string, value: string, ns: string | undefined }; type SetAttribute = { type: "SetAttribute", root: number, field: string, value: string, ns: string | undefined };
type RemoveAttribute = { type: "RemoveAttribute", root: number, name: string }; type RemoveAttribute = { type: "RemoveAttribute", root: number, name: string };
type DomEdit = type DomEdit =
PushRoot | PushRoot |
AppendChildren | AppendChildren |
+1
View File
@@ -41,6 +41,7 @@ features = [
"HtmlInputElement", "HtmlInputElement",
"HtmlSelectElement", "HtmlSelectElement",
"HtmlTextAreaElement", "HtmlTextAreaElement",
"HtmlFormElement",
"EventTarget", "EventTarget",
"HtmlCollection", "HtmlCollection",
"Node", "Node",
+3 -4
View File
@@ -178,7 +178,8 @@ fn virtual_event_from_websys_event(event: web_sys::Event) -> Arc<dyn Any + Send
}) })
.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");
Arc::new(FormData { value }) let values = std::collections::HashMap::new();
Arc::new(FormData { value, values })
} }
"click" | "contextmenu" | "doubleclick" | "drag" | "dragend" | "dragenter" | "dragexit" "click" | "contextmenu" | "doubleclick" | "drag" | "dragend" | "dragenter" | "dragexit"
| "dragleave" | "dragover" | "dragstart" | "drop" | "mousedown" | "mouseenter" | "dragleave" | "dragover" | "dragstart" | "drop" | "mousedown" | "mouseenter"
@@ -296,9 +297,7 @@ fn decode_trigger(event: &web_sys::Event) -> anyhow::Result<UserEvent> {
priority: dioxus_core::EventPriority::Medium, priority: dioxus_core::EventPriority::Medium,
}); });
} }
Some(Err(e)) => { Some(Err(e)) => return Err(e.into()),
return Err(e.into());
}
None => { None => {
// walk the tree upwards until we actually find an event target // walk the tree upwards until we actually find an event target
if let Some(parent) = target.parent_element() { if let Some(parent) = target.parent_element() {