-
Notifications
You must be signed in to change notification settings - Fork 34
/
Copy pathform.js
57 lines (52 loc) · 1.43 KB
/
form.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import {html} from "htl";
export function form(inputs, options) {
return (Array.isArray(inputs) ? arrayForm : objectForm)(inputs, options);
}
function arrayTemplate(inputs) {
return html`<div>${inputs}`;
}
function arrayForm(inputs, {template = arrayTemplate} = {}) {
inputs = [...inputs]; // defensive copy
let value = inputs.map(({value}) => value);
return Object.defineProperty(template(inputs), "value", {
get() {
for (let i = 0, n = inputs.length; i < n; ++i) {
const v = inputs[i].value;
if (!Object.is(v, value[i])) {
value = [...value];
value[i] = v;
}
}
return value;
},
set(v = []) {
for (let i = 0, n = inputs.length; i < n; ++i) {
inputs[i].value = v[i];
}
}
});
}
function objectTemplate(inputs) {
return html`<div>${Object.values(inputs)}`;
}
function objectForm(inputs, {template = objectTemplate} = {}) {
inputs = {...inputs}; // defensive copy
let value = Object.fromEntries(Object.entries(inputs).map(([name, {value}]) => [name, value]));
return Object.defineProperty(template(inputs), "value", {
get() {
for (const k in value) {
const v = inputs[k].value;
if (!Object.is(v, value[k])) {
value = {...value};
value[k] = v;
}
}
return value;
},
set(v = {}) {
for (const name in inputs) {
inputs[name].value = v[name];
}
}
});
}