@conform-to/dom 1.17.0 → 1.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/dom.d.ts +13 -9
- package/dist/dom.js +91 -24
- package/dist/dom.mjs +90 -24
- package/dist/form.js +23 -23
- package/dist/form.mjs +24 -24
- package/dist/formdata.d.ts +41 -26
- package/dist/formdata.js +103 -102
- package/dist/formdata.mjs +97 -97
- package/dist/future/index.d.ts +2 -2
- package/dist/future/index.js +7 -6
- package/dist/future/index.mjs +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4 -3
- package/dist/index.mjs +1 -1
- package/dist/standard-schema.js +1 -1
- package/dist/standard-schema.mjs +2 -2
- package/dist/submission.js +11 -11
- package/dist/submission.mjs +12 -12
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
╚══════╝ ╚═════╝ ╚═╝ ╚══╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝
|
|
8
8
|
```
|
|
9
9
|
|
|
10
|
-
Version 1.
|
|
10
|
+
Version 1.18.0 / License MIT / Copyright (c) 2026 Edmund Hung
|
|
11
11
|
|
|
12
12
|
Progressively enhance HTML forms with React. Build resilient, type-safe forms with no hassle using web standards.
|
|
13
13
|
|
package/dist/dom.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export type FieldElement = HTMLInputElement | HTMLSelectElement | HTMLTextAreaEl
|
|
|
7
7
|
* Form Control element. It can either be a submit button or a submit input.
|
|
8
8
|
*/
|
|
9
9
|
export type Submitter = HTMLInputElement | HTMLButtonElement;
|
|
10
|
+
export declare function dispatchInternalUpdateEvent(form: HTMLFormElement): void;
|
|
10
11
|
export declare function isInputElement(element: Element): element is HTMLInputElement;
|
|
11
12
|
export declare function isSelectElement(element: Element): element is HTMLSelectElement;
|
|
12
13
|
export declare function isTextAreaElement(element: Element): element is HTMLTextAreaElement;
|
|
@@ -38,15 +39,11 @@ export declare function getFormEncType(event: SubmitEvent): 'application/x-www-f
|
|
|
38
39
|
* with respect to the submitter `formmethod` attribute.
|
|
39
40
|
*/
|
|
40
41
|
export declare function getFormMethod(event: SubmitEvent): 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
41
|
-
/**
|
|
42
|
-
* Creates a submit event that behaves like a real form submission.
|
|
43
|
-
*/
|
|
44
|
-
export declare function createSubmitEvent(submitter?: HTMLElement | null): SubmitEvent;
|
|
45
42
|
/**
|
|
46
43
|
* Trigger a form submit event with an optional submitter.
|
|
47
44
|
* If the submitter is not mounted, it will be appended to the form and removed after submission.
|
|
48
45
|
*/
|
|
49
|
-
export declare function requestSubmit(form: HTMLFormElement | null | undefined, submitter:
|
|
46
|
+
export declare function requestSubmit(form: HTMLFormElement | null | undefined, submitter: HTMLElement | null): void;
|
|
50
47
|
/**
|
|
51
48
|
* Triggers form submission with an intent value. This is achieved by
|
|
52
49
|
* creating a hidden button element with the intent value and then submitting it with the form.
|
|
@@ -62,26 +59,33 @@ type FormCallback = (event: {
|
|
|
62
59
|
target: HTMLFormElement;
|
|
63
60
|
submitter?: HTMLInputElement | HTMLButtonElement | null;
|
|
64
61
|
}) => void;
|
|
62
|
+
type InternalUpdateEvent = {
|
|
63
|
+
target: HTMLFormElement;
|
|
64
|
+
};
|
|
65
|
+
type InternalCallback = (event: InternalUpdateEvent) => void;
|
|
65
66
|
export declare function createGlobalFormsObserver(): {
|
|
66
67
|
onFieldUpdate(callback: InputCallback): () => void;
|
|
67
68
|
onFormUpdate(callback: FormCallback): () => void;
|
|
69
|
+
onInternalUpdate(callback: InternalCallback): () => void;
|
|
68
70
|
dispose(): void;
|
|
69
71
|
};
|
|
72
|
+
export declare function isCheckboxGroup(element: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement): boolean;
|
|
70
73
|
/**
|
|
71
74
|
* Change the value of the given field element.
|
|
72
75
|
* Dispatches both `input` and `change` events only if the value is changed.
|
|
73
76
|
*/
|
|
74
|
-
export declare function change(element: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement
|
|
77
|
+
export declare function change(element: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement | HTMLFieldSetElement | Array<HTMLInputElement>, value: unknown, options?: {
|
|
75
78
|
preventDefault?: boolean;
|
|
76
|
-
|
|
79
|
+
forceDispatch?: boolean;
|
|
80
|
+
}): boolean;
|
|
77
81
|
/**
|
|
78
82
|
* Dispatches focus and focusin events on the given element.
|
|
79
83
|
*/
|
|
80
|
-
export declare function focus(element:
|
|
84
|
+
export declare function focus(element: Element): void;
|
|
81
85
|
/**
|
|
82
86
|
* Dispatches blur and focusout events on the given element.
|
|
83
87
|
*/
|
|
84
|
-
export declare function blur(element:
|
|
88
|
+
export declare function blur(element: Element): void;
|
|
85
89
|
export declare function normalizeStringValues(value: unknown): string[] | undefined;
|
|
86
90
|
export declare function normalizeFileValues(value: unknown): File[] | undefined;
|
|
87
91
|
/**
|
package/dist/dom.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
+
var formdata = require('./formdata.js');
|
|
5
6
|
var util = require('./util.js');
|
|
6
7
|
|
|
7
8
|
/**
|
|
@@ -13,6 +14,10 @@ var util = require('./util.js');
|
|
|
13
14
|
* Form Control element. It can either be a submit button or a submit input.
|
|
14
15
|
*/
|
|
15
16
|
|
|
17
|
+
var CONFORM_INTERNAL_EVENT = 'conform:internal';
|
|
18
|
+
function dispatchInternalUpdateEvent(form) {
|
|
19
|
+
form.dispatchEvent(new Event(CONFORM_INTERNAL_EVENT));
|
|
20
|
+
}
|
|
16
21
|
function isInputElement(element) {
|
|
17
22
|
return element.tagName === 'INPUT';
|
|
18
23
|
}
|
|
@@ -96,27 +101,24 @@ function getFormMethod(event) {
|
|
|
96
101
|
return 'GET';
|
|
97
102
|
}
|
|
98
103
|
|
|
99
|
-
/**
|
|
100
|
-
* Creates a submit event that behaves like a real form submission.
|
|
101
|
-
*/
|
|
102
|
-
function createSubmitEvent(submitter) {
|
|
103
|
-
return new SubmitEvent('submit', {
|
|
104
|
-
bubbles: true,
|
|
105
|
-
cancelable: true,
|
|
106
|
-
submitter
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
|
|
110
104
|
/**
|
|
111
105
|
* Trigger a form submit event with an optional submitter.
|
|
112
106
|
* If the submitter is not mounted, it will be appended to the form and removed after submission.
|
|
113
107
|
*/
|
|
114
108
|
function requestSubmit(form, submitter) {
|
|
115
|
-
util.invariant(
|
|
109
|
+
util.invariant(form != null, 'Form element is required to trigger submission.');
|
|
110
|
+
util.invariant(submitter === null || isSubmitter(submitter), 'Submitter must be a button or input element or null.');
|
|
111
|
+
util.invariant(submitter === null || submitter.form === form, 'Submitter must be associated with the form.');
|
|
116
112
|
if (typeof form.requestSubmit === 'function') {
|
|
117
113
|
form.requestSubmit(submitter);
|
|
114
|
+
} else if (submitter) {
|
|
115
|
+
submitter.click();
|
|
118
116
|
} else {
|
|
119
|
-
|
|
117
|
+
var submitButton = document.createElement('button');
|
|
118
|
+
submitButton.hidden = true;
|
|
119
|
+
form.appendChild(submitButton);
|
|
120
|
+
submitButton.click();
|
|
121
|
+
form.removeChild(submitButton);
|
|
120
122
|
}
|
|
121
123
|
}
|
|
122
124
|
|
|
@@ -148,6 +150,7 @@ function createFileList(value) {
|
|
|
148
150
|
function createGlobalFormsObserver() {
|
|
149
151
|
var inputListeners = new Set();
|
|
150
152
|
var formListeners = new Set();
|
|
153
|
+
var internalListeners = new Set();
|
|
151
154
|
var cleanup = null;
|
|
152
155
|
function initialize() {
|
|
153
156
|
var observer = new MutationObserver(handleMutation);
|
|
@@ -160,10 +163,12 @@ function createGlobalFormsObserver() {
|
|
|
160
163
|
});
|
|
161
164
|
document.addEventListener('input', handleInput);
|
|
162
165
|
document.addEventListener('reset', handleReset);
|
|
166
|
+
document.addEventListener(CONFORM_INTERNAL_EVENT, handleInternal, true);
|
|
163
167
|
document.addEventListener('submit', handleSubmit, true);
|
|
164
168
|
return () => {
|
|
165
169
|
document.removeEventListener('input', handleInput);
|
|
166
170
|
document.removeEventListener('reset', handleReset);
|
|
171
|
+
document.removeEventListener(CONFORM_INTERNAL_EVENT, handleInternal, true);
|
|
167
172
|
document.removeEventListener('submit', handleSubmit, true);
|
|
168
173
|
observer.disconnect();
|
|
169
174
|
};
|
|
@@ -222,6 +227,14 @@ function createGlobalFormsObserver() {
|
|
|
222
227
|
}));
|
|
223
228
|
}
|
|
224
229
|
}
|
|
230
|
+
function handleInternal(event) {
|
|
231
|
+
var target = event.target;
|
|
232
|
+
if (target instanceof HTMLFormElement) {
|
|
233
|
+
internalListeners.forEach(callback => callback({
|
|
234
|
+
target
|
|
235
|
+
}));
|
|
236
|
+
}
|
|
237
|
+
}
|
|
225
238
|
function getAssociatedFormElement(formId, node) {
|
|
226
239
|
if (formId !== null) {
|
|
227
240
|
return document.forms.namedItem(formId);
|
|
@@ -324,26 +337,76 @@ function createGlobalFormsObserver() {
|
|
|
324
337
|
formListeners.delete(callback);
|
|
325
338
|
};
|
|
326
339
|
},
|
|
327
|
-
|
|
340
|
+
onInternalUpdate(callback) {
|
|
328
341
|
var _cleanup3;
|
|
329
|
-
(_cleanup3 = cleanup)
|
|
342
|
+
cleanup = (_cleanup3 = cleanup) !== null && _cleanup3 !== void 0 ? _cleanup3 : initialize();
|
|
343
|
+
internalListeners.add(callback);
|
|
344
|
+
return () => {
|
|
345
|
+
internalListeners.delete(callback);
|
|
346
|
+
};
|
|
347
|
+
},
|
|
348
|
+
dispose() {
|
|
349
|
+
var _cleanup4;
|
|
350
|
+
(_cleanup4 = cleanup) === null || _cleanup4 === void 0 || _cleanup4();
|
|
330
351
|
cleanup = null;
|
|
331
352
|
inputListeners.clear();
|
|
332
353
|
formListeners.clear();
|
|
354
|
+
internalListeners.clear();
|
|
333
355
|
}
|
|
334
356
|
};
|
|
335
357
|
}
|
|
358
|
+
function isCheckboxGroup(element) {
|
|
359
|
+
if (element.type === 'checkbox') {
|
|
360
|
+
for (var input of (_element$form$element = (_element$form = element.form) === null || _element$form === void 0 ? void 0 : _element$form.elements) !== null && _element$form$element !== void 0 ? _element$form$element : []) {
|
|
361
|
+
var _element$form$element, _element$form;
|
|
362
|
+
if (input instanceof HTMLInputElement && input !== element && input.type === 'checkbox' && input.name === element.name) {
|
|
363
|
+
return true;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
return false;
|
|
368
|
+
}
|
|
336
369
|
|
|
337
370
|
/**
|
|
338
371
|
* Change the value of the given field element.
|
|
339
372
|
* Dispatches both `input` and `change` events only if the value is changed.
|
|
340
373
|
*/
|
|
341
374
|
function change(element, value, options) {
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
375
|
+
var isChanged = false;
|
|
376
|
+
if (element instanceof HTMLFieldSetElement || Array.isArray(element)) {
|
|
377
|
+
var baseName;
|
|
378
|
+
var inputs;
|
|
379
|
+
var preventDefault;
|
|
380
|
+
if (Array.isArray(element)) {
|
|
381
|
+
var _element$0$name, _element$;
|
|
382
|
+
baseName = (_element$0$name = (_element$ = element[0]) === null || _element$ === void 0 ? void 0 : _element$.name) !== null && _element$0$name !== void 0 ? _element$0$name : '';
|
|
383
|
+
inputs = element;
|
|
384
|
+
preventDefault = false;
|
|
385
|
+
} else {
|
|
386
|
+
baseName = element.name;
|
|
387
|
+
inputs = Array.from(element.elements);
|
|
388
|
+
preventDefault = true;
|
|
389
|
+
}
|
|
390
|
+
for (var input of inputs) {
|
|
391
|
+
if (isFieldElement(input)) {
|
|
392
|
+
var path = formdata.getRelativePath(input.name, baseName);
|
|
393
|
+
if (path) {
|
|
394
|
+
var name = formdata.formatPath(path);
|
|
395
|
+
var pathValue = value === null ? value : formdata.getPathValue(value, name);
|
|
396
|
+
var isInputChanged = change(input, isCheckboxGroup(input) && Array.isArray(pathValue) ? pathValue.includes(input.value) : pathValue, {
|
|
397
|
+
preventDefault
|
|
398
|
+
});
|
|
399
|
+
isChanged || (isChanged = isInputChanged);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
} else {
|
|
404
|
+
// The value should be set to the element before dispatching the event
|
|
405
|
+
isChanged = updateField(element, {
|
|
406
|
+
value: typeof value === 'boolean' ? value ? element.value : null : value
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
if (element instanceof Element && (isChanged || options !== null && options !== void 0 && options.forceDispatch)) {
|
|
347
410
|
var inputEvent = new InputEvent('input', {
|
|
348
411
|
bubbles: true,
|
|
349
412
|
cancelable: true
|
|
@@ -362,6 +425,7 @@ function change(element, value, options) {
|
|
|
362
425
|
// Dispatch change event (necessary for select to update the selected option)
|
|
363
426
|
element.dispatchEvent(changeEvent);
|
|
364
427
|
}
|
|
428
|
+
return isChanged;
|
|
365
429
|
}
|
|
366
430
|
|
|
367
431
|
/**
|
|
@@ -431,9 +495,11 @@ function updateField(element, options) {
|
|
|
431
495
|
var _defaultValue = normalizeStringValues(options.defaultValue);
|
|
432
496
|
if (_value) {
|
|
433
497
|
var checked = _value.includes(element.value);
|
|
434
|
-
if (
|
|
435
|
-
|
|
436
|
-
|
|
498
|
+
if (checked !== element.checked) {
|
|
499
|
+
if (element.type === 'checkbox' || checked) {
|
|
500
|
+
// Simulate a click to update the checked state
|
|
501
|
+
element.click();
|
|
502
|
+
}
|
|
437
503
|
isChanged = true;
|
|
438
504
|
}
|
|
439
505
|
element.checked = checked;
|
|
@@ -554,11 +620,12 @@ exports.blur = blur;
|
|
|
554
620
|
exports.change = change;
|
|
555
621
|
exports.createFileList = createFileList;
|
|
556
622
|
exports.createGlobalFormsObserver = createGlobalFormsObserver;
|
|
557
|
-
exports.
|
|
623
|
+
exports.dispatchInternalUpdateEvent = dispatchInternalUpdateEvent;
|
|
558
624
|
exports.focus = focus;
|
|
559
625
|
exports.getFormAction = getFormAction;
|
|
560
626
|
exports.getFormEncType = getFormEncType;
|
|
561
627
|
exports.getFormMethod = getFormMethod;
|
|
628
|
+
exports.isCheckboxGroup = isCheckboxGroup;
|
|
562
629
|
exports.isDirtyInput = isDirtyInput;
|
|
563
630
|
exports.isFieldElement = isFieldElement;
|
|
564
631
|
exports.isGlobalInstance = isGlobalInstance;
|
package/dist/dom.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getRelativePath, formatPath, getPathValue } from './formdata.mjs';
|
|
1
2
|
import { invariant } from './util.mjs';
|
|
2
3
|
|
|
3
4
|
/**
|
|
@@ -9,6 +10,10 @@ import { invariant } from './util.mjs';
|
|
|
9
10
|
* Form Control element. It can either be a submit button or a submit input.
|
|
10
11
|
*/
|
|
11
12
|
|
|
13
|
+
var CONFORM_INTERNAL_EVENT = 'conform:internal';
|
|
14
|
+
function dispatchInternalUpdateEvent(form) {
|
|
15
|
+
form.dispatchEvent(new Event(CONFORM_INTERNAL_EVENT));
|
|
16
|
+
}
|
|
12
17
|
function isInputElement(element) {
|
|
13
18
|
return element.tagName === 'INPUT';
|
|
14
19
|
}
|
|
@@ -92,27 +97,24 @@ function getFormMethod(event) {
|
|
|
92
97
|
return 'GET';
|
|
93
98
|
}
|
|
94
99
|
|
|
95
|
-
/**
|
|
96
|
-
* Creates a submit event that behaves like a real form submission.
|
|
97
|
-
*/
|
|
98
|
-
function createSubmitEvent(submitter) {
|
|
99
|
-
return new SubmitEvent('submit', {
|
|
100
|
-
bubbles: true,
|
|
101
|
-
cancelable: true,
|
|
102
|
-
submitter
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
|
|
106
100
|
/**
|
|
107
101
|
* Trigger a form submit event with an optional submitter.
|
|
108
102
|
* If the submitter is not mounted, it will be appended to the form and removed after submission.
|
|
109
103
|
*/
|
|
110
104
|
function requestSubmit(form, submitter) {
|
|
111
|
-
invariant(
|
|
105
|
+
invariant(form != null, 'Form element is required to trigger submission.');
|
|
106
|
+
invariant(submitter === null || isSubmitter(submitter), 'Submitter must be a button or input element or null.');
|
|
107
|
+
invariant(submitter === null || submitter.form === form, 'Submitter must be associated with the form.');
|
|
112
108
|
if (typeof form.requestSubmit === 'function') {
|
|
113
109
|
form.requestSubmit(submitter);
|
|
110
|
+
} else if (submitter) {
|
|
111
|
+
submitter.click();
|
|
114
112
|
} else {
|
|
115
|
-
|
|
113
|
+
var submitButton = document.createElement('button');
|
|
114
|
+
submitButton.hidden = true;
|
|
115
|
+
form.appendChild(submitButton);
|
|
116
|
+
submitButton.click();
|
|
117
|
+
form.removeChild(submitButton);
|
|
116
118
|
}
|
|
117
119
|
}
|
|
118
120
|
|
|
@@ -144,6 +146,7 @@ function createFileList(value) {
|
|
|
144
146
|
function createGlobalFormsObserver() {
|
|
145
147
|
var inputListeners = new Set();
|
|
146
148
|
var formListeners = new Set();
|
|
149
|
+
var internalListeners = new Set();
|
|
147
150
|
var cleanup = null;
|
|
148
151
|
function initialize() {
|
|
149
152
|
var observer = new MutationObserver(handleMutation);
|
|
@@ -156,10 +159,12 @@ function createGlobalFormsObserver() {
|
|
|
156
159
|
});
|
|
157
160
|
document.addEventListener('input', handleInput);
|
|
158
161
|
document.addEventListener('reset', handleReset);
|
|
162
|
+
document.addEventListener(CONFORM_INTERNAL_EVENT, handleInternal, true);
|
|
159
163
|
document.addEventListener('submit', handleSubmit, true);
|
|
160
164
|
return () => {
|
|
161
165
|
document.removeEventListener('input', handleInput);
|
|
162
166
|
document.removeEventListener('reset', handleReset);
|
|
167
|
+
document.removeEventListener(CONFORM_INTERNAL_EVENT, handleInternal, true);
|
|
163
168
|
document.removeEventListener('submit', handleSubmit, true);
|
|
164
169
|
observer.disconnect();
|
|
165
170
|
};
|
|
@@ -218,6 +223,14 @@ function createGlobalFormsObserver() {
|
|
|
218
223
|
}));
|
|
219
224
|
}
|
|
220
225
|
}
|
|
226
|
+
function handleInternal(event) {
|
|
227
|
+
var target = event.target;
|
|
228
|
+
if (target instanceof HTMLFormElement) {
|
|
229
|
+
internalListeners.forEach(callback => callback({
|
|
230
|
+
target
|
|
231
|
+
}));
|
|
232
|
+
}
|
|
233
|
+
}
|
|
221
234
|
function getAssociatedFormElement(formId, node) {
|
|
222
235
|
if (formId !== null) {
|
|
223
236
|
return document.forms.namedItem(formId);
|
|
@@ -320,26 +333,76 @@ function createGlobalFormsObserver() {
|
|
|
320
333
|
formListeners.delete(callback);
|
|
321
334
|
};
|
|
322
335
|
},
|
|
323
|
-
|
|
336
|
+
onInternalUpdate(callback) {
|
|
324
337
|
var _cleanup3;
|
|
325
|
-
(_cleanup3 = cleanup)
|
|
338
|
+
cleanup = (_cleanup3 = cleanup) !== null && _cleanup3 !== void 0 ? _cleanup3 : initialize();
|
|
339
|
+
internalListeners.add(callback);
|
|
340
|
+
return () => {
|
|
341
|
+
internalListeners.delete(callback);
|
|
342
|
+
};
|
|
343
|
+
},
|
|
344
|
+
dispose() {
|
|
345
|
+
var _cleanup4;
|
|
346
|
+
(_cleanup4 = cleanup) === null || _cleanup4 === void 0 || _cleanup4();
|
|
326
347
|
cleanup = null;
|
|
327
348
|
inputListeners.clear();
|
|
328
349
|
formListeners.clear();
|
|
350
|
+
internalListeners.clear();
|
|
329
351
|
}
|
|
330
352
|
};
|
|
331
353
|
}
|
|
354
|
+
function isCheckboxGroup(element) {
|
|
355
|
+
if (element.type === 'checkbox') {
|
|
356
|
+
for (var input of (_element$form$element = (_element$form = element.form) === null || _element$form === void 0 ? void 0 : _element$form.elements) !== null && _element$form$element !== void 0 ? _element$form$element : []) {
|
|
357
|
+
var _element$form$element, _element$form;
|
|
358
|
+
if (input instanceof HTMLInputElement && input !== element && input.type === 'checkbox' && input.name === element.name) {
|
|
359
|
+
return true;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
return false;
|
|
364
|
+
}
|
|
332
365
|
|
|
333
366
|
/**
|
|
334
367
|
* Change the value of the given field element.
|
|
335
368
|
* Dispatches both `input` and `change` events only if the value is changed.
|
|
336
369
|
*/
|
|
337
370
|
function change(element, value, options) {
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
371
|
+
var isChanged = false;
|
|
372
|
+
if (element instanceof HTMLFieldSetElement || Array.isArray(element)) {
|
|
373
|
+
var baseName;
|
|
374
|
+
var inputs;
|
|
375
|
+
var preventDefault;
|
|
376
|
+
if (Array.isArray(element)) {
|
|
377
|
+
var _element$0$name, _element$;
|
|
378
|
+
baseName = (_element$0$name = (_element$ = element[0]) === null || _element$ === void 0 ? void 0 : _element$.name) !== null && _element$0$name !== void 0 ? _element$0$name : '';
|
|
379
|
+
inputs = element;
|
|
380
|
+
preventDefault = false;
|
|
381
|
+
} else {
|
|
382
|
+
baseName = element.name;
|
|
383
|
+
inputs = Array.from(element.elements);
|
|
384
|
+
preventDefault = true;
|
|
385
|
+
}
|
|
386
|
+
for (var input of inputs) {
|
|
387
|
+
if (isFieldElement(input)) {
|
|
388
|
+
var path = getRelativePath(input.name, baseName);
|
|
389
|
+
if (path) {
|
|
390
|
+
var name = formatPath(path);
|
|
391
|
+
var pathValue = value === null ? value : getPathValue(value, name);
|
|
392
|
+
var isInputChanged = change(input, isCheckboxGroup(input) && Array.isArray(pathValue) ? pathValue.includes(input.value) : pathValue, {
|
|
393
|
+
preventDefault
|
|
394
|
+
});
|
|
395
|
+
isChanged || (isChanged = isInputChanged);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
} else {
|
|
400
|
+
// The value should be set to the element before dispatching the event
|
|
401
|
+
isChanged = updateField(element, {
|
|
402
|
+
value: typeof value === 'boolean' ? value ? element.value : null : value
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
if (element instanceof Element && (isChanged || options !== null && options !== void 0 && options.forceDispatch)) {
|
|
343
406
|
var inputEvent = new InputEvent('input', {
|
|
344
407
|
bubbles: true,
|
|
345
408
|
cancelable: true
|
|
@@ -358,6 +421,7 @@ function change(element, value, options) {
|
|
|
358
421
|
// Dispatch change event (necessary for select to update the selected option)
|
|
359
422
|
element.dispatchEvent(changeEvent);
|
|
360
423
|
}
|
|
424
|
+
return isChanged;
|
|
361
425
|
}
|
|
362
426
|
|
|
363
427
|
/**
|
|
@@ -427,9 +491,11 @@ function updateField(element, options) {
|
|
|
427
491
|
var _defaultValue = normalizeStringValues(options.defaultValue);
|
|
428
492
|
if (_value) {
|
|
429
493
|
var checked = _value.includes(element.value);
|
|
430
|
-
if (
|
|
431
|
-
|
|
432
|
-
|
|
494
|
+
if (checked !== element.checked) {
|
|
495
|
+
if (element.type === 'checkbox' || checked) {
|
|
496
|
+
// Simulate a click to update the checked state
|
|
497
|
+
element.click();
|
|
498
|
+
}
|
|
433
499
|
isChanged = true;
|
|
434
500
|
}
|
|
435
501
|
element.checked = checked;
|
|
@@ -546,4 +612,4 @@ function isDirtyInput(element) {
|
|
|
546
612
|
return false;
|
|
547
613
|
}
|
|
548
614
|
|
|
549
|
-
export { blur, change, createFileList, createGlobalFormsObserver,
|
|
615
|
+
export { blur, change, createFileList, createGlobalFormsObserver, dispatchInternalUpdateEvent, focus, getFormAction, getFormEncType, getFormMethod, isCheckboxGroup, isDirtyInput, isFieldElement, isGlobalInstance, isInputElement, isSelectElement, isSubmitter, isTextAreaElement, normalizeFileValues, normalizeStringValues, requestIntent, requestSubmit, updateField };
|
package/dist/form.js
CHANGED
|
@@ -43,7 +43,7 @@ function getDefaultKey(defaultValue, prefix) {
|
|
|
43
43
|
var [key, value] = _ref2;
|
|
44
44
|
if (Array.isArray(value)) {
|
|
45
45
|
for (var i = 0; i < value.length; i++) {
|
|
46
|
-
result[formdata.
|
|
46
|
+
result[formdata.appendPath(key, i)] = util.generateId();
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
return result;
|
|
@@ -76,7 +76,7 @@ function handleIntent(meta, intent, fields, initialized) {
|
|
|
76
76
|
validated,
|
|
77
77
|
value
|
|
78
78
|
} = intent.payload;
|
|
79
|
-
var _name2 = formdata.
|
|
79
|
+
var _name2 = formdata.appendPath(intent.payload.name, intent.payload.index);
|
|
80
80
|
if (typeof value !== 'undefined') {
|
|
81
81
|
updateValue(meta, _name2 !== null && _name2 !== void 0 ? _name2 : '', value);
|
|
82
82
|
}
|
|
@@ -105,8 +105,8 @@ function handleIntent(meta, intent, fields, initialized) {
|
|
|
105
105
|
}
|
|
106
106
|
case 'reset':
|
|
107
107
|
{
|
|
108
|
-
var _name3 = formdata.
|
|
109
|
-
var _value = formdata.
|
|
108
|
+
var _name3 = formdata.appendPath(intent.payload.name, intent.payload.index);
|
|
109
|
+
var _value = formdata.getPathValue(meta.defaultValue, _name3);
|
|
110
110
|
updateValue(meta, _name3, _value);
|
|
111
111
|
if (_name3) {
|
|
112
112
|
submission.setState(meta.validated, _name3, () => undefined);
|
|
@@ -141,7 +141,7 @@ function handleIntent(meta, intent, fields, initialized) {
|
|
|
141
141
|
var validatedFields = (_fields$filter = fields === null || fields === void 0 ? void 0 : fields.filter(name => meta.validated[name])) !== null && _fields$filter !== void 0 ? _fields$filter : [];
|
|
142
142
|
meta.error = Object.entries(meta.error).reduce((result, _ref3) => {
|
|
143
143
|
var [name, error] = _ref3;
|
|
144
|
-
if (meta.validated[name] || validatedFields.some(field => formdata.
|
|
144
|
+
if (meta.validated[name] || validatedFields.some(field => formdata.isPathPrefix(name, field))) {
|
|
145
145
|
result[name] = error;
|
|
146
146
|
}
|
|
147
147
|
return result;
|
|
@@ -159,8 +159,8 @@ function updateValue(meta, name, value) {
|
|
|
159
159
|
meta.initialValue = util.clone(meta.initialValue);
|
|
160
160
|
meta.value = util.clone(meta.value);
|
|
161
161
|
meta.key = util.clone(meta.key);
|
|
162
|
-
formdata.
|
|
163
|
-
formdata.
|
|
162
|
+
formdata.setPathValue(meta.initialValue, name, () => value);
|
|
163
|
+
formdata.setPathValue(meta.value, name, () => value);
|
|
164
164
|
if (util.isPlainObject(value) || Array.isArray(value)) {
|
|
165
165
|
submission.setState(meta.key, name, () => undefined);
|
|
166
166
|
Object.assign(meta.key, getDefaultKey(value, name));
|
|
@@ -185,11 +185,11 @@ function createValueProxy(value) {
|
|
|
185
185
|
if (name === '') {
|
|
186
186
|
return val;
|
|
187
187
|
}
|
|
188
|
-
var path = formdata.
|
|
189
|
-
var basename = formdata.
|
|
190
|
-
var key = formdata.
|
|
188
|
+
var path = formdata.parsePath(name);
|
|
189
|
+
var basename = formdata.formatPath(path.slice(0, -1));
|
|
190
|
+
var key = formdata.formatPath(path.slice(-1));
|
|
191
191
|
var parentValue = proxy[basename];
|
|
192
|
-
return formdata.
|
|
192
|
+
return formdata.getPathValue(parentValue, key);
|
|
193
193
|
});
|
|
194
194
|
}
|
|
195
195
|
function createConstraintProxy(constraint) {
|
|
@@ -197,7 +197,7 @@ function createConstraintProxy(constraint) {
|
|
|
197
197
|
var _result;
|
|
198
198
|
var result = constraint[name];
|
|
199
199
|
if (!result) {
|
|
200
|
-
var path = formdata.
|
|
200
|
+
var path = formdata.parsePath(name);
|
|
201
201
|
for (var i = path.length - 1; i >= 0; i--) {
|
|
202
202
|
var segment = path[i];
|
|
203
203
|
|
|
@@ -210,7 +210,7 @@ function createConstraintProxy(constraint) {
|
|
|
210
210
|
break;
|
|
211
211
|
}
|
|
212
212
|
}
|
|
213
|
-
var alternative = formdata.
|
|
213
|
+
var alternative = formdata.formatPath(path);
|
|
214
214
|
if (name !== alternative) {
|
|
215
215
|
result = proxy[alternative];
|
|
216
216
|
}
|
|
@@ -221,11 +221,11 @@ function createConstraintProxy(constraint) {
|
|
|
221
221
|
function createKeyProxy(key) {
|
|
222
222
|
return createStateProxy((name, proxy) => {
|
|
223
223
|
var currentKey = key[name];
|
|
224
|
-
var segments = formdata.
|
|
224
|
+
var segments = formdata.parsePath(name);
|
|
225
225
|
if (segments.length === 0) {
|
|
226
226
|
return currentKey;
|
|
227
227
|
}
|
|
228
|
-
var parentKey = proxy[formdata.
|
|
228
|
+
var parentKey = proxy[formdata.formatPath(segments.slice(0, -1))];
|
|
229
229
|
if (typeof parentKey === 'undefined') {
|
|
230
230
|
return currentKey;
|
|
231
231
|
}
|
|
@@ -239,7 +239,7 @@ function createValidProxy(error) {
|
|
|
239
239
|
return keys.length === 0;
|
|
240
240
|
}
|
|
241
241
|
for (var key of keys) {
|
|
242
|
-
if (formdata.
|
|
242
|
+
if (formdata.isPathPrefix(key, name) && typeof error[key] !== 'undefined') {
|
|
243
243
|
return false;
|
|
244
244
|
}
|
|
245
245
|
}
|
|
@@ -270,7 +270,7 @@ function shouldNotify(prev, next, cache, scope) {
|
|
|
270
270
|
var names = (_scope$name = scope.name) !== null && _scope$name !== void 0 ? _scope$name : [];
|
|
271
271
|
var list = prefixes.length === 0 ? names : Array.from(new Set([...Object.keys(prev), ...Object.keys(next)]));
|
|
272
272
|
var _loop = function _loop(_name4) {
|
|
273
|
-
if (prefixes.length === 0 || names.includes(_name4) || prefixes.some(prefix => formdata.
|
|
273
|
+
if (prefixes.length === 0 || names.includes(_name4) || prefixes.some(prefix => formdata.isPathPrefix(_name4, prefix))) {
|
|
274
274
|
var _cache$_name;
|
|
275
275
|
(_cache$_name = cache[_name4]) !== null && _cache$_name !== void 0 ? _cache$_name : cache[_name4] = compareFn(prev[_name4], next[_name4]);
|
|
276
276
|
if (cache[_name4]) {
|
|
@@ -580,13 +580,13 @@ function createFormContext(options) {
|
|
|
580
580
|
switch (intent.type) {
|
|
581
581
|
case 'update':
|
|
582
582
|
{
|
|
583
|
-
var _name5 = formdata.
|
|
584
|
-
var baseSegments = formdata.
|
|
583
|
+
var _name5 = formdata.appendPath(intent.payload.name, intent.payload.index);
|
|
584
|
+
var baseSegments = formdata.parsePath(_name5);
|
|
585
585
|
for (var element of formElement.elements) {
|
|
586
586
|
if (dom.isFieldElement(element)) {
|
|
587
587
|
var paths = formdata.getRelativePath(element.name, baseSegments);
|
|
588
588
|
if (paths) {
|
|
589
|
-
var value = formdata.
|
|
589
|
+
var value = formdata.getPathValue(intent.payload.value, paths);
|
|
590
590
|
var inputValue = typeof value === 'string' || Array.isArray(value) && value.every(item => typeof item === 'string') ? value : undefined;
|
|
591
591
|
if (typeof inputValue !== 'undefined' || _name5 === '' && paths.length > 1) {
|
|
592
592
|
dom.updateField(element, {
|
|
@@ -603,10 +603,10 @@ function createFormContext(options) {
|
|
|
603
603
|
}
|
|
604
604
|
case 'reset':
|
|
605
605
|
{
|
|
606
|
-
var prefix = formdata.
|
|
606
|
+
var prefix = formdata.appendPath(intent.payload.name, intent.payload.index);
|
|
607
607
|
for (var _element of formElement.elements) {
|
|
608
|
-
if (dom.isFieldElement(_element) && _element.name && formdata.
|
|
609
|
-
var _value2 = formdata.
|
|
608
|
+
if (dom.isFieldElement(_element) && _element.name && formdata.isPathPrefix(_element.name, prefix)) {
|
|
609
|
+
var _value2 = formdata.getPathValue(meta.defaultValue, _element.name);
|
|
610
610
|
var defaultValue = typeof _value2 === 'string' || Array.isArray(_value2) && _value2.every(item => typeof item === 'string') ? _value2 : undefined;
|
|
611
611
|
if (typeof defaultValue === 'undefined' && !_element.dataset.conform && 'defaultValue' in _element && !dom.isDirtyInput(_element)) {
|
|
612
612
|
continue;
|