Skip to content

Commit 241b10b

Browse files
committed
use fetch request to upload form data
1 parent 1e3fac1 commit 241b10b

File tree

1 file changed

+51
-7
lines changed

1 file changed

+51
-7
lines changed

src/client/packages/idom-client-react/src/components.js

+51-7
Original file line numberDiff line numberDiff line change
@@ -29,22 +29,31 @@ export function Layout({ saveUpdateHook, sendEvent, loadImportSource }) {
2929
`;
3030
}
3131

32+
const ELEMENT_WRAPPER_COMPONENTS = {
33+
form: FormElement,
34+
input: UserInputElement,
35+
script: ScriptElement,
36+
select: UserInputElement,
37+
textarea: UserInputElement,
38+
};
39+
3240
export function Element({ model }) {
3341
if (model.error !== undefined) {
3442
if (model.error) {
3543
return html`<pre>${model.error}</pre>`;
3644
} else {
3745
return null;
3846
}
39-
} else if (model.tagName == "script") {
40-
return html`<${ScriptElement} model=${model} />`;
41-
} else if (["input", "select", "textarea"].includes(model.tagName)) {
42-
return html`<${UserInputElement} model=${model} />`;
43-
} else if (model.importSource) {
44-
return html`<${ImportedElement} model=${model} />`;
47+
}
48+
49+
let Component;
50+
if (model.importSource) {
51+
Component = ImportedElement;
4552
} else {
46-
return html`<${StandardElement} model=${model} />`;
53+
Component = ELEMENT_WRAPPER_COMPONENTS[model.tagName] || StandardElement;
4754
}
55+
56+
return html`<${Component} model=${model} />`;
4857
}
4958

5059
function StandardElement({ model }) {
@@ -155,6 +164,41 @@ function ScriptElement({ model }) {
155164
return html`<div ref=${ref} />`;
156165
}
157166

167+
function FormElement({ model }) {
168+
const layoutContext = React.useContext(LayoutContext);
169+
const props = createElementAttributes(model, layoutContext.sendEvent);
170+
171+
if (props.target && props.target !== "_self") {
172+
return html`<${StandardElement} model=${model} />`;
173+
}
174+
175+
const oldOnSubmit = props.onSubmit || (() => {});
176+
async function onSubmit(event) {
177+
event.preventDefault();
178+
if (!model?.eventHandlers?.onSubmit?.preventDefault) {
179+
await fetch(props.action || window.location.href, {
180+
method: props.method || "POST",
181+
body: new FormData(event.target),
182+
});
183+
}
184+
if (oldOnSubmit) {
185+
oldOnSubmit(event);
186+
}
187+
}
188+
189+
// Use createElement here to avoid warning about variable numbers of children not
190+
// having keys. Warning about this must now be the responsibility of the server
191+
// providing the models instead of the client rendering them.
192+
return React.createElement(
193+
model.tagName,
194+
{ ...props, onSubmit },
195+
...createElementChildren(
196+
model,
197+
(model) => html`<${Element} key=${model.key} model=${model} />`
198+
)
199+
);
200+
}
201+
158202
function ImportedElement({ model }) {
159203
const layoutContext = React.useContext(LayoutContext);
160204

0 commit comments

Comments
 (0)