@appius-fr/apx 2.5.2 → 2.6.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.
@@ -0,0 +1,315 @@
1
+ # APX Tools: Form Packer
2
+
3
+ The `form-packer` module provides utilities for converting HTML forms into structured JSON objects. It handles complex form structures including nested objects, arrays, numeric indices, and mixed structures.
4
+
5
+ ---
6
+
7
+ ## Installation
8
+
9
+ The `form-packer` module is automatically included when you import APX. It provides both a direct API and an APX object method.
10
+
11
+ ```javascript
12
+ import APX from './APX.mjs';
13
+ // APX.tools.packFormToJSON() and APX('form').pack() are now available
14
+ ```
15
+
16
+ ---
17
+
18
+ ## Usage
19
+
20
+ ### Method 1: Direct API
21
+
22
+ ```javascript
23
+ const form = document.querySelector('#myForm');
24
+ const data = APX.tools.packFormToJSON(form);
25
+ console.log(data);
26
+ ```
27
+
28
+ ### Method 2: APX Object Method (Recommended)
29
+
30
+ ```javascript
31
+ // Using APX selector
32
+ const data = APX('form#myForm').pack();
33
+ const data2 = APX('form.myformclass').pack();
34
+ ```
35
+
36
+ ---
37
+
38
+ ## Features
39
+
40
+ ### Nested Objects
41
+
42
+ Use bracket notation to create nested objects:
43
+
44
+ ```html
45
+ <input name="user[name]" value="John">
46
+ <input name="user[email]" value="john@example.com">
47
+ <input name="user[profile][age]" value="30">
48
+ ```
49
+
50
+ **Result:**
51
+ ```json
52
+ {
53
+ "user": {
54
+ "name": "John",
55
+ "email": "john@example.com",
56
+ "profile": {
57
+ "age": "30"
58
+ }
59
+ }
60
+ }
61
+ ```
62
+
63
+ ### Arrays
64
+
65
+ Use `[]` notation to create arrays:
66
+
67
+ ```html
68
+ <input name="tags[]" value="javascript">
69
+ <input name="tags[]" value="html">
70
+ <input name="tags[]" value="css">
71
+ ```
72
+
73
+ **Result:**
74
+ ```json
75
+ {
76
+ "tags": ["javascript", "html", "css"]
77
+ }
78
+ ```
79
+
80
+ ### Numeric Indices
81
+
82
+ Use numeric indices to create arrays with specific positions:
83
+
84
+ ```html
85
+ <input name="items[0][name]" value="Item 1">
86
+ <input name="items[0][price]" value="10">
87
+ <input name="items[1][name]" value="Item 2">
88
+ <input name="items[1][price]" value="20">
89
+ ```
90
+
91
+ **Result:**
92
+ ```json
93
+ {
94
+ "items": [
95
+ { "name": "Item 1", "price": "10" },
96
+ { "name": "Item 2", "price": "20" }
97
+ ]
98
+ }
99
+ ```
100
+
101
+ ### Mixed Structures
102
+
103
+ The module intelligently handles mixed structures (objects with both numeric and string keys):
104
+
105
+ ```html
106
+ <input name="data[type]" value="product">
107
+ <input name="data[0][name]" value="Item 1">
108
+ <input name="data[1][name]" value="Item 2">
109
+ ```
110
+
111
+ **Result:**
112
+ ```json
113
+ {
114
+ "data": {
115
+ "type": "product",
116
+ "0": { "name": "Item 1" },
117
+ "1": { "name": "Item 2" }
118
+ }
119
+ }
120
+ ```
121
+
122
+ ---
123
+
124
+ ## API
125
+
126
+ ### `APX.tools.packFormToJSON(form)`
127
+
128
+ Converts an HTML form element into a JSON object.
129
+
130
+ **Parameters:**
131
+ - `form` (HTMLFormElement): The form element to convert
132
+
133
+ **Returns:** (Object) The JSON object representation of the form data
134
+
135
+ **Throws:** (TypeError) If `form` is not an `HTMLFormElement`
136
+
137
+ **Example:**
138
+ ```javascript
139
+ const form = document.querySelector('#myForm');
140
+ try {
141
+ const data = APX.tools.packFormToJSON(form);
142
+ console.log(data);
143
+ } catch (error) {
144
+ console.error('Error:', error.message);
145
+ }
146
+ ```
147
+
148
+ ### `APX('form').pack()`
149
+
150
+ Converts the first selected form element into a JSON object. This is a chainable method on APX objects.
151
+
152
+ **Returns:** (Object) The JSON object representation of the form data
153
+
154
+ **Throws:** (Error) If no element is found or the first element is not a form
155
+
156
+ **Example:**
157
+ ```javascript
158
+ try {
159
+ const data = APX('form#myForm').pack();
160
+ console.log(data);
161
+ } catch (error) {
162
+ console.error('Error:', error.message);
163
+ }
164
+ ```
165
+
166
+ ---
167
+
168
+ ## Advanced Features
169
+
170
+ ### Conflict Detection
171
+
172
+ The module automatically detects incompatible form structures and throws descriptive errors:
173
+
174
+ ```html
175
+ <!-- This will throw an error -->
176
+ <input name="items[0]" value="primitive value">
177
+ <input name="items[0][nested][value]" value="nested value">
178
+ ```
179
+
180
+ **Error:** `Path conflict: "items[0]" is used as a final value, but "items[0][nested][value]" tries to use it as an intermediate path.`
181
+
182
+ ### Two-Phase Processing
183
+
184
+ The module uses a two-phase processing architecture:
185
+
186
+ 1. **Analysis Phase**: Analyzes all form fields to detect conflicts and structure requirements
187
+ 2. **Processing Phase**: Builds the JSON object with intelligent type conversion
188
+
189
+ This ensures correct handling of complex structures and prevents data loss.
190
+
191
+ ### ES6+ Best Practices
192
+
193
+ The module is built with modern JavaScript:
194
+ - Arrow functions
195
+ - Destructuring
196
+ - Optional chaining (`?.`)
197
+ - Nullish coalescing (`??`)
198
+ - `for...of` loops
199
+ - `Number.parseInt` / `Number.isNaN`
200
+ - `reduce()` for transformations
201
+
202
+ ---
203
+
204
+ ## Examples
205
+
206
+ ### Complex Form Example
207
+
208
+ ```html
209
+ <form id="userForm">
210
+ <input name="name" value="John Doe">
211
+ <input name="email" value="john@example.com">
212
+
213
+ <input name="address[street]" value="123 Main St">
214
+ <input name="address[city]" value="New York">
215
+ <input name="address[zip]" value="10001">
216
+
217
+ <input name="tags[]" value="developer">
218
+ <input name="tags[]" value="designer">
219
+
220
+ <input name="items[0][name]" value="Laptop">
221
+ <input name="items[0][price]" value="999">
222
+ <input name="items[1][name]" value="Mouse">
223
+ <input name="items[1][price]" value="29">
224
+ </form>
225
+ ```
226
+
227
+ ```javascript
228
+ const data = APX('form#userForm').pack();
229
+ ```
230
+
231
+ **Result:**
232
+ ```json
233
+ {
234
+ "name": "John Doe",
235
+ "email": "john@example.com",
236
+ "address": {
237
+ "street": "123 Main St",
238
+ "city": "New York",
239
+ "zip": "10001"
240
+ },
241
+ "tags": ["developer", "designer"],
242
+ "items": [
243
+ { "name": "Laptop", "price": "999" },
244
+ { "name": "Mouse", "price": "29" }
245
+ ]
246
+ }
247
+ ```
248
+
249
+ ### Multiple Values
250
+
251
+ If multiple inputs share the same name (without brackets), they are automatically converted to an array:
252
+
253
+ ```html
254
+ <input name="color" value="red">
255
+ <input name="color" value="blue">
256
+ <input name="color" value="green">
257
+ ```
258
+
259
+ **Result:**
260
+ ```json
261
+ {
262
+ "color": ["red", "blue", "green"]
263
+ }
264
+ ```
265
+
266
+ ---
267
+
268
+ ## Supported Input Types
269
+
270
+ The module supports all standard HTML form input types:
271
+ - `text`, `email`, `password`, `number`, `tel`, `url`, `search`
272
+ - `checkbox`, `radio`
273
+ - `select` (single and multiple)
274
+ - `textarea`
275
+ - `hidden`
276
+ - Custom input types
277
+
278
+ ---
279
+
280
+ ## Error Handling
281
+
282
+ The module provides clear error messages for common issues:
283
+
284
+ - **Invalid input**: `TypeError: packFormToJSON expects an HTMLFormElement`
285
+ - **No element found**: `Error: No element found` (when using `.pack()`)
286
+ - **Not a form**: `Error: Element is not a form` (when using `.pack()`)
287
+ - **Path conflicts**: Descriptive error messages indicating the conflicting paths
288
+
289
+ ---
290
+
291
+ ## Demo
292
+
293
+ See the interactive demo at `demo/modules/tools/index.html` for:
294
+ - Live form examples
295
+ - Dynamic form generation
296
+ - JSON output visualization
297
+ - Form-to-JSON validation tool
298
+
299
+ ---
300
+
301
+ ## Notes
302
+
303
+ - Empty form fields are included in the result (with empty string values)
304
+ - Checkboxes and radio buttons use their `value` attribute (or `"on"` if no value)
305
+ - Multiple select elements create arrays automatically
306
+ - The module handles edge cases like empty keys, mixed structures, and numeric indices
307
+ - All conversions preserve the original form structure as much as possible
308
+
309
+ ---
310
+
311
+ ## License
312
+
313
+ Author : Thibault SAELEN
314
+ Copyright Appius SARL.
315
+
@@ -0,0 +1,30 @@
1
+ import { packFormToJSON } from './packToJson.mjs';
2
+
3
+ /**
4
+ * Ajoute la méthode pack() aux objets APX pour convertir les formulaires en JSON
5
+ * @param {Object} apx - L'objet APX à augmenter
6
+ * @returns {Object} L'objet APX augmenté
7
+ */
8
+ export default function (apx) {
9
+ /**
10
+ * Convertit le premier formulaire sélectionné en objet JSON
11
+ * @returns {Object} L'objet JSON résultant
12
+ * @throws {Error} Si aucun formulaire n'est trouvé ou si le premier élément n'est pas un formulaire
13
+ * @example
14
+ * const data = APX('form.myformclass').pack();
15
+ */
16
+ apx.pack = function () {
17
+ const firstElement = this.first();
18
+ if (!firstElement) {
19
+ throw new Error('No element found');
20
+ }
21
+ if (firstElement.tagName !== 'FORM') {
22
+ throw new Error('Element is not a form');
23
+ }
24
+ return packFormToJSON(firstElement);
25
+ };
26
+
27
+ return apx;
28
+ }
29
+
30
+