wip: pass form data between web and desktop
This commit is contained in:
1 parent
63b06b7977
commit
f66d17ca84
6 files changed
+68
-8
No files matched your search
@@ -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,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 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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":
|
||||||
|
|||||||
@@ -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 |
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ features = [
|
|||||||
"HtmlInputElement",
|
"HtmlInputElement",
|
||||||
"HtmlSelectElement",
|
"HtmlSelectElement",
|
||||||
"HtmlTextAreaElement",
|
"HtmlTextAreaElement",
|
||||||
|
"HtmlFormElement",
|
||||||
"EventTarget",
|
"EventTarget",
|
||||||
"HtmlCollection",
|
"HtmlCollection",
|
||||||
"Node",
|
"Node",
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|||||||
Reference in new issue
Block a user