|
1 | | -import Observer from '@cocreate/observer'; |
2 | | -import { getAttributeNames, ObjectId } from '@cocreate/utils'; |
3 | | -import Action from '@cocreate/actions'; |
4 | | -import elementPrototype from '@cocreate/element-prototype'; |
5 | | - |
| 1 | +import Observer from "@cocreate/observer"; |
| 2 | +import { getAttributeNames, ObjectId } from "@cocreate/utils"; |
| 3 | +import Action from "@cocreate/actions"; |
| 4 | +import elementPrototype from "@cocreate/element-prototype"; |
6 | 5 |
|
7 | 6 | /** |
8 | | - * Initializes form elements. If no parameter is provided, or null is passed, it queries and initializes all form elements. |
| 7 | + * Initializes form elements. If no parameter is provided, or null is passed, it queries and initializes all form elements. |
9 | 8 | * It can also initialize a single form element or an array of form elements. |
10 | | - * |
| 9 | + * |
11 | 10 | * @param {(Element|Element[]|null)} [elements] - Optional. A single form element, an array of form elements, or null. |
12 | 11 | * - If null or omitted, the function queries and initializes all form elements. |
13 | 12 | * - If a single form element is provided, it initializes that element. |
14 | 13 | * - If an array of form elements is provided, each element in the array is initialized. |
15 | 14 | */ |
16 | 15 | function init(elements) { |
17 | | - if (!elements) |
18 | | - elements = document.querySelectorAll('form'); |
19 | | - else if (!Array.isArray(elements)) |
20 | | - elements = [elements] |
21 | | - |
22 | | - for (let element of elements) { |
23 | | - Observer.init({ |
24 | | - name: 'CoCreateFormElements', |
25 | | - observe: ['addedNodes'], |
26 | | - selector: '[storage], [database], [array], [index], [object], [key]', |
27 | | - callback: function (mutation) { |
28 | | - if (element == mutation.target.form) |
29 | | - setAttribute(element, [mutation.target]) |
30 | | - } |
31 | | - }); |
32 | | - |
33 | | - runObjectId(element); |
34 | | - setAttribute(element); |
35 | | - disableAutoFill(element); |
36 | | - setValue(element) |
37 | | - element.addEventListener('submit', function (event) { |
38 | | - if (!element.hasAttribute('action')) { |
39 | | - event.preventDefault(); |
40 | | - } |
41 | | - }); |
42 | | - } |
| 16 | + if (!elements) elements = document.querySelectorAll("form"); |
| 17 | + else if (!Array.isArray(elements)) elements = [elements]; |
| 18 | + |
| 19 | + for (let element of elements) { |
| 20 | + Observer.init({ |
| 21 | + name: "CoCreateFormElements", |
| 22 | + observe: ["addedNodes"], |
| 23 | + selector: |
| 24 | + "[storage], [database], [array], [index], [object], [key]", |
| 25 | + callback: function (mutation) { |
| 26 | + if (element == mutation.target.form) |
| 27 | + setAttribute(element, [mutation.target]); |
| 28 | + } |
| 29 | + }); |
| 30 | + |
| 31 | + runObjectId(element); |
| 32 | + setAttribute(element); |
| 33 | + disableAutoFill(element); |
| 34 | + setValue(element); |
| 35 | + element.addEventListener("submit", function (event) { |
| 36 | + if (!element.hasAttribute("action")) { |
| 37 | + event.preventDefault(); |
| 38 | + } |
| 39 | + }); |
| 40 | + } |
43 | 41 | } |
44 | 42 |
|
45 | 43 | /** |
46 | | -* @param form |
47 | | -*/ |
| 44 | + * @param form |
| 45 | + */ |
48 | 46 | function runObjectId(form) { |
49 | | - let elements = Array.from(form.querySelectorAll("[object='ObjectId()']")); |
50 | | - |
51 | | - if (form.getAttribute('object') === "ObjectId()") { |
52 | | - elements.push(form); |
53 | | - } |
54 | | - for (let i = 0; i < elements.length; i++) { |
55 | | - let array = elements[i].getAttribute('array') |
56 | | - if (!array) |
57 | | - continue |
58 | | - elements[i].setAttribute('object', ObjectId().toString()) |
59 | | - |
60 | | - } |
| 47 | + let elements = Array.from(form.querySelectorAll("[object='ObjectId()']")); |
| 48 | + |
| 49 | + if (form.getAttribute("object") === "ObjectId()") { |
| 50 | + elements.push(form); |
| 51 | + } |
| 52 | + for (let i = 0; i < elements.length; i++) { |
| 53 | + let array = elements[i].getAttribute("array"); |
| 54 | + if (!array) continue; |
| 55 | + elements[i].setAttribute("object", ObjectId().toString()); |
| 56 | + } |
61 | 57 | } |
62 | 58 |
|
63 | 59 | /** |
64 | | -* @param form |
65 | | -*/ |
| 60 | + * @param form |
| 61 | + */ |
66 | 62 | function setAttribute(form, elements) { |
67 | | - if (!elements) |
68 | | - elements = form.querySelectorAll('[storage], [database], [array], [index], [object], [key]'); |
69 | | - |
70 | | - for (let attribute of form.attributes) { |
71 | | - let variable = window.CoCreateConfig.attributes[attribute.name] |
72 | | - |
73 | | - // Set the attribute of all elements in the variable |
74 | | - if (variable) { |
75 | | - for (let el of elements) { |
76 | | - // Set the value of the attribute. |
77 | | - // TODO: skip-attribute naming convention, perhaps skip by defualt if storage, database, array not the same and use attribute to apply for cases where one _id will be used across 2 arrays |
78 | | - if (!el.getAttribute(attribute.name) && !el.hasAttribute('skip-attribute')) { |
79 | | - el.setAttribute(attribute.name, attribute.value); |
80 | | - } |
81 | | - } |
82 | | - } |
83 | | - } |
| 63 | + if (!elements) |
| 64 | + elements = form.querySelectorAll( |
| 65 | + "[storage], [database], [array], [index], [object], [key]" |
| 66 | + ); |
| 67 | + |
| 68 | + for (let attribute of form.attributes) { |
| 69 | + let variable = window.CoCreateConfig.attributes[attribute.name]; |
| 70 | + |
| 71 | + // Set the attribute of all elements in the variable |
| 72 | + if (variable) { |
| 73 | + for (let el of elements) { |
| 74 | + // Set the value of the attribute. |
| 75 | + // TODO: skip-attribute naming convention, perhaps skip by defualt if storage, database, array not the same and use attribute to apply for cases where one _id will be used across 2 arrays |
| 76 | + if ( |
| 77 | + !el.getAttribute(attribute.name) && |
| 78 | + !el.hasAttribute("skip-attribute") |
| 79 | + ) { |
| 80 | + el.setAttribute(attribute.name, attribute.value); |
| 81 | + } |
| 82 | + } |
| 83 | + } |
| 84 | + } |
84 | 85 | } |
85 | 86 |
|
86 | 87 | /** |
87 | | -* @param element |
88 | | -*/ |
| 88 | + * @param element |
| 89 | + */ |
89 | 90 | function disableAutoFill(element) { |
90 | | - // Clear the text area and set the autocomplete attribute to off. |
91 | | - if (element.tagName == "TEXTAREA") { |
92 | | - element.value = ""; |
93 | | - element.setAttribute("autocomplete", "off"); |
94 | | - } |
95 | | - // Set the autocomplete attribute to off. |
96 | | - if (!element.hasAttribute("autocomplete")) { |
97 | | - element.setAttribute('autocomplete', "off"); |
98 | | - } |
| 91 | + // Clear the text area and set the autocomplete attribute to off. |
| 92 | + if (element.tagName == "TEXTAREA") { |
| 93 | + element.value = ""; |
| 94 | + element.setAttribute("autocomplete", "off"); |
| 95 | + } |
| 96 | + // Set the autocomplete attribute to off. |
| 97 | + if (!element.hasAttribute("autocomplete")) { |
| 98 | + element.setAttribute("autocomplete", "off"); |
| 99 | + } |
99 | 100 | } |
100 | 101 |
|
101 | 102 | /** |
102 | | -* @param form |
103 | | -*/ |
| 103 | + * @param form |
| 104 | + */ |
104 | 105 | function reset(form) { |
105 | | - // Convert the form elements collection to an array |
106 | | - const formElementsArray = Array.from(form.elements); |
107 | | - |
108 | | - // Query for additional elements with [object] or [key] attributes that are not already part of form controls |
109 | | - const customElements = Array.from(form.querySelectorAll('[object], [key]:not(input):not(select):not(textarea):not(button)')); |
110 | | - |
111 | | - // Merge form elements and custom elements using the spread operator |
112 | | - const allElements = [...formElementsArray, ...customElements]; |
113 | | - |
114 | | - // Store the elements and their values in a map for restoration |
115 | | - const elementStates = new Map(); |
116 | | - |
117 | | - // Iterate over all elements and store their current state based on the 'reset' attribute |
118 | | - for (const element of allElements) { |
119 | | - if (['BUTTON', 'FIELDSET'].includes(element.tagName)) |
120 | | - continue |
121 | | - // Get the reset attribute value, if any |
122 | | - const resetType = element.getAttribute('reset'); |
123 | | - if (element.hasAttribute('object') && (!resetType || resetType === 'object')) |
124 | | - element.setAttribute('object', ''); |
125 | | - if (resetType === 'false' || resetType === 'object') |
126 | | - elementStates.set(element, element.getValue() || element.value || element.getAttribute('value')); |
127 | | - if (!resetType || resetType !== 'object') |
128 | | - element.setValue('') |
129 | | - } |
130 | | - |
131 | | - if (form.hasAttribute('object')) |
132 | | - form.setAttribute('object', ''); |
133 | | - |
134 | | - // Perform the default form reset |
135 | | - form.reset(); |
136 | | - |
137 | | - // Restore values based on the 'reset' attribute |
138 | | - elementStates.forEach((value, element) => { |
139 | | - element.setValue(value) |
140 | | - }); |
141 | | - |
142 | | - // Dispatch a custom reset event |
143 | | - document.dispatchEvent(new CustomEvent('reset', { |
144 | | - detail: {} |
145 | | - })); |
| 106 | + // Convert the form elements collection to an array |
| 107 | + const formElementsArray = Array.from(form.elements); |
| 108 | + |
| 109 | + // Query for additional elements with [object] or [key] attributes that are not already part of form controls |
| 110 | + const customElements = Array.from( |
| 111 | + form.querySelectorAll( |
| 112 | + "[object], [key]:not(input):not(select):not(textarea):not(button)" |
| 113 | + ) |
| 114 | + ); |
| 115 | + |
| 116 | + // Merge form elements and custom elements using the spread operator |
| 117 | + const allElements = [...formElementsArray, ...customElements]; |
| 118 | + |
| 119 | + // Store the elements and their values in a map for restoration |
| 120 | + const elementStates = new Map(); |
| 121 | + |
| 122 | + // Iterate over all elements and store their current state based on the 'reset' attribute |
| 123 | + for (const element of allElements) { |
| 124 | + if (["BUTTON", "FIELDSET"].includes(element.tagName)) continue; |
| 125 | + // Get the reset attribute value, if any |
| 126 | + const resetType = element.getAttribute("reset"); |
| 127 | + if ( |
| 128 | + element.hasAttribute("object") && |
| 129 | + (!resetType || resetType === "object") |
| 130 | + ) |
| 131 | + element.setAttribute("object", ""); |
| 132 | + if (resetType === "false" || resetType === "object") |
| 133 | + elementStates.set( |
| 134 | + element, |
| 135 | + element.getValue() || |
| 136 | + element.value || |
| 137 | + element.getAttribute("value") |
| 138 | + ); |
| 139 | + if (!resetType || resetType === "value") element.setValue(""); |
| 140 | + } |
| 141 | + |
| 142 | + if (form.hasAttribute("object")) form.setAttribute("object", ""); |
| 143 | + |
| 144 | + // Perform the default form reset |
| 145 | + form.reset(); |
| 146 | + |
| 147 | + // Restore values based on the 'reset' attribute |
| 148 | + elementStates.forEach((value, element) => { |
| 149 | + element.setValue(value); |
| 150 | + }); |
| 151 | + |
| 152 | + // Dispatch a custom reset event |
| 153 | + document.dispatchEvent( |
| 154 | + new CustomEvent("reset", { |
| 155 | + detail: {} |
| 156 | + }) |
| 157 | + ); |
146 | 158 | } |
147 | 159 |
|
148 | 160 | function setValue(form) { |
149 | | - form.setValue = (value) => { |
150 | | - if (typeof value !== "object") |
151 | | - elementPrototype.setValue(form, value); |
152 | | - else { |
153 | | - const inputs = form.querySelectorAll('[name], [key]'); |
154 | | - inputs.forEach(element => { |
155 | | - const key = element.getAttribute('key') || element.getAttribute('name'); |
156 | | - if (value[key]) { |
157 | | - element.setValue(value[key]); |
158 | | - } |
159 | | - }); |
160 | | - |
161 | | - } |
162 | | - } |
| 161 | + form.setValue = (value) => { |
| 162 | + if (typeof value !== "object") elementPrototype.setValue(form, value); |
| 163 | + else { |
| 164 | + const inputs = form.querySelectorAll("[name], [key]"); |
| 165 | + inputs.forEach((element) => { |
| 166 | + const key = |
| 167 | + element.getAttribute("key") || element.getAttribute("name"); |
| 168 | + if (value[key]) { |
| 169 | + element.setValue(value[key]); |
| 170 | + } |
| 171 | + }); |
| 172 | + } |
| 173 | + }; |
163 | 174 | } |
164 | 175 |
|
165 | 176 | Observer.init({ |
166 | | - name: 'CoCreateForm', |
167 | | - observe: ['addedNodes'], |
168 | | - selector: 'form', |
169 | | - callback: mutation => init(mutation.target) |
| 177 | + name: "CoCreateForm", |
| 178 | + observe: ["addedNodes"], |
| 179 | + selector: "form", |
| 180 | + callback: (mutation) => init(mutation.target) |
170 | 181 | }); |
171 | 182 |
|
172 | 183 | Observer.init({ |
173 | | - name: 'CoCreateForm', |
174 | | - observe: ['attributes'], |
175 | | - attributeName: getAttributeNames(['storage', 'database', 'array', 'object', 'index']), |
176 | | - selector: 'form', |
177 | | - callback: mutation => mutation.target.tagName === "FORM" && |
178 | | - setAttribute(mutation.target) |
| 184 | + name: "CoCreateForm", |
| 185 | + observe: ["attributes"], |
| 186 | + attributeName: getAttributeNames([ |
| 187 | + "storage", |
| 188 | + "database", |
| 189 | + "array", |
| 190 | + "object", |
| 191 | + "index" |
| 192 | + ]), |
| 193 | + selector: "form", |
| 194 | + callback: (mutation) => |
| 195 | + mutation.target.tagName === "FORM" && setAttribute(mutation.target) |
179 | 196 | }); |
180 | 197 |
|
181 | 198 | Action.init({ |
182 | | - name: "reset", |
183 | | - endEvent: "reset", |
184 | | - callback: (action) => { |
185 | | - if (action.form) |
186 | | - reset(action.form); |
187 | | - } |
| 199 | + name: "reset", |
| 200 | + endEvent: "reset", |
| 201 | + callback: (action) => { |
| 202 | + if (action.form) reset(action.form); |
| 203 | + } |
188 | 204 | }); |
189 | 205 |
|
190 | 206 | init(); |
|
0 commit comments