@cocreate/elements 1.37.1 → 1.38.1
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/CHANGELOG.md +21 -0
- package/docs/index.html +330 -328
- package/package.json +1 -1
- package/prettier.config.js +16 -0
- package/src/form.js +166 -150
- package/src/index.js +1392 -1295
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cocreate/elements",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.38.1",
|
|
4
4
|
"description": "Fetch content into any html element by using html5 attributes to query data stored in CoCreate headless CMS. If data is changed it will instantly reflect in html tags as changes are broadcasted in realtime",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"elements",
|
package/src/form.js
CHANGED
|
@@ -1,190 +1,206 @@
|
|
|
1
|
-
import Observer from
|
|
2
|
-
import { getAttributeNames, ObjectId } from
|
|
3
|
-
import Action from
|
|
4
|
-
import elementPrototype from
|
|
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
|
-
|
|
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
|
-
}
|
|
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
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
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
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
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
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
177
|
+
name: "CoCreateForm",
|
|
178
|
+
observe: ["addedNodes"],
|
|
179
|
+
selector: "form",
|
|
180
|
+
callback: (mutation) => init(mutation.target)
|
|
170
181
|
});
|
|
171
182
|
|
|
172
183
|
Observer.init({
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
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
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
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();
|