formique 1.0.1 → 1.0.3
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 +624 -0
- package/package.json +6 -5
- package/formique.js +0 -2939
package/formique.js
DELETED
|
@@ -1,2939 +0,0 @@
|
|
|
1
|
-
import pretty from 'pretty';
|
|
2
|
-
|
|
3
|
-
// Base class for form rendering
|
|
4
|
-
class FormBuilder
|
|
5
|
-
{
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
renderField(type, name, label, validate, attributes, bindingSyntax, options) {
|
|
9
|
-
throw new Error('Method renderField must be implemented');
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
// Extended class for specific form rendering methods
|
|
20
|
-
class Formique extends FormBuilder {
|
|
21
|
-
|
|
22
|
-
constructor (formParams = {}, formSchema) {
|
|
23
|
-
super();
|
|
24
|
-
this.formSchema=formSchema;
|
|
25
|
-
this.divClass='input-block';
|
|
26
|
-
this.inputClass='form-input';
|
|
27
|
-
this.radioGroupClass='radio-group';
|
|
28
|
-
this.checkboxGroupClass='checkbox-group';
|
|
29
|
-
this.selectGroupClass='form-select';
|
|
30
|
-
this.formParams=formParams;
|
|
31
|
-
this.formMarkUp='';
|
|
32
|
-
|
|
33
|
-
if (this.formParams) {
|
|
34
|
-
this.formMarkUp += this.renderFormElement();
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
this.renderForm();
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
// renderFormElement method
|
|
46
|
-
renderFormElement() {
|
|
47
|
-
let formHTML = '<form\n';
|
|
48
|
-
// Use this.formParams directly
|
|
49
|
-
const paramsToUse = this.formParams || {};
|
|
50
|
-
|
|
51
|
-
// Dynamically add attributes if they are present in the parameters
|
|
52
|
-
for (const [key, value] of Object.entries(paramsToUse)) {
|
|
53
|
-
if (value !== undefined && value !== null) {
|
|
54
|
-
// Handle boolean attributes
|
|
55
|
-
if (typeof value === 'boolean') {
|
|
56
|
-
if (value) {
|
|
57
|
-
formHTML += ` ${key}\n`;
|
|
58
|
-
}
|
|
59
|
-
} else {
|
|
60
|
-
// Handle other attributes
|
|
61
|
-
const formattedKey = key === 'accept_charset' ? 'accept-charset' : key.replace(/_/g, '-');
|
|
62
|
-
formHTML += ` ${formattedKey}="${value}"\n`;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Close the <form> tag
|
|
68
|
-
formHTML += '>\n';
|
|
69
|
-
|
|
70
|
-
// Manually ensure vertical formatting of the HTML string
|
|
71
|
-
formHTML = formHTML.replace(/\n\s*$/, '\n'); // Remove trailing whitespace/newline if necessary
|
|
72
|
-
return formHTML;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
// Main renderForm method
|
|
77
|
-
renderForm() {
|
|
78
|
-
// Process each field synchronously
|
|
79
|
-
const formHTML = this.formSchema.map(field => {
|
|
80
|
-
const [type, name, label, validate, attributes = {}, bindingSyntax, options] = field;
|
|
81
|
-
return this.renderField(type, name, label, validate, attributes, bindingSyntax, options);
|
|
82
|
-
}).join('');
|
|
83
|
-
|
|
84
|
-
//return formHTML;
|
|
85
|
-
//return this.formMarkUp;
|
|
86
|
-
|
|
87
|
-
this.formMarkUp += formHTML;
|
|
88
|
-
//console.log("here", this.formMarkUp);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
renderField(type, name, label, validate, attributes, bindingSyntax, options) {
|
|
93
|
-
switch (type) {
|
|
94
|
-
case 'text':
|
|
95
|
-
return this.renderTextField(type, name, label, validate, attributes, bindingSyntax);
|
|
96
|
-
case 'email':
|
|
97
|
-
return this.renderEmailField(type, name, label, validate, attributes, bindingSyntax);
|
|
98
|
-
case 'number':
|
|
99
|
-
return this.renderNumberField(type, name, label, validate, attributes, bindingSyntax);
|
|
100
|
-
case 'password':
|
|
101
|
-
return this.renderPasswordField(type, name, label, validate, attributes, bindingSyntax);
|
|
102
|
-
case 'tel': // New case for tel field
|
|
103
|
-
return this.renderTelField(type, name, label, validate, attributes, bindingSyntax);
|
|
104
|
-
case 'date':
|
|
105
|
-
return this.renderDateField(type, name, label, validate, attributes, bindingSyntax);
|
|
106
|
-
case 'time':
|
|
107
|
-
return this.renderTimeField(type, name, label, validate, attributes, bindingSyntax);
|
|
108
|
-
case 'datetime-local':
|
|
109
|
-
return this.renderDateTimeField(type, name, label, validate, attributes, bindingSyntax);
|
|
110
|
-
case 'month':
|
|
111
|
-
return this.renderMonthField(type, name, label, validate, attributes, bindingSyntax);
|
|
112
|
-
case 'week':
|
|
113
|
-
return this.renderWeekField(type, name, label, validate, attributes, bindingSyntax);
|
|
114
|
-
case 'url':
|
|
115
|
-
return this.renderUrlField(type, name, label, validate, attributes, bindingSyntax);
|
|
116
|
-
case 'search':
|
|
117
|
-
return this.renderSearchField(type, name, label, validate, attributes, bindingSyntax);
|
|
118
|
-
case 'color':
|
|
119
|
-
return this.renderColorField(type, name, label, validate, attributes, bindingSyntax);
|
|
120
|
-
case 'checkbox':
|
|
121
|
-
return this.renderCheckboxField(type, name, label, validate, attributes, bindingSyntax, options);
|
|
122
|
-
case 'radio':
|
|
123
|
-
return this.renderRadioField(type, name, label, validate, attributes, bindingSyntax, options);
|
|
124
|
-
case 'file':
|
|
125
|
-
return this.renderFileField(type, name, label, validate, attributes, bindingSyntax);
|
|
126
|
-
case 'hidden':
|
|
127
|
-
return this.renderHiddenField(type, name, label, validate, attributes, bindingSyntax);
|
|
128
|
-
case 'image':
|
|
129
|
-
return this.renderImageField(type, name, label, validate, attributes, bindingSyntax);
|
|
130
|
-
case 'textarea':
|
|
131
|
-
return this.renderTextareaField(type, name, label, validate, attributes, bindingSyntax);
|
|
132
|
-
case 'singleSelect':
|
|
133
|
-
return this.renderSingleSelectField(type, name, label, validate, attributes, bindingSyntax, options);
|
|
134
|
-
case 'multipleSelect':
|
|
135
|
-
return this.renderMultipleSelectField(type, name, label, validate, attributes, bindingSyntax, options);
|
|
136
|
-
case 'submit':
|
|
137
|
-
return this.renderSubmitButton(type, name, label, attributes);
|
|
138
|
-
default:
|
|
139
|
-
console.warn(`Unsupported field type '${type}' encountered.`);
|
|
140
|
-
return ''; // or handle gracefully
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
// Specific rendering methods for each field type
|
|
152
|
-
renderTextField(type, name, label, validate, attributes, bindingSyntax) {
|
|
153
|
-
|
|
154
|
-
//console.log("here");
|
|
155
|
-
// Define valid attributes for different input types
|
|
156
|
-
const textInputAttributes = [
|
|
157
|
-
'required',
|
|
158
|
-
'minlength',
|
|
159
|
-
'maxlength',
|
|
160
|
-
'pattern',
|
|
161
|
-
'placeholder',
|
|
162
|
-
'readonly',
|
|
163
|
-
'disabled',
|
|
164
|
-
'size',
|
|
165
|
-
'autocomplete',
|
|
166
|
-
'spellcheck',
|
|
167
|
-
'inputmode',
|
|
168
|
-
'title',
|
|
169
|
-
];
|
|
170
|
-
|
|
171
|
-
// Construct validation attributes
|
|
172
|
-
let validationAttrs = '';
|
|
173
|
-
if (validate) {
|
|
174
|
-
Object.entries(validate).forEach(([key, value]) => {
|
|
175
|
-
if (textInputAttributes.includes(key)) {
|
|
176
|
-
if (typeof value === 'boolean' && value) {
|
|
177
|
-
validationAttrs += ` ${key}\n`;
|
|
178
|
-
} else {
|
|
179
|
-
switch (key) {
|
|
180
|
-
case 'minlength':
|
|
181
|
-
case 'maxlength':
|
|
182
|
-
validationAttrs += ` ${key}="${value}"\n`;
|
|
183
|
-
break;
|
|
184
|
-
default:
|
|
185
|
-
if (!numberInputAttributes.includes(key)) {
|
|
186
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type 'number'.\x1b[0m`);
|
|
187
|
-
}
|
|
188
|
-
break;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
} else {
|
|
192
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type 'text'.\x1b[0m`);
|
|
193
|
-
}
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
// Handle the binding syntax
|
|
198
|
-
let bindingDirective = '';
|
|
199
|
-
if (bindingSyntax === 'bind:value' && name) {
|
|
200
|
-
bindingDirective = ` bind:value="${name}"\n`;
|
|
201
|
-
}
|
|
202
|
-
if (bindingSyntax.startsWith('::') && name) {
|
|
203
|
-
bindingDirective = ` bind:value="${name}"\n`;
|
|
204
|
-
}
|
|
205
|
-
if (bindingSyntax && !name) {
|
|
206
|
-
console.log(`\x1b[31m%s\x1b[0m`, `You cannot set binding value when there is no name attribute defined in ${name} ${type} field.`);
|
|
207
|
-
return;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
// Get the id from attributes or fall back to name
|
|
212
|
-
let id = attributes.id || name;
|
|
213
|
-
|
|
214
|
-
// Determine if semantiq is true based on formParams
|
|
215
|
-
const semantq = this.formParams?.semantq || false;
|
|
216
|
-
|
|
217
|
-
// Construct additional attributes dynamically
|
|
218
|
-
let additionalAttrs = '';
|
|
219
|
-
for (const [key, value] of Object.entries(attributes)) {
|
|
220
|
-
if (key !== 'id' && value !== undefined) {
|
|
221
|
-
if (key.startsWith('on')) {
|
|
222
|
-
// Handle event attributes
|
|
223
|
-
if (semantq) {
|
|
224
|
-
const eventValue = value.endsWith('()') ? value.slice(0, -2) : value;
|
|
225
|
-
additionalAttrs += ` @${key.replace(/^on/, '')}={${eventValue}}\n`;
|
|
226
|
-
} else {
|
|
227
|
-
// Add parentheses if not present
|
|
228
|
-
const eventValue = value.endsWith('()') ? value : `${value}()`;
|
|
229
|
-
additionalAttrs += ` ${key}="${eventValue}"\n`;
|
|
230
|
-
}
|
|
231
|
-
} else {
|
|
232
|
-
// Handle boolean attributes
|
|
233
|
-
if (value === true) {
|
|
234
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}\n`;
|
|
235
|
-
} else if (value !== false) {
|
|
236
|
-
// Convert underscores to hyphens and set the attribute
|
|
237
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}="${value}"\n`;
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
// Construct the final HTML string
|
|
244
|
-
let formHTML = `
|
|
245
|
-
<div class="${this.divClass}">
|
|
246
|
-
<label for="${id}">${label}</label>
|
|
247
|
-
<input
|
|
248
|
-
type="${type}"
|
|
249
|
-
name="${name}"
|
|
250
|
-
${bindingDirective}
|
|
251
|
-
id="${id}"
|
|
252
|
-
${additionalAttrs}
|
|
253
|
-
${validationAttrs}
|
|
254
|
-
/>
|
|
255
|
-
</div>
|
|
256
|
-
`.replace(/^\s*\n/gm, '').trim();
|
|
257
|
-
|
|
258
|
-
// Format the entire HTML using pretty
|
|
259
|
-
let formattedHtml = pretty(formHTML, {
|
|
260
|
-
indent_size: 2,
|
|
261
|
-
wrap_line_length: 0,
|
|
262
|
-
preserve_newlines: true, // Preserve existing newlines
|
|
263
|
-
});
|
|
264
|
-
|
|
265
|
-
// Apply vertical layout to the <input> element only
|
|
266
|
-
formattedHtml = formattedHtml.replace(/<input\s+([^>]*)\/>/, (match, p1) => {
|
|
267
|
-
// Reformat attributes into a vertical layout
|
|
268
|
-
const attributes = p1.trim().split(/\s+/).map(attr => ` ${attr}`).join('\n');
|
|
269
|
-
return `<input\n${attributes}\n/>`;
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
// Ensure the <div> block starts on a new line
|
|
273
|
-
/*
|
|
274
|
-
formattedHtml = formattedHtml.replace(/<div\s+([^>]*)>/, (match) => {
|
|
275
|
-
// Ensure <div> starts on a new line
|
|
276
|
-
return `\n${match}\n`;
|
|
277
|
-
});
|
|
278
|
-
*/
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
//this.formMarkUp += formattedHtml;
|
|
282
|
-
//console.log("HR",this.formMarkUp);
|
|
283
|
-
return formattedHtml;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
// Specific rendering methods for each field type
|
|
290
|
-
renderEmailField(type, name, label, validate, attributes, bindingSyntax) {
|
|
291
|
-
// Define valid attributes for the email input type
|
|
292
|
-
const emailInputAttributes = [
|
|
293
|
-
'required',
|
|
294
|
-
'minlength',
|
|
295
|
-
'maxlength',
|
|
296
|
-
'pattern',
|
|
297
|
-
'placeholder',
|
|
298
|
-
'readonly',
|
|
299
|
-
'disabled',
|
|
300
|
-
'size',
|
|
301
|
-
'autocomplete',
|
|
302
|
-
'spellcheck',
|
|
303
|
-
'inputmode',
|
|
304
|
-
'title',
|
|
305
|
-
];
|
|
306
|
-
|
|
307
|
-
// Construct validation attributes
|
|
308
|
-
let validationAttrs = '';
|
|
309
|
-
if (validate) {
|
|
310
|
-
Object.entries(validate).forEach(([key, value]) => {
|
|
311
|
-
if (emailInputAttributes.includes(key)) {
|
|
312
|
-
if (typeof value === 'boolean' && value) {
|
|
313
|
-
validationAttrs += ` ${key}\n`;
|
|
314
|
-
} else {
|
|
315
|
-
switch (key) {
|
|
316
|
-
case 'minlength':
|
|
317
|
-
case 'maxlength':
|
|
318
|
-
validationAttrs += ` ${key}="${value}"\n`;
|
|
319
|
-
break;
|
|
320
|
-
case 'pattern':
|
|
321
|
-
validationAttrs += ` ${key}="${value}"\n`;
|
|
322
|
-
break;
|
|
323
|
-
default:
|
|
324
|
-
if (!numberInputAttributes.includes(key)) {
|
|
325
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type 'number'.\x1b[0m`);
|
|
326
|
-
}
|
|
327
|
-
break;
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
} else {
|
|
331
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type 'email'.\x1b[0m`);
|
|
332
|
-
}
|
|
333
|
-
});
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
// Handle the binding syntax
|
|
337
|
-
let bindingDirective = '';
|
|
338
|
-
if (bindingSyntax === 'bind:value' && name) {
|
|
339
|
-
bindingDirective = ` bind:value="${name}"\n`;
|
|
340
|
-
}
|
|
341
|
-
if (bindingSyntax.startsWith('::') && name) {
|
|
342
|
-
bindingDirective = ` bind:value="${name}"\n`;
|
|
343
|
-
}
|
|
344
|
-
if (bindingSyntax && !name) {
|
|
345
|
-
console.log(`\x1b[31m%s\x1b[0m`, `You cannot set binding value when there is no name attribute defined in ${name} ${type} field.`);
|
|
346
|
-
return;
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
// Get the id from attributes or fall back to name
|
|
350
|
-
let id = attributes.id || name;
|
|
351
|
-
|
|
352
|
-
// Construct additional attributes dynamically
|
|
353
|
-
let additionalAttrs = '';
|
|
354
|
-
for (const [key, value] of Object.entries(attributes)) {
|
|
355
|
-
if (key !== 'id' && value !== undefined) {
|
|
356
|
-
if (key.startsWith('on')) {
|
|
357
|
-
// Handle event attributes
|
|
358
|
-
const eventValue = value.endsWith('()') ? value.slice(0, -2) : value;
|
|
359
|
-
additionalAttrs += ` @${key.replace(/^on/, '')}={${eventValue}}\n`;
|
|
360
|
-
} else {
|
|
361
|
-
// Handle boolean attributes
|
|
362
|
-
if (value === true) {
|
|
363
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}\n`;
|
|
364
|
-
} else if (value !== false) {
|
|
365
|
-
// Convert underscores to hyphens and set the attribute
|
|
366
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}="${value}"\n`;
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
// Construct the final HTML string
|
|
373
|
-
let formHTML = `
|
|
374
|
-
<div class="${this.divClass}">
|
|
375
|
-
<label for="${id}">${label}</label>
|
|
376
|
-
<input
|
|
377
|
-
type="${type}"
|
|
378
|
-
name="${name}"
|
|
379
|
-
${bindingDirective}
|
|
380
|
-
id="${id}"
|
|
381
|
-
${additionalAttrs}
|
|
382
|
-
${validationAttrs}
|
|
383
|
-
/>
|
|
384
|
-
</div>
|
|
385
|
-
`.replace(/^\s*\n/gm, '').trim();
|
|
386
|
-
|
|
387
|
-
// Format the entire HTML using pretty
|
|
388
|
-
let formattedHtml = pretty(formHTML, {
|
|
389
|
-
indent_size: 2,
|
|
390
|
-
wrap_line_length: 0,
|
|
391
|
-
preserve_newlines: true, // Preserve existing newlines
|
|
392
|
-
});
|
|
393
|
-
|
|
394
|
-
// Apply vertical layout to the <input> element only
|
|
395
|
-
formattedHtml = formattedHtml.replace(/<input\s+([^>]*)\/>/, (match, p1) => {
|
|
396
|
-
// Reformat attributes into a vertical layout
|
|
397
|
-
const attributes = p1.trim().split(/\s+/).map(attr => ` ${attr}`).join('\n');
|
|
398
|
-
return `<input\n${attributes}\n/>`;
|
|
399
|
-
});
|
|
400
|
-
|
|
401
|
-
// Ensure the <div> block starts on a new line and remove extra blank lines
|
|
402
|
-
|
|
403
|
-
formattedHtml = formattedHtml.replace(/(<div\s+[^>]*>)/g, (match) => {
|
|
404
|
-
// Ensure <div> starts on a new line
|
|
405
|
-
return `\n${match}\n`;
|
|
406
|
-
}).replace(/\n\s*\n/g, '\n'); // Remove extra blank lines
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
//this.formMarkUp += formattedHtml;
|
|
410
|
-
|
|
411
|
-
return formattedHtml;
|
|
412
|
-
//return this.formMarkUp;
|
|
413
|
-
//console.log(this.formMarkUp);
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
renderNumberField(type, name, label, validate, attributes, bindingSyntax) {
|
|
419
|
-
// Define valid attributes for the number input type
|
|
420
|
-
const numberInputAttributes = [
|
|
421
|
-
'required',
|
|
422
|
-
'min',
|
|
423
|
-
'max',
|
|
424
|
-
'step',
|
|
425
|
-
'placeholder',
|
|
426
|
-
'readonly',
|
|
427
|
-
'disabled',
|
|
428
|
-
'size',
|
|
429
|
-
'autocomplete',
|
|
430
|
-
'inputmode',
|
|
431
|
-
'title',
|
|
432
|
-
];
|
|
433
|
-
|
|
434
|
-
// Construct validation attributes
|
|
435
|
-
let validationAttrs = '';
|
|
436
|
-
if (validate) {
|
|
437
|
-
Object.entries(validate).forEach(([key, value]) => {
|
|
438
|
-
if (numberInputAttributes.includes(key)) {
|
|
439
|
-
if (typeof value === 'boolean' && value) {
|
|
440
|
-
validationAttrs += ` ${key}\n`;
|
|
441
|
-
} else {
|
|
442
|
-
switch (key) {
|
|
443
|
-
case 'min':
|
|
444
|
-
case 'max':
|
|
445
|
-
validationAttrs += ` ${key}="${value}"\n`;
|
|
446
|
-
break;
|
|
447
|
-
case 'step':
|
|
448
|
-
validationAttrs += ` ${key}="${value}"\n`;
|
|
449
|
-
break;
|
|
450
|
-
default:
|
|
451
|
-
if (!numberInputAttributes.includes(key)) {
|
|
452
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type 'number'.\x1b[0m`);
|
|
453
|
-
}
|
|
454
|
-
break;
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
} else {
|
|
458
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type 'number'.\x1b[0m`);
|
|
459
|
-
}
|
|
460
|
-
});
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
// Handle the binding syntax
|
|
464
|
-
let bindingDirective = '';
|
|
465
|
-
if (bindingSyntax === 'bind:value' && name) {
|
|
466
|
-
bindingDirective = ` bind:value="${name}"\n`;
|
|
467
|
-
}
|
|
468
|
-
if (bindingSyntax.startsWith('::') && name) {
|
|
469
|
-
bindingDirective = ` bind:value="${name}"\n`;
|
|
470
|
-
}
|
|
471
|
-
if (bindingSyntax && !name) {
|
|
472
|
-
console.log(`\x1b[31m%s\x1b[0m`, `You cannot set binding value when there is no name attribute defined in ${name} ${type} field.`);
|
|
473
|
-
return;
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
// Get the id from attributes or fall back to name
|
|
478
|
-
let id = attributes.id || name;
|
|
479
|
-
|
|
480
|
-
// Construct additional attributes dynamically
|
|
481
|
-
let additionalAttrs = '';
|
|
482
|
-
for (const [key, value] of Object.entries(attributes)) {
|
|
483
|
-
if (key !== 'id' && value !== undefined) {
|
|
484
|
-
if (key.startsWith('on')) {
|
|
485
|
-
// Handle event attributes
|
|
486
|
-
const eventValue = value.endsWith('()') ? value.slice(0, -2) : value;
|
|
487
|
-
additionalAttrs += ` @${key.replace(/^on/, '')}={${eventValue}}\n`;
|
|
488
|
-
} else {
|
|
489
|
-
// Handle boolean attributes
|
|
490
|
-
if (value === true) {
|
|
491
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}\n`;
|
|
492
|
-
} else if (value !== false) {
|
|
493
|
-
// Convert underscores to hyphens and set the attribute
|
|
494
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}="${value}"\n`;
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
// Construct the final HTML string
|
|
501
|
-
let formHTML = `
|
|
502
|
-
<div class="${this.divClass}">
|
|
503
|
-
<label for="${id}">${label}</label>
|
|
504
|
-
<input
|
|
505
|
-
type="${type}"
|
|
506
|
-
name="${name}"
|
|
507
|
-
${bindingDirective}
|
|
508
|
-
id="${id}"
|
|
509
|
-
${additionalAttrs}
|
|
510
|
-
${validationAttrs}
|
|
511
|
-
/>
|
|
512
|
-
</div>
|
|
513
|
-
`.replace(/^\s*\n/gm, '').trim();
|
|
514
|
-
|
|
515
|
-
// Format the entire HTML using pretty
|
|
516
|
-
let formattedHtml = pretty(formHTML, {
|
|
517
|
-
indent_size: 2,
|
|
518
|
-
wrap_line_length: 0,
|
|
519
|
-
preserve_newlines: true, // Preserve existing newlines
|
|
520
|
-
});
|
|
521
|
-
|
|
522
|
-
// Apply vertical layout to the <input> element only
|
|
523
|
-
formattedHtml = formattedHtml.replace(/<input\s+([^>]*)\/>/, (match, p1) => {
|
|
524
|
-
// Reformat attributes into a vertical layout
|
|
525
|
-
const attributes = p1.trim().split(/\s+/).map(attr => ` ${attr}`).join('\n');
|
|
526
|
-
return `<input\n${attributes}\n/>`;
|
|
527
|
-
});
|
|
528
|
-
|
|
529
|
-
// Ensure the <div> block starts on a new line and remove extra blank lines
|
|
530
|
-
formattedHtml = formattedHtml.replace(/(<div\s+[^>]*>)/g, (match) => {
|
|
531
|
-
// Ensure <div> starts on a new line
|
|
532
|
-
return `\n${match}\n`;
|
|
533
|
-
}).replace(/\n\s*\n/g, '\n'); // Remove extra blank lines
|
|
534
|
-
|
|
535
|
-
return formattedHtml;
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
// New method for rendering password fields
|
|
541
|
-
renderPasswordField(type, name, label, validate, attributes, bindingSyntax) {
|
|
542
|
-
// Define valid attributes for the password input type
|
|
543
|
-
const passwordInputAttributes = [
|
|
544
|
-
'required',
|
|
545
|
-
'minlength',
|
|
546
|
-
'maxlength',
|
|
547
|
-
'pattern',
|
|
548
|
-
'placeholder',
|
|
549
|
-
'readonly',
|
|
550
|
-
'disabled',
|
|
551
|
-
'size',
|
|
552
|
-
'autocomplete',
|
|
553
|
-
'spellcheck',
|
|
554
|
-
'inputmode',
|
|
555
|
-
'title',
|
|
556
|
-
];
|
|
557
|
-
|
|
558
|
-
// Construct validation attributes
|
|
559
|
-
let validationAttrs = '';
|
|
560
|
-
if (validate) {
|
|
561
|
-
Object.entries(validate).forEach(([key, value]) => {
|
|
562
|
-
if (passwordInputAttributes.includes(key)) {
|
|
563
|
-
if (typeof value === 'boolean' && value) {
|
|
564
|
-
validationAttrs += ` ${key}\n`;
|
|
565
|
-
} else {
|
|
566
|
-
switch (key) {
|
|
567
|
-
case 'minlength':
|
|
568
|
-
case 'maxlength':
|
|
569
|
-
case 'pattern':
|
|
570
|
-
validationAttrs += ` ${key}="${value}"\n`;
|
|
571
|
-
break;
|
|
572
|
-
default:
|
|
573
|
-
if (!passwordInputAttributes.includes(key)) {
|
|
574
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type 'password'.\x1b[0m`);
|
|
575
|
-
}
|
|
576
|
-
break;
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
} else {
|
|
580
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type 'password'.\x1b[0m`);
|
|
581
|
-
}
|
|
582
|
-
});
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
// Handle the binding syntax
|
|
586
|
-
let bindingDirective = '';
|
|
587
|
-
if (bindingSyntax === 'bind:value' && name) {
|
|
588
|
-
bindingDirective = ` bind:value="${name}"\n`;
|
|
589
|
-
}
|
|
590
|
-
if (bindingSyntax.startsWith('::') && name) {
|
|
591
|
-
bindingDirective = ` bind:value="${name}"\n`;
|
|
592
|
-
}
|
|
593
|
-
if (bindingSyntax && !name) {
|
|
594
|
-
console.log(`\x1b[31m%s\x1b[0m`, `You cannot set binding value when there is no name attribute defined in ${name} ${type} field.`);
|
|
595
|
-
return;
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
// Get the id from attributes or fall back to name
|
|
599
|
-
let id = attributes.id || name;
|
|
600
|
-
|
|
601
|
-
// Construct additional attributes dynamically
|
|
602
|
-
let additionalAttrs = '';
|
|
603
|
-
for (const [key, value] of Object.entries(attributes)) {
|
|
604
|
-
if (key !== 'id' && value !== undefined) {
|
|
605
|
-
if (key.startsWith('on')) {
|
|
606
|
-
// Handle event attributes
|
|
607
|
-
const eventValue = value.endsWith('()') ? value.slice(0, -2) : value;
|
|
608
|
-
additionalAttrs += ` @${key.replace(/^on/, '')}={${eventValue}}\n`;
|
|
609
|
-
} else {
|
|
610
|
-
// Handle boolean attributes
|
|
611
|
-
if (value === true) {
|
|
612
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}\n`;
|
|
613
|
-
} else if (value !== false) {
|
|
614
|
-
// Convert underscores to hyphens and set the attribute
|
|
615
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}="${value}"\n`;
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
}
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
// Construct the final HTML string
|
|
622
|
-
let formHTML = `
|
|
623
|
-
<div class="${this.divClass}">
|
|
624
|
-
<label for="${id}">${label}</label>
|
|
625
|
-
<input
|
|
626
|
-
type="${type}"
|
|
627
|
-
name="${name}"
|
|
628
|
-
${bindingDirective}
|
|
629
|
-
id="${id}"
|
|
630
|
-
${additionalAttrs}
|
|
631
|
-
${validationAttrs}
|
|
632
|
-
/>
|
|
633
|
-
</div>
|
|
634
|
-
`.replace(/^\s*\n/gm, '').trim();
|
|
635
|
-
|
|
636
|
-
// Format the entire HTML using pretty
|
|
637
|
-
let formattedHtml = pretty(formHTML, {
|
|
638
|
-
indent_size: 2,
|
|
639
|
-
wrap_line_length: 0,
|
|
640
|
-
preserve_newlines: true, // Preserve existing newlines
|
|
641
|
-
});
|
|
642
|
-
|
|
643
|
-
// Apply vertical layout to the <input> element only
|
|
644
|
-
formattedHtml = formattedHtml.replace(/<input\s+([^>]*)\/>/, (match, p1) => {
|
|
645
|
-
// Reformat attributes into a vertical layout
|
|
646
|
-
const attributes = p1.trim().split(/\s+/).map(attr => ` ${attr}`).join('\n');
|
|
647
|
-
return `<input\n${attributes}\n/>`;
|
|
648
|
-
});
|
|
649
|
-
|
|
650
|
-
// Ensure the <div> block starts on a new line and remove extra blank lines
|
|
651
|
-
formattedHtml = formattedHtml.replace(/(<div\s+[^>]*>)/g, (match) => {
|
|
652
|
-
// Ensure <div> starts on a new line
|
|
653
|
-
return `\n${match}\n`;
|
|
654
|
-
}).replace(/\n\s*\n/g, '\n'); // Remove extra blank lines
|
|
655
|
-
|
|
656
|
-
return formattedHtml;
|
|
657
|
-
}
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
// New method for rendering tel fields
|
|
665
|
-
renderTelField(type, name, label, validate, attributes, bindingSyntax) {
|
|
666
|
-
// Define valid attributes for the tel input type
|
|
667
|
-
const telInputAttributes = [
|
|
668
|
-
'required',
|
|
669
|
-
'pattern',
|
|
670
|
-
'placeholder',
|
|
671
|
-
'readonly',
|
|
672
|
-
'disabled',
|
|
673
|
-
'size',
|
|
674
|
-
'autocomplete',
|
|
675
|
-
'spellcheck',
|
|
676
|
-
'inputmode',
|
|
677
|
-
'title',
|
|
678
|
-
'minlength',
|
|
679
|
-
'maxlength',
|
|
680
|
-
];
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
// Construct validation attributes
|
|
684
|
-
let validationAttrs = '';
|
|
685
|
-
if (validate) {
|
|
686
|
-
Object.entries(validate).forEach(([key, value]) => {
|
|
687
|
-
if (telInputAttributes.includes(key)) {
|
|
688
|
-
if (typeof value === 'boolean' && value) {
|
|
689
|
-
validationAttrs += ` ${key}\n`;
|
|
690
|
-
} else {
|
|
691
|
-
switch (key) {
|
|
692
|
-
case 'pattern':
|
|
693
|
-
validationAttrs += ` ${key}="${value}"\n`;
|
|
694
|
-
break;
|
|
695
|
-
default:
|
|
696
|
-
if (!telInputAttributes.includes(key)) {
|
|
697
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type 'tel'.\x1b[0m`);
|
|
698
|
-
}
|
|
699
|
-
break;
|
|
700
|
-
}
|
|
701
|
-
}
|
|
702
|
-
} else {
|
|
703
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type 'tel'.\x1b[0m`);
|
|
704
|
-
}
|
|
705
|
-
});
|
|
706
|
-
}
|
|
707
|
-
|
|
708
|
-
// Handle the binding syntax
|
|
709
|
-
let bindingDirective = '';
|
|
710
|
-
if (bindingSyntax === 'bind:value' && name) {
|
|
711
|
-
bindingDirective = ` bind:value="${name}"\n`;
|
|
712
|
-
}
|
|
713
|
-
if (bindingSyntax.startsWith('::') && name) {
|
|
714
|
-
bindingDirective = ` bind:value="${name}"\n`;
|
|
715
|
-
}
|
|
716
|
-
if (bindingSyntax && !name) {
|
|
717
|
-
console.log(`\x1b[31m%s\x1b[0m`, `You cannot set binding value when there is no name attribute defined in ${name} ${type} field.`);
|
|
718
|
-
return;
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
// Get the id from attributes or fall back to name
|
|
722
|
-
let id = attributes.id || name;
|
|
723
|
-
|
|
724
|
-
// Construct additional attributes dynamically
|
|
725
|
-
let additionalAttrs = '';
|
|
726
|
-
for (const [key, value] of Object.entries(attributes)) {
|
|
727
|
-
if (key !== 'id' && value !== undefined) {
|
|
728
|
-
if (key.startsWith('on')) {
|
|
729
|
-
// Handle event attributes
|
|
730
|
-
const eventValue = value.endsWith('()') ? value.slice(0, -2) : value;
|
|
731
|
-
additionalAttrs += ` @${key.replace(/^on/, '')}={${eventValue}}\n`;
|
|
732
|
-
} else {
|
|
733
|
-
// Handle boolean attributes
|
|
734
|
-
if (value === true) {
|
|
735
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}\n`;
|
|
736
|
-
} else if (value !== false) {
|
|
737
|
-
// Convert underscores to hyphens and set the attribute
|
|
738
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}="${value}"\n`;
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
}
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
// Construct the final HTML string
|
|
745
|
-
let formHTML = `
|
|
746
|
-
<div class="${this.divClass}">
|
|
747
|
-
<label for="${id}">${label}</label>
|
|
748
|
-
<input
|
|
749
|
-
type="${type}"
|
|
750
|
-
name="${name}"
|
|
751
|
-
${bindingDirective}
|
|
752
|
-
id="${id}"
|
|
753
|
-
${additionalAttrs}
|
|
754
|
-
${validationAttrs}
|
|
755
|
-
/>
|
|
756
|
-
</div>
|
|
757
|
-
`.replace(/^\s*\n/gm, '').trim();
|
|
758
|
-
|
|
759
|
-
// Format the entire HTML using pretty
|
|
760
|
-
let formattedHtml = pretty(formHTML, {
|
|
761
|
-
indent_size: 2,
|
|
762
|
-
wrap_line_length: 0,
|
|
763
|
-
preserve_newlines: true, // Preserve existing newlines
|
|
764
|
-
});
|
|
765
|
-
|
|
766
|
-
// Apply vertical layout to the <input> element only
|
|
767
|
-
formattedHtml = formattedHtml.replace(/<input\s+([^>]*)\/>/, (match, p1) => {
|
|
768
|
-
// Reformat attributes into a vertical layout
|
|
769
|
-
const attributes = p1.trim().split(/\s+/).map(attr => ` ${attr}`).join('\n');
|
|
770
|
-
return `<input\n${attributes}\n/>`;
|
|
771
|
-
});
|
|
772
|
-
|
|
773
|
-
// Ensure the <div> block starts on a new line and remove extra blank lines
|
|
774
|
-
formattedHtml = formattedHtml.replace(/(<div\s+[^>]*>)/g, (match) => {
|
|
775
|
-
// Ensure <div> starts on a new line
|
|
776
|
-
return `\n${match}\n`;
|
|
777
|
-
}).replace(/\n\s*\n/g, '\n'); // Remove extra blank lines
|
|
778
|
-
|
|
779
|
-
return formattedHtml;
|
|
780
|
-
}
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
renderDateField(type, name, label, validate, attributes, bindingSyntax) {
|
|
785
|
-
// Define valid attributes for the date input type
|
|
786
|
-
const dateInputAttributes = [
|
|
787
|
-
'required',
|
|
788
|
-
'min',
|
|
789
|
-
'max',
|
|
790
|
-
'step',
|
|
791
|
-
'placeholder',
|
|
792
|
-
'readonly',
|
|
793
|
-
'disabled',
|
|
794
|
-
'autocomplete',
|
|
795
|
-
'spellcheck',
|
|
796
|
-
'inputmode',
|
|
797
|
-
'title',
|
|
798
|
-
];
|
|
799
|
-
|
|
800
|
-
// Construct validation attributes
|
|
801
|
-
let validationAttrs = '';
|
|
802
|
-
if (validate) {
|
|
803
|
-
Object.entries(validate).forEach(([key, value]) => {
|
|
804
|
-
if (dateInputAttributes.includes(key)) {
|
|
805
|
-
if (typeof value === 'boolean' && value) {
|
|
806
|
-
validationAttrs += ` ${key}\n`;
|
|
807
|
-
} else {
|
|
808
|
-
switch (key) {
|
|
809
|
-
case 'min':
|
|
810
|
-
case 'max':
|
|
811
|
-
case 'step':
|
|
812
|
-
validationAttrs += ` ${key}="${value}"\n`;
|
|
813
|
-
break;
|
|
814
|
-
default:
|
|
815
|
-
if (!dateInputAttributes.includes(key)) {
|
|
816
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type 'date'.\x1b[0m`);
|
|
817
|
-
}
|
|
818
|
-
break;
|
|
819
|
-
}
|
|
820
|
-
}
|
|
821
|
-
} else {
|
|
822
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type 'date'.\x1b[0m`);
|
|
823
|
-
}
|
|
824
|
-
});
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
// Handle the binding syntax
|
|
828
|
-
let bindingDirective = '';
|
|
829
|
-
if (bindingSyntax === 'bind:value' && name) {
|
|
830
|
-
bindingDirective = ` bind:value="${name}"\n`;
|
|
831
|
-
}
|
|
832
|
-
if (bindingSyntax.startsWith('::') && name) {
|
|
833
|
-
bindingDirective = ` bind:value="${name}"\n`;
|
|
834
|
-
}
|
|
835
|
-
if (bindingSyntax && !name) {
|
|
836
|
-
console.log(`\x1b[31m%s\x1b[0m`, `You cannot set binding value when there is no name attribute defined in ${name} ${type} field.`);
|
|
837
|
-
return;
|
|
838
|
-
}
|
|
839
|
-
|
|
840
|
-
// Get the id from attributes or fall back to name
|
|
841
|
-
let id = attributes.id || name;
|
|
842
|
-
|
|
843
|
-
// Construct additional attributes dynamically
|
|
844
|
-
let additionalAttrs = '';
|
|
845
|
-
for (const [key, value] of Object.entries(attributes)) {
|
|
846
|
-
if (key !== 'id' && value !== undefined) {
|
|
847
|
-
if (key.startsWith('on')) {
|
|
848
|
-
// Handle event attributes
|
|
849
|
-
const eventValue = value.endsWith('()') ? value.slice(0, -2) : value;
|
|
850
|
-
additionalAttrs += ` @${key.replace(/^on/, '')}={${eventValue}}\n`;
|
|
851
|
-
} else {
|
|
852
|
-
// Handle boolean attributes
|
|
853
|
-
if (value === true) {
|
|
854
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}\n`;
|
|
855
|
-
} else if (value !== false) {
|
|
856
|
-
// Convert underscores to hyphens and set the attribute
|
|
857
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}="${value}"\n`;
|
|
858
|
-
}
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
|
-
}
|
|
862
|
-
|
|
863
|
-
// Construct the final HTML string
|
|
864
|
-
let formHTML = `
|
|
865
|
-
<div class="${this.divClass}">
|
|
866
|
-
<label for="${id}">${label}</label>
|
|
867
|
-
<input
|
|
868
|
-
type="${type}"
|
|
869
|
-
name="${name}"
|
|
870
|
-
${bindingDirective}
|
|
871
|
-
id="${id}"
|
|
872
|
-
${additionalAttrs}
|
|
873
|
-
${validationAttrs}
|
|
874
|
-
/>
|
|
875
|
-
</div>
|
|
876
|
-
`.replace(/^\s*\n/gm, '').trim();
|
|
877
|
-
|
|
878
|
-
// Format the entire HTML using pretty
|
|
879
|
-
let formattedHtml = pretty(formHTML, {
|
|
880
|
-
indent_size: 2,
|
|
881
|
-
wrap_line_length: 0,
|
|
882
|
-
preserve_newlines: true, // Preserve existing newlines
|
|
883
|
-
});
|
|
884
|
-
|
|
885
|
-
// Apply vertical layout to the <input> element only
|
|
886
|
-
formattedHtml = formattedHtml.replace(/<input\s+([^>]*)\/>/, (match, p1) => {
|
|
887
|
-
// Reformat attributes into a vertical layout
|
|
888
|
-
const attributes = p1.trim().split(/\s+/).map(attr => ` ${attr}`).join('\n');
|
|
889
|
-
return `<input\n${attributes}\n/>`;
|
|
890
|
-
});
|
|
891
|
-
|
|
892
|
-
// Ensure the <div> block starts on a new line and remove extra blank lines
|
|
893
|
-
formattedHtml = formattedHtml.replace(/(<div\s+[^>]*>)/g, (match) => {
|
|
894
|
-
// Ensure <div> starts on a new line
|
|
895
|
-
return `\n${match}\n`;
|
|
896
|
-
}).replace(/\n\s*\n/g, '\n'); // Remove extra blank lines
|
|
897
|
-
|
|
898
|
-
return formattedHtml;
|
|
899
|
-
}
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
renderTimeField(type, name, label, validate, attributes, bindingSyntax) {
|
|
904
|
-
// Define valid attributes for the time input type
|
|
905
|
-
const timeInputAttributes = [
|
|
906
|
-
'required',
|
|
907
|
-
'min',
|
|
908
|
-
'max',
|
|
909
|
-
'step',
|
|
910
|
-
'readonly',
|
|
911
|
-
'disabled',
|
|
912
|
-
'autocomplete',
|
|
913
|
-
'spellcheck',
|
|
914
|
-
'inputmode',
|
|
915
|
-
'title',
|
|
916
|
-
];
|
|
917
|
-
|
|
918
|
-
// Construct validation attributes
|
|
919
|
-
let validationAttrs = '';
|
|
920
|
-
if (validate) {
|
|
921
|
-
Object.entries(validate).forEach(([key, value]) => {
|
|
922
|
-
if (timeInputAttributes.includes(key)) {
|
|
923
|
-
if (typeof value === 'boolean' && value) {
|
|
924
|
-
validationAttrs += ` ${key}\n`;
|
|
925
|
-
} else {
|
|
926
|
-
switch (key) {
|
|
927
|
-
case 'min':
|
|
928
|
-
case 'max':
|
|
929
|
-
case 'step':
|
|
930
|
-
validationAttrs += ` ${key}="${value}"\n`;
|
|
931
|
-
break;
|
|
932
|
-
default:
|
|
933
|
-
if (!timeInputAttributes.includes(key)) {
|
|
934
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type '${type}'.\x1b[0m`);
|
|
935
|
-
}
|
|
936
|
-
break;
|
|
937
|
-
}
|
|
938
|
-
}
|
|
939
|
-
} else {
|
|
940
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type '${type}'.\x1b[0m`);
|
|
941
|
-
}
|
|
942
|
-
});
|
|
943
|
-
}
|
|
944
|
-
|
|
945
|
-
// Handle the binding syntax
|
|
946
|
-
let bindingDirective = '';
|
|
947
|
-
if (bindingSyntax === 'bind:value' && name) {
|
|
948
|
-
bindingDirective = ` bind:value="${name}"\n`;
|
|
949
|
-
}
|
|
950
|
-
if (bindingSyntax.startsWith('::') && name) {
|
|
951
|
-
bindingDirective = ` bind:value="${name}"\n`;
|
|
952
|
-
}
|
|
953
|
-
if (bindingSyntax && !name) {
|
|
954
|
-
console.log(`\x1b[31m%s\x1b[0m`, `You cannot set binding value when there is no name attribute defined in ${name} ${type} field.`);
|
|
955
|
-
return;
|
|
956
|
-
}
|
|
957
|
-
|
|
958
|
-
// Get the id from attributes or fall back to name
|
|
959
|
-
let id = attributes.id || name;
|
|
960
|
-
|
|
961
|
-
// Construct additional attributes dynamically
|
|
962
|
-
let additionalAttrs = '';
|
|
963
|
-
for (const [key, value] of Object.entries(attributes)) {
|
|
964
|
-
if (key !== 'id' && value !== undefined) {
|
|
965
|
-
if (key.startsWith('on')) {
|
|
966
|
-
// Handle event attributes
|
|
967
|
-
const eventValue = value.endsWith('()') ? value.slice(0, -2) : value;
|
|
968
|
-
additionalAttrs += ` @${key.replace(/^on/, '')}={${eventValue}}\n`;
|
|
969
|
-
} else {
|
|
970
|
-
// Handle boolean attributes
|
|
971
|
-
if (value === true) {
|
|
972
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}\n`;
|
|
973
|
-
} else if (value !== false) {
|
|
974
|
-
// Convert underscores to hyphens and set the attribute
|
|
975
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}="${value}"\n`;
|
|
976
|
-
}
|
|
977
|
-
}
|
|
978
|
-
}
|
|
979
|
-
}
|
|
980
|
-
|
|
981
|
-
// Construct the final HTML string
|
|
982
|
-
let formHTML = `
|
|
983
|
-
<div class="${this.divClass}">
|
|
984
|
-
<label for="${id}">${label}</label>
|
|
985
|
-
<input
|
|
986
|
-
type="${type}"
|
|
987
|
-
name="${name}"
|
|
988
|
-
${bindingDirective}
|
|
989
|
-
id="${id}"
|
|
990
|
-
${additionalAttrs}
|
|
991
|
-
${validationAttrs}
|
|
992
|
-
/>
|
|
993
|
-
</div>
|
|
994
|
-
`.replace(/^\s*\n/gm, '').trim();
|
|
995
|
-
|
|
996
|
-
// Format the entire HTML using pretty
|
|
997
|
-
let formattedHtml = pretty(formHTML, {
|
|
998
|
-
indent_size: 2,
|
|
999
|
-
wrap_line_length: 0,
|
|
1000
|
-
preserve_newlines: true, // Preserve existing newlines
|
|
1001
|
-
});
|
|
1002
|
-
|
|
1003
|
-
// Apply vertical layout to the <input> element only
|
|
1004
|
-
formattedHtml = formattedHtml.replace(/<input\s+([^>]*)\/>/, (match, p1) => {
|
|
1005
|
-
// Reformat attributes into a vertical layout
|
|
1006
|
-
const attributes = p1.trim().split(/\s+/).map(attr => ` ${attr}`).join('\n');
|
|
1007
|
-
return `<input\n${attributes}\n/>`;
|
|
1008
|
-
});
|
|
1009
|
-
|
|
1010
|
-
// Ensure the <div> block starts on a new line and remove extra blank lines
|
|
1011
|
-
formattedHtml = formattedHtml.replace(/(<div\s+[^>]*>)/g, (match) => {
|
|
1012
|
-
// Ensure <div> starts on a new line
|
|
1013
|
-
return `\n${match}\n`;
|
|
1014
|
-
}).replace(/\n\s*\n/g, '\n'); // Remove extra blank lines
|
|
1015
|
-
|
|
1016
|
-
return formattedHtml;
|
|
1017
|
-
}
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
renderDateTimeField(type, name, label, validate, attributes, bindingSyntax) {
|
|
1023
|
-
// Define valid attributes for the datetime input type
|
|
1024
|
-
const dateTimeInputAttributes = [
|
|
1025
|
-
'required',
|
|
1026
|
-
'min',
|
|
1027
|
-
'max',
|
|
1028
|
-
'step',
|
|
1029
|
-
'readonly',
|
|
1030
|
-
'disabled',
|
|
1031
|
-
'autocomplete',
|
|
1032
|
-
'spellcheck',
|
|
1033
|
-
'inputmode',
|
|
1034
|
-
'title',
|
|
1035
|
-
];
|
|
1036
|
-
|
|
1037
|
-
// Construct validation attributes
|
|
1038
|
-
let validationAttrs = '';
|
|
1039
|
-
if (validate) {
|
|
1040
|
-
Object.entries(validate).forEach(([key, value]) => {
|
|
1041
|
-
if (dateTimeInputAttributes.includes(key)) {
|
|
1042
|
-
if (typeof value === 'boolean' && value) {
|
|
1043
|
-
validationAttrs += ` ${key}\n`;
|
|
1044
|
-
} else {
|
|
1045
|
-
switch (key) {
|
|
1046
|
-
case 'min':
|
|
1047
|
-
case 'max':
|
|
1048
|
-
case 'step':
|
|
1049
|
-
validationAttrs += ` ${key}="${value}"\n`;
|
|
1050
|
-
break;
|
|
1051
|
-
default:
|
|
1052
|
-
if (!dateTimeInputAttributes.includes(key)) {
|
|
1053
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type '${type}'.\x1b[0m`);
|
|
1054
|
-
}
|
|
1055
|
-
break;
|
|
1056
|
-
}
|
|
1057
|
-
}
|
|
1058
|
-
} else {
|
|
1059
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type '${type}'.\x1b[0m`);
|
|
1060
|
-
}
|
|
1061
|
-
});
|
|
1062
|
-
}
|
|
1063
|
-
|
|
1064
|
-
// Handle the binding syntax
|
|
1065
|
-
let bindingDirective = '';
|
|
1066
|
-
if (bindingSyntax === 'bind:value' && name) {
|
|
1067
|
-
bindingDirective = ` bind:value="${name}"\n`;
|
|
1068
|
-
} if (bindingSyntax.startsWith('::') && name) {
|
|
1069
|
-
bindingDirective = ` bind:value="${name}"\n`;
|
|
1070
|
-
}
|
|
1071
|
-
if (bindingSyntax && !name) {
|
|
1072
|
-
console.log(`\x1b[31m%s\x1b[0m`, `You cannot set binding value when there is no name attribute defined in ${name} ${type} field.`);
|
|
1073
|
-
return;
|
|
1074
|
-
}
|
|
1075
|
-
|
|
1076
|
-
// Get the id from attributes or fall back to name
|
|
1077
|
-
let id = attributes.id || name;
|
|
1078
|
-
|
|
1079
|
-
// Construct additional attributes dynamically
|
|
1080
|
-
let additionalAttrs = '';
|
|
1081
|
-
for (const [key, value] of Object.entries(attributes)) {
|
|
1082
|
-
if (key !== 'id' && value !== undefined) {
|
|
1083
|
-
if (key.startsWith('on')) {
|
|
1084
|
-
// Handle event attributes
|
|
1085
|
-
const eventValue = value.endsWith('()') ? value.slice(0, -2) : value;
|
|
1086
|
-
additionalAttrs += ` @${key.replace(/^on/, '')}={${eventValue}}\n`;
|
|
1087
|
-
} else {
|
|
1088
|
-
// Handle boolean attributes
|
|
1089
|
-
if (value === true) {
|
|
1090
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}\n`;
|
|
1091
|
-
} else if (value !== false) {
|
|
1092
|
-
// Convert underscores to hyphens and set the attribute
|
|
1093
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}="${value}"\n`;
|
|
1094
|
-
}
|
|
1095
|
-
}
|
|
1096
|
-
}
|
|
1097
|
-
}
|
|
1098
|
-
|
|
1099
|
-
// Construct the final HTML string
|
|
1100
|
-
let formHTML = `
|
|
1101
|
-
<div class="${this.divClass}">
|
|
1102
|
-
<label for="${id}">${label}</label>
|
|
1103
|
-
<input
|
|
1104
|
-
type="${type}"
|
|
1105
|
-
name="${name}"
|
|
1106
|
-
${bindingDirective}
|
|
1107
|
-
id="${id}"
|
|
1108
|
-
${additionalAttrs}
|
|
1109
|
-
${validationAttrs}
|
|
1110
|
-
/>
|
|
1111
|
-
</div>
|
|
1112
|
-
`.replace(/^\s*\n/gm, '').trim();
|
|
1113
|
-
|
|
1114
|
-
// Format the entire HTML using pretty
|
|
1115
|
-
let formattedHtml = pretty(formHTML, {
|
|
1116
|
-
indent_size: 2,
|
|
1117
|
-
wrap_line_length: 0,
|
|
1118
|
-
preserve_newlines: true, // Preserve existing newlines
|
|
1119
|
-
});
|
|
1120
|
-
|
|
1121
|
-
// Apply vertical layout to the <input> element only
|
|
1122
|
-
formattedHtml = formattedHtml.replace(/<input\s+([^>]*)\/>/, (match, p1) => {
|
|
1123
|
-
// Reformat attributes into a vertical layout
|
|
1124
|
-
const attributes = p1.trim().split(/\s+/).map(attr => ` ${attr}`).join('\n');
|
|
1125
|
-
return `<input\n${attributes}\n/>`;
|
|
1126
|
-
});
|
|
1127
|
-
|
|
1128
|
-
// Ensure the <div> block starts on a new line and remove extra blank lines
|
|
1129
|
-
formattedHtml = formattedHtml.replace(/(<div\s+[^>]*>)/g, (match) => {
|
|
1130
|
-
// Ensure <div> starts on a new line
|
|
1131
|
-
return `\n${match}\n`;
|
|
1132
|
-
}).replace(/\n\s*\n/g, '\n'); // Remove extra blank lines
|
|
1133
|
-
|
|
1134
|
-
return formattedHtml;
|
|
1135
|
-
}
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
renderMonthField(type, name, label, validate, attributes, bindingSyntax) {
|
|
1144
|
-
// Define valid attributes for the month input type
|
|
1145
|
-
const monthInputAttributes = [
|
|
1146
|
-
'required',
|
|
1147
|
-
'min',
|
|
1148
|
-
'max',
|
|
1149
|
-
'pattern',
|
|
1150
|
-
'placeholder',
|
|
1151
|
-
'readonly',
|
|
1152
|
-
'disabled',
|
|
1153
|
-
'size',
|
|
1154
|
-
'autocomplete',
|
|
1155
|
-
'spellcheck',
|
|
1156
|
-
'inputmode',
|
|
1157
|
-
'title',
|
|
1158
|
-
];
|
|
1159
|
-
|
|
1160
|
-
// Construct validation attributes
|
|
1161
|
-
let validationAttrs = '';
|
|
1162
|
-
if (validate) {
|
|
1163
|
-
Object.entries(validate).forEach(([key, value]) => {
|
|
1164
|
-
if (monthInputAttributes.includes(key)) {
|
|
1165
|
-
if (typeof value === 'boolean' && value) {
|
|
1166
|
-
validationAttrs += ` ${key}\n`;
|
|
1167
|
-
} else {
|
|
1168
|
-
switch (key) {
|
|
1169
|
-
case 'min':
|
|
1170
|
-
case 'max':
|
|
1171
|
-
case 'pattern':
|
|
1172
|
-
validationAttrs += ` ${key}="${value}"\n`;
|
|
1173
|
-
break;
|
|
1174
|
-
default:
|
|
1175
|
-
if (monthInputAttributes.includes(key)) {
|
|
1176
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type 'month'.\x1b[0m`);
|
|
1177
|
-
}
|
|
1178
|
-
break;
|
|
1179
|
-
}
|
|
1180
|
-
}
|
|
1181
|
-
} else {
|
|
1182
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type 'month'.\x1b[0m`);
|
|
1183
|
-
}
|
|
1184
|
-
});
|
|
1185
|
-
}
|
|
1186
|
-
|
|
1187
|
-
// Handle the binding syntax
|
|
1188
|
-
let bindingDirective = '';
|
|
1189
|
-
if (bindingSyntax === 'bind:value' && name) {
|
|
1190
|
-
bindingDirective = ` bind:value="${name}"\n`;
|
|
1191
|
-
} if (bindingSyntax.startsWith('::') && name) {
|
|
1192
|
-
bindingDirective = ` bind:value="${name}"\n`;
|
|
1193
|
-
} if (bindingSyntax && !name) {
|
|
1194
|
-
console.log(`\x1b[31m%s\x1b[0m`, `You cannot set binding value when there is no name attribute defined in ${name} ${type} field.`);
|
|
1195
|
-
return;
|
|
1196
|
-
}
|
|
1197
|
-
|
|
1198
|
-
// Get the id from attributes or fall back to name
|
|
1199
|
-
let id = attributes.id || name;
|
|
1200
|
-
|
|
1201
|
-
// Construct additional attributes dynamically
|
|
1202
|
-
let additionalAttrs = '';
|
|
1203
|
-
for (const [key, value] of Object.entries(attributes)) {
|
|
1204
|
-
if (key !== 'id' && value !== undefined) {
|
|
1205
|
-
if (key.startsWith('on')) {
|
|
1206
|
-
// Handle event attributes
|
|
1207
|
-
const eventValue = value.endsWith('()') ? value.slice(0, -2) : value;
|
|
1208
|
-
additionalAttrs += ` @${key.replace(/^on/, '')}={${eventValue}}\n`;
|
|
1209
|
-
} else {
|
|
1210
|
-
// Handle boolean attributes
|
|
1211
|
-
if (value === true) {
|
|
1212
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}\n`;
|
|
1213
|
-
} else if (value !== false) {
|
|
1214
|
-
// Convert underscores to hyphens and set the attribute
|
|
1215
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}="${value}"\n`;
|
|
1216
|
-
}
|
|
1217
|
-
}
|
|
1218
|
-
}
|
|
1219
|
-
}
|
|
1220
|
-
|
|
1221
|
-
// Construct the final HTML string
|
|
1222
|
-
let formHTML = `
|
|
1223
|
-
<div class="${this.divClass}">
|
|
1224
|
-
<label for="${id}">${label}</label>
|
|
1225
|
-
<input
|
|
1226
|
-
type="${type}"
|
|
1227
|
-
name="${name}"
|
|
1228
|
-
${bindingDirective}
|
|
1229
|
-
id="${id}"
|
|
1230
|
-
${additionalAttrs}
|
|
1231
|
-
${validationAttrs}
|
|
1232
|
-
/>
|
|
1233
|
-
</div>
|
|
1234
|
-
`.replace(/^\s*\n/gm, '').trim();
|
|
1235
|
-
|
|
1236
|
-
// Format the entire HTML using pretty
|
|
1237
|
-
let formattedHtml = pretty(formHTML, {
|
|
1238
|
-
indent_size: 2,
|
|
1239
|
-
wrap_line_length: 0,
|
|
1240
|
-
preserve_newlines: true, // Preserve existing newlines
|
|
1241
|
-
});
|
|
1242
|
-
|
|
1243
|
-
// Apply vertical layout to the <input> element only
|
|
1244
|
-
formattedHtml = formattedHtml.replace(/<input\s+([^>]*)\/>/, (match, p1) => {
|
|
1245
|
-
// Reformat attributes into a vertical layout
|
|
1246
|
-
const attributes = p1.trim().split(/\s+/).map(attr => ` ${attr}`).join('\n');
|
|
1247
|
-
return `<input\n${attributes}\n/>`;
|
|
1248
|
-
});
|
|
1249
|
-
|
|
1250
|
-
// Ensure the <div> block starts on a new line and remove extra blank lines
|
|
1251
|
-
formattedHtml = formattedHtml.replace(/(<div\s+[^>]*>)/g, (match) => {
|
|
1252
|
-
// Ensure <div> starts on a new line
|
|
1253
|
-
return `\n${match}\n`;
|
|
1254
|
-
}).replace(/\n\s*\n/g, '\n'); // Remove extra blank lines
|
|
1255
|
-
|
|
1256
|
-
return formattedHtml;
|
|
1257
|
-
}
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
renderWeekField(type, name, label, validate, attributes, bindingSyntax) {
|
|
1262
|
-
// Define valid attributes for the week input type
|
|
1263
|
-
const weekInputAttributes = [
|
|
1264
|
-
'required',
|
|
1265
|
-
'min',
|
|
1266
|
-
'max',
|
|
1267
|
-
'pattern',
|
|
1268
|
-
'placeholder',
|
|
1269
|
-
'readonly',
|
|
1270
|
-
'disabled',
|
|
1271
|
-
'size',
|
|
1272
|
-
'autocomplete',
|
|
1273
|
-
'spellcheck',
|
|
1274
|
-
'inputmode',
|
|
1275
|
-
'title',
|
|
1276
|
-
];
|
|
1277
|
-
|
|
1278
|
-
// Construct validation attributes
|
|
1279
|
-
let validationAttrs = '';
|
|
1280
|
-
if (validate) {
|
|
1281
|
-
Object.entries(validate).forEach(([key, value]) => {
|
|
1282
|
-
if (weekInputAttributes.includes(key)) {
|
|
1283
|
-
if (typeof value === 'boolean' && value) {
|
|
1284
|
-
validationAttrs += ` ${key}\n`;
|
|
1285
|
-
} else {
|
|
1286
|
-
switch (key) {
|
|
1287
|
-
case 'min':
|
|
1288
|
-
case 'max':
|
|
1289
|
-
case 'pattern':
|
|
1290
|
-
validationAttrs += ` ${key}="${value}"\n`;
|
|
1291
|
-
break;
|
|
1292
|
-
default:
|
|
1293
|
-
if (weekInputAttributes.includes(key)) {
|
|
1294
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type 'week'.\x1b[0m`);
|
|
1295
|
-
}
|
|
1296
|
-
break;
|
|
1297
|
-
}
|
|
1298
|
-
}
|
|
1299
|
-
} else {
|
|
1300
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type 'week'.\x1b[0m`);
|
|
1301
|
-
}
|
|
1302
|
-
});
|
|
1303
|
-
}
|
|
1304
|
-
|
|
1305
|
-
// Handle the binding syntax
|
|
1306
|
-
let bindingDirective = '';
|
|
1307
|
-
if (bindingSyntax === 'bind:value' && name) {
|
|
1308
|
-
bindingDirective = ` bind:value="${name}"\n`;
|
|
1309
|
-
} if (bindingSyntax.startsWith('::') && name) {
|
|
1310
|
-
bindingDirective = ` bind:value="${name}"\n`;
|
|
1311
|
-
} if (bindingSyntax && !name) {
|
|
1312
|
-
console.log(`\x1b[31m%s\x1b[0m`, `You cannot set binding value when there is no name attribute defined in ${name} ${type} field.`);
|
|
1313
|
-
return;
|
|
1314
|
-
}
|
|
1315
|
-
|
|
1316
|
-
// Get the id from attributes or fall back to name
|
|
1317
|
-
let id = attributes.id || name;
|
|
1318
|
-
|
|
1319
|
-
// Construct additional attributes dynamically
|
|
1320
|
-
let additionalAttrs = '';
|
|
1321
|
-
for (const [key, value] of Object.entries(attributes)) {
|
|
1322
|
-
if (key !== 'id' && value !== undefined) {
|
|
1323
|
-
if (key.startsWith('on')) {
|
|
1324
|
-
// Handle event attributes
|
|
1325
|
-
const eventValue = value.endsWith('()') ? value.slice(0, -2) : value;
|
|
1326
|
-
additionalAttrs += ` @${key.replace(/^on/, '')}={${eventValue}}\n`;
|
|
1327
|
-
} else {
|
|
1328
|
-
// Handle boolean attributes
|
|
1329
|
-
if (value === true) {
|
|
1330
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}\n`;
|
|
1331
|
-
} else if (value !== false) {
|
|
1332
|
-
// Convert underscores to hyphens and set the attribute
|
|
1333
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}="${value}"\n`;
|
|
1334
|
-
}
|
|
1335
|
-
}
|
|
1336
|
-
}
|
|
1337
|
-
}
|
|
1338
|
-
|
|
1339
|
-
// Construct the final HTML string
|
|
1340
|
-
let formHTML = `
|
|
1341
|
-
<div class="${this.divClass}">
|
|
1342
|
-
<label for="${id}">${label}</label>
|
|
1343
|
-
<input
|
|
1344
|
-
type="${type}"
|
|
1345
|
-
name="${name}"
|
|
1346
|
-
${bindingDirective}
|
|
1347
|
-
id="${id}"
|
|
1348
|
-
${additionalAttrs}
|
|
1349
|
-
${validationAttrs}
|
|
1350
|
-
/>
|
|
1351
|
-
</div>
|
|
1352
|
-
`.replace(/^\s*\n/gm, '').trim();
|
|
1353
|
-
|
|
1354
|
-
// Format the entire HTML using pretty
|
|
1355
|
-
let formattedHtml = pretty(formHTML, {
|
|
1356
|
-
indent_size: 2,
|
|
1357
|
-
wrap_line_length: 0,
|
|
1358
|
-
preserve_newlines: true, // Preserve existing newlines
|
|
1359
|
-
});
|
|
1360
|
-
|
|
1361
|
-
// Apply vertical layout to the <input> element only
|
|
1362
|
-
formattedHtml = formattedHtml.replace(/<input\s+([^>]*)\/>/, (match, p1) => {
|
|
1363
|
-
// Reformat attributes into a vertical layout
|
|
1364
|
-
const attributes = p1.trim().split(/\s+/).map(attr => ` ${attr}`).join('\n');
|
|
1365
|
-
return `<input\n${attributes}\n/>`;
|
|
1366
|
-
});
|
|
1367
|
-
|
|
1368
|
-
// Ensure the <div> block starts on a new line and remove extra blank lines
|
|
1369
|
-
formattedHtml = formattedHtml.replace(/(<div\s+[^>]*>)/g, (match) => {
|
|
1370
|
-
// Ensure <div> starts on a new line
|
|
1371
|
-
return `\n${match}\n`;
|
|
1372
|
-
}).replace(/\n\s*\n/g, '\n'); // Remove extra blank lines
|
|
1373
|
-
|
|
1374
|
-
return formattedHtml;
|
|
1375
|
-
}
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
renderUrlField(type, name, label, validate, attributes, bindingSyntax) {
|
|
1380
|
-
// Define valid attributes for the URL input type
|
|
1381
|
-
const urlInputAttributes = [
|
|
1382
|
-
'required',
|
|
1383
|
-
'pattern',
|
|
1384
|
-
'placeholder',
|
|
1385
|
-
'readonly',
|
|
1386
|
-
'disabled',
|
|
1387
|
-
'size',
|
|
1388
|
-
'autocomplete',
|
|
1389
|
-
'spellcheck',
|
|
1390
|
-
'inputmode',
|
|
1391
|
-
'title',
|
|
1392
|
-
];
|
|
1393
|
-
|
|
1394
|
-
// Construct validation attributes
|
|
1395
|
-
let validationAttrs = '';
|
|
1396
|
-
if (validate) {
|
|
1397
|
-
Object.entries(validate).forEach(([key, value]) => {
|
|
1398
|
-
if (urlInputAttributes.includes(key)) {
|
|
1399
|
-
if (typeof value === 'boolean' && value) {
|
|
1400
|
-
validationAttrs += ` ${key}\n`;
|
|
1401
|
-
} else {
|
|
1402
|
-
switch (key) {
|
|
1403
|
-
case 'pattern':
|
|
1404
|
-
validationAttrs += ` ${key}="${value}"\n`;
|
|
1405
|
-
break;
|
|
1406
|
-
default:
|
|
1407
|
-
if (!urlInputAttributes.includes(key)) {
|
|
1408
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type '${type}'.\x1b[0m`);
|
|
1409
|
-
}
|
|
1410
|
-
break;
|
|
1411
|
-
}
|
|
1412
|
-
}
|
|
1413
|
-
} else {
|
|
1414
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type '${type}'.\x1b[0m`);
|
|
1415
|
-
}
|
|
1416
|
-
});
|
|
1417
|
-
}
|
|
1418
|
-
|
|
1419
|
-
// Handle the binding syntax
|
|
1420
|
-
let bindingDirective = '';
|
|
1421
|
-
if (bindingSyntax === 'bind:value' && name) {
|
|
1422
|
-
bindingDirective = ` bind:value="${name}"\n`;
|
|
1423
|
-
} if (bindingSyntax.startsWith('::') && name) {
|
|
1424
|
-
bindingDirective = ` bind:value="${name}"\n`;
|
|
1425
|
-
} if (bindingSyntax && !name) {
|
|
1426
|
-
console.log(`\x1b[31m%s\x1b[0m`, `You cannot set binding value when there is no name attribute defined in ${name} ${type} field.`);
|
|
1427
|
-
return;
|
|
1428
|
-
}
|
|
1429
|
-
|
|
1430
|
-
// Get the id from attributes or fall back to name
|
|
1431
|
-
let id = attributes.id || name;
|
|
1432
|
-
|
|
1433
|
-
// Construct additional attributes dynamically
|
|
1434
|
-
let additionalAttrs = '';
|
|
1435
|
-
for (const [key, value] of Object.entries(attributes)) {
|
|
1436
|
-
if (key !== 'id' && value !== undefined) {
|
|
1437
|
-
if (key.startsWith('on')) {
|
|
1438
|
-
// Handle event attributes
|
|
1439
|
-
const eventValue = value.endsWith('()') ? value.slice(0, -2) : value;
|
|
1440
|
-
additionalAttrs += ` @${key.replace(/^on/, '')}={${eventValue}}\n`;
|
|
1441
|
-
} else {
|
|
1442
|
-
// Handle boolean attributes
|
|
1443
|
-
if (value === true) {
|
|
1444
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}\n`;
|
|
1445
|
-
} else if (value !== false) {
|
|
1446
|
-
// Convert underscores to hyphens and set the attribute
|
|
1447
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}="${value}"\n`;
|
|
1448
|
-
}
|
|
1449
|
-
}
|
|
1450
|
-
}
|
|
1451
|
-
}
|
|
1452
|
-
|
|
1453
|
-
// Construct the final HTML string
|
|
1454
|
-
let formHTML = `
|
|
1455
|
-
<div class="${this.divClass}">
|
|
1456
|
-
<label for="${id}">${label}</label>
|
|
1457
|
-
<input
|
|
1458
|
-
type="${type}"
|
|
1459
|
-
name="${name}"
|
|
1460
|
-
${bindingDirective}
|
|
1461
|
-
id="${id}"
|
|
1462
|
-
${additionalAttrs}
|
|
1463
|
-
${validationAttrs}
|
|
1464
|
-
/>
|
|
1465
|
-
</div>
|
|
1466
|
-
`.replace(/^\s*\n/gm, '').trim();
|
|
1467
|
-
|
|
1468
|
-
// Format the entire HTML using pretty
|
|
1469
|
-
let formattedHtml = pretty(formHTML, {
|
|
1470
|
-
indent_size: 2,
|
|
1471
|
-
wrap_line_length: 0,
|
|
1472
|
-
preserve_newlines: true, // Preserve existing newlines
|
|
1473
|
-
});
|
|
1474
|
-
|
|
1475
|
-
// Apply vertical layout to the <input> element only
|
|
1476
|
-
formattedHtml = formattedHtml.replace(/<input\s+([^>]*)\/>/, (match, p1) => {
|
|
1477
|
-
// Reformat attributes into a vertical layout
|
|
1478
|
-
const attributes = p1.trim().split(/\s+/).map(attr => ` ${attr}`).join('\n');
|
|
1479
|
-
return `<input\n${attributes}\n/>`;
|
|
1480
|
-
});
|
|
1481
|
-
|
|
1482
|
-
// Ensure the <div> block starts on a new line and remove extra blank lines
|
|
1483
|
-
formattedHtml = formattedHtml.replace(/(<div\s+[^>]*>)/g, (match) => {
|
|
1484
|
-
// Ensure <div> starts on a new line
|
|
1485
|
-
return `\n${match}\n`;
|
|
1486
|
-
}).replace(/\n\s*\n/g, '\n'); // Remove extra blank lines
|
|
1487
|
-
|
|
1488
|
-
return formattedHtml;
|
|
1489
|
-
}
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
renderSearchField(type, name, label, validate, attributes, bindingSyntax) {
|
|
1493
|
-
// Define valid attributes for the search input type
|
|
1494
|
-
const searchInputAttributes = [
|
|
1495
|
-
'required',
|
|
1496
|
-
'pattern',
|
|
1497
|
-
'placeholder',
|
|
1498
|
-
'readonly',
|
|
1499
|
-
'disabled',
|
|
1500
|
-
'size',
|
|
1501
|
-
'autocomplete',
|
|
1502
|
-
'spellcheck',
|
|
1503
|
-
'inputmode',
|
|
1504
|
-
'title',
|
|
1505
|
-
];
|
|
1506
|
-
|
|
1507
|
-
// Construct validation attributes
|
|
1508
|
-
let validationAttrs = '';
|
|
1509
|
-
if (validate) {
|
|
1510
|
-
Object.entries(validate).forEach(([key, value]) => {
|
|
1511
|
-
if (searchInputAttributes.includes(key)) {
|
|
1512
|
-
if (typeof value === 'boolean' && value) {
|
|
1513
|
-
validationAttrs += ` ${key}\n`;
|
|
1514
|
-
} else {
|
|
1515
|
-
switch (key) {
|
|
1516
|
-
case 'pattern':
|
|
1517
|
-
validationAttrs += ` ${key}="${value}"\n`;
|
|
1518
|
-
break;
|
|
1519
|
-
default:
|
|
1520
|
-
if (!searchInputAttributes.includes(key)) {
|
|
1521
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type '${type}'.\x1b[0m`);
|
|
1522
|
-
}
|
|
1523
|
-
break;
|
|
1524
|
-
}
|
|
1525
|
-
}
|
|
1526
|
-
} else {
|
|
1527
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type '${type}'.\x1b[0m`);
|
|
1528
|
-
}
|
|
1529
|
-
});
|
|
1530
|
-
}
|
|
1531
|
-
|
|
1532
|
-
// Handle the binding syntax
|
|
1533
|
-
let bindingDirective = '';
|
|
1534
|
-
if (bindingSyntax === 'bind:value' && name) {
|
|
1535
|
-
bindingDirective = ` bind:value="${name}"\n`;
|
|
1536
|
-
} if (bindingSyntax.startsWith('::') && name) {
|
|
1537
|
-
bindingDirective = ` bind:value="${name}"\n`;
|
|
1538
|
-
} if (bindingSyntax && !name) {
|
|
1539
|
-
console.log(`\x1b[31m%s\x1b[0m`, `You cannot set binding value when there is no name attribute defined in ${name} ${type} field.`);
|
|
1540
|
-
return;
|
|
1541
|
-
}
|
|
1542
|
-
|
|
1543
|
-
// Get the id from attributes or fall back to name
|
|
1544
|
-
let id = attributes.id || name;
|
|
1545
|
-
|
|
1546
|
-
// Construct additional attributes dynamically
|
|
1547
|
-
let additionalAttrs = '';
|
|
1548
|
-
for (const [key, value] of Object.entries(attributes)) {
|
|
1549
|
-
if (key !== 'id' && value !== undefined) {
|
|
1550
|
-
if (key.startsWith('on')) {
|
|
1551
|
-
// Handle event attributes
|
|
1552
|
-
const eventValue = value.endsWith('()') ? value.slice(0, -2) : value;
|
|
1553
|
-
additionalAttrs += ` @${key.replace(/^on/, '')}={${eventValue}}\n`;
|
|
1554
|
-
} else {
|
|
1555
|
-
// Handle boolean attributes
|
|
1556
|
-
if (value === true) {
|
|
1557
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}\n`;
|
|
1558
|
-
} else if (value !== false) {
|
|
1559
|
-
// Convert underscores to hyphens and set the attribute
|
|
1560
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}="${value}"\n`;
|
|
1561
|
-
}
|
|
1562
|
-
}
|
|
1563
|
-
}
|
|
1564
|
-
}
|
|
1565
|
-
|
|
1566
|
-
// Construct the final HTML string
|
|
1567
|
-
let formHTML = `
|
|
1568
|
-
<div class="${this.divClass}">
|
|
1569
|
-
<label for="${id}">${label}</label>
|
|
1570
|
-
<input
|
|
1571
|
-
type="${type}"
|
|
1572
|
-
name="${name}"
|
|
1573
|
-
${bindingDirective}
|
|
1574
|
-
id="${id}"
|
|
1575
|
-
${additionalAttrs}
|
|
1576
|
-
${validationAttrs}
|
|
1577
|
-
/>
|
|
1578
|
-
</div>
|
|
1579
|
-
`.replace(/^\s*\n/gm, '').trim();
|
|
1580
|
-
|
|
1581
|
-
// Format the entire HTML using pretty
|
|
1582
|
-
let formattedHtml = pretty(formHTML, {
|
|
1583
|
-
indent_size: 2,
|
|
1584
|
-
wrap_line_length: 0,
|
|
1585
|
-
preserve_newlines: true, // Preserve existing newlines
|
|
1586
|
-
});
|
|
1587
|
-
|
|
1588
|
-
// Apply vertical layout to the <input> element only
|
|
1589
|
-
formattedHtml = formattedHtml.replace(/<input\s+([^>]*)\/>/, (match, p1) => {
|
|
1590
|
-
// Reformat attributes into a vertical layout
|
|
1591
|
-
const attributes = p1.trim().split(/\s+/).map(attr => ` ${attr}`).join('\n');
|
|
1592
|
-
return `<input\n${attributes}\n/>`;
|
|
1593
|
-
});
|
|
1594
|
-
|
|
1595
|
-
// Ensure the <div> block starts on a new line and remove extra blank lines
|
|
1596
|
-
formattedHtml = formattedHtml.replace(/(<div\s+[^>]*>)/g, (match) => {
|
|
1597
|
-
// Ensure <div> starts on a new line
|
|
1598
|
-
return `\n${match}\n`;
|
|
1599
|
-
}).replace(/\n\s*\n/g, '\n'); // Remove extra blank lines
|
|
1600
|
-
|
|
1601
|
-
return formattedHtml;
|
|
1602
|
-
}
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
renderColorField(type, name, label, validate, attributes, bindingSyntax) {
|
|
1606
|
-
// Define valid attributes for the color input type
|
|
1607
|
-
const colorInputAttributes = [
|
|
1608
|
-
'required',
|
|
1609
|
-
'readonly',
|
|
1610
|
-
'disabled',
|
|
1611
|
-
'autocomplete',
|
|
1612
|
-
'inputmode',
|
|
1613
|
-
'title',
|
|
1614
|
-
];
|
|
1615
|
-
|
|
1616
|
-
// Construct validation attributes
|
|
1617
|
-
let validationAttrs = '';
|
|
1618
|
-
if (validate) {
|
|
1619
|
-
Object.entries(validate).forEach(([key, value]) => {
|
|
1620
|
-
if (colorInputAttributes.includes(key)) {
|
|
1621
|
-
if (typeof value === 'boolean' && value) {
|
|
1622
|
-
validationAttrs += ` ${key}\n`;
|
|
1623
|
-
} else {
|
|
1624
|
-
switch (key) {
|
|
1625
|
-
default:
|
|
1626
|
-
if (!colorInputAttributes.includes(key)) {
|
|
1627
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type '${type}'.\x1b[0m`);
|
|
1628
|
-
}
|
|
1629
|
-
break;
|
|
1630
|
-
}
|
|
1631
|
-
}
|
|
1632
|
-
} else {
|
|
1633
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type '${type}'.\x1b[0m`);
|
|
1634
|
-
}
|
|
1635
|
-
});
|
|
1636
|
-
}
|
|
1637
|
-
|
|
1638
|
-
// Handle the binding syntax
|
|
1639
|
-
let bindingDirective = '';
|
|
1640
|
-
if (bindingSyntax === 'bind:value') {
|
|
1641
|
-
bindingDirective = ` bind:value="${name}"\n`;
|
|
1642
|
-
} else if (bindingSyntax.startsWith('::') && name) {
|
|
1643
|
-
bindingDirective = ` bind:value="${name}"\n`;
|
|
1644
|
-
}
|
|
1645
|
-
if (bindingSyntax && !name) {
|
|
1646
|
-
console.log(`\x1b[31m%s\x1b[0m`, `You cannot set binding value when there is no name attribute defined in ${name} ${type} field.`);
|
|
1647
|
-
return;
|
|
1648
|
-
}
|
|
1649
|
-
|
|
1650
|
-
// Get the id from attributes or fall back to name
|
|
1651
|
-
let id = attributes.id || name;
|
|
1652
|
-
|
|
1653
|
-
// Construct additional attributes dynamically
|
|
1654
|
-
let additionalAttrs = '';
|
|
1655
|
-
for (const [key, value] of Object.entries(attributes)) {
|
|
1656
|
-
if (key !== 'id' && value !== undefined) {
|
|
1657
|
-
if (key.startsWith('on')) {
|
|
1658
|
-
// Handle event attributes
|
|
1659
|
-
const eventValue = value.endsWith('()') ? value.slice(0, -2) : value;
|
|
1660
|
-
additionalAttrs += ` @${key.replace(/^on/, '')}={${eventValue}}\n`;
|
|
1661
|
-
} else {
|
|
1662
|
-
// Handle boolean attributes
|
|
1663
|
-
if (value === true) {
|
|
1664
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}\n`;
|
|
1665
|
-
} else if (value !== false) {
|
|
1666
|
-
// Convert underscores to hyphens and set the attribute
|
|
1667
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}="${value}"\n`;
|
|
1668
|
-
}
|
|
1669
|
-
}
|
|
1670
|
-
}
|
|
1671
|
-
}
|
|
1672
|
-
|
|
1673
|
-
// Construct the final HTML string
|
|
1674
|
-
let formHTML = `
|
|
1675
|
-
<div class="${this.divClass}">
|
|
1676
|
-
<label for="${id}">${label}</label>
|
|
1677
|
-
<input
|
|
1678
|
-
type="${type}"
|
|
1679
|
-
name="${name}"
|
|
1680
|
-
${bindingDirective}
|
|
1681
|
-
id="${id}"
|
|
1682
|
-
${additionalAttrs}
|
|
1683
|
-
${validationAttrs}
|
|
1684
|
-
/>
|
|
1685
|
-
</div>
|
|
1686
|
-
`.replace(/^\s*\n/gm, '').trim();
|
|
1687
|
-
|
|
1688
|
-
// Format the entire HTML using pretty
|
|
1689
|
-
let formattedHtml = pretty(formHTML, {
|
|
1690
|
-
indent_size: 2,
|
|
1691
|
-
wrap_line_length: 0,
|
|
1692
|
-
preserve_newlines: true, // Preserve existing newlines
|
|
1693
|
-
});
|
|
1694
|
-
|
|
1695
|
-
// Apply vertical layout to the <input> element only
|
|
1696
|
-
formattedHtml = formattedHtml.replace(/<input\s+([^>]*)\/>/, (match, p1) => {
|
|
1697
|
-
// Reformat attributes into a vertical layout
|
|
1698
|
-
const attributes = p1.trim().split(/\s+/).map(attr => ` ${attr}`).join('\n');
|
|
1699
|
-
return `<input\n${attributes}\n/>`;
|
|
1700
|
-
});
|
|
1701
|
-
|
|
1702
|
-
// Ensure the <div> block starts on a new line and remove extra blank lines
|
|
1703
|
-
formattedHtml = formattedHtml.replace(/(<div\s+[^>]*>)/g, (match) => {
|
|
1704
|
-
// Ensure <div> starts on a new line
|
|
1705
|
-
return `\n${match}\n`;
|
|
1706
|
-
}).replace(/\n\s*\n/g, '\n'); // Remove extra blank lines
|
|
1707
|
-
|
|
1708
|
-
return formattedHtml;
|
|
1709
|
-
}
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
renderFileField(type, name, label, validate, attributes, bindingSyntax) {
|
|
1717
|
-
// Define valid attributes for the file input type
|
|
1718
|
-
const fileInputAttributes = [
|
|
1719
|
-
'required',
|
|
1720
|
-
'accept',
|
|
1721
|
-
'multiple',
|
|
1722
|
-
'disabled',
|
|
1723
|
-
'title',
|
|
1724
|
-
];
|
|
1725
|
-
|
|
1726
|
-
// Construct validation attributes
|
|
1727
|
-
let validationAttrs = '';
|
|
1728
|
-
if (validate) {
|
|
1729
|
-
Object.entries(validate).forEach(([key, value]) => {
|
|
1730
|
-
if (fileInputAttributes.includes(key)) {
|
|
1731
|
-
if (typeof value === 'boolean' && value) {
|
|
1732
|
-
validationAttrs += ` ${key}\n`;
|
|
1733
|
-
} else {
|
|
1734
|
-
switch (key) {
|
|
1735
|
-
default:
|
|
1736
|
-
if (!fileInputAttributes.includes(key)) {
|
|
1737
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type '${type}'.\x1b[0m`);
|
|
1738
|
-
}
|
|
1739
|
-
break;
|
|
1740
|
-
}
|
|
1741
|
-
}
|
|
1742
|
-
} else {
|
|
1743
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type '${type}'.\x1b[0m`);
|
|
1744
|
-
}
|
|
1745
|
-
});
|
|
1746
|
-
}
|
|
1747
|
-
|
|
1748
|
-
// Handle the binding syntax
|
|
1749
|
-
let bindingDirective = '';
|
|
1750
|
-
if (bindingSyntax === 'bind:value') {
|
|
1751
|
-
bindingDirective = ` bind:value="${name}"\n`;
|
|
1752
|
-
} if (bindingSyntax.startsWith('::') && name) {
|
|
1753
|
-
bindingDirective = ` bind:value="${name}"\n`;
|
|
1754
|
-
}
|
|
1755
|
-
if (bindingSyntax && !name) {
|
|
1756
|
-
console.log(`\x1b[31m%s\x1b[0m`, `You cannot set binding value when there is no name attribute defined in ${name} ${type} field.`);
|
|
1757
|
-
return;
|
|
1758
|
-
}
|
|
1759
|
-
|
|
1760
|
-
// Get the id from attributes or fall back to name
|
|
1761
|
-
let id = attributes.id || name;
|
|
1762
|
-
|
|
1763
|
-
// Construct additional attributes dynamically
|
|
1764
|
-
let additionalAttrs = '';
|
|
1765
|
-
for (const [key, value] of Object.entries(attributes)) {
|
|
1766
|
-
if (key !== 'id' && value !== undefined) {
|
|
1767
|
-
if (key.startsWith('on')) {
|
|
1768
|
-
// Handle event attributes
|
|
1769
|
-
const eventValue = value.endsWith('()') ? value.slice(0, -2) : value;
|
|
1770
|
-
additionalAttrs += ` @${key.replace(/^on/, '')}={${eventValue}}\n`;
|
|
1771
|
-
} else {
|
|
1772
|
-
// Handle boolean attributes
|
|
1773
|
-
if (value === true) {
|
|
1774
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}\n`;
|
|
1775
|
-
} else if (value !== false) {
|
|
1776
|
-
// Convert underscores to hyphens and set the attribute
|
|
1777
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}="${value}"\n`;
|
|
1778
|
-
}
|
|
1779
|
-
}
|
|
1780
|
-
}
|
|
1781
|
-
}
|
|
1782
|
-
|
|
1783
|
-
// Construct the final HTML string
|
|
1784
|
-
let formHTML = `
|
|
1785
|
-
<div class="${this.divClass}">
|
|
1786
|
-
<label for="${id}">${label}</label>
|
|
1787
|
-
<input
|
|
1788
|
-
type="${type}"
|
|
1789
|
-
name="${name}"
|
|
1790
|
-
${bindingDirective}
|
|
1791
|
-
id="${id}"
|
|
1792
|
-
${additionalAttrs}
|
|
1793
|
-
${validationAttrs}
|
|
1794
|
-
/>
|
|
1795
|
-
</div>
|
|
1796
|
-
`.replace(/^\s*\n/gm, '').trim();
|
|
1797
|
-
|
|
1798
|
-
// Format the entire HTML using pretty
|
|
1799
|
-
let formattedHtml = pretty(formHTML, {
|
|
1800
|
-
indent_size: 2,
|
|
1801
|
-
wrap_line_length: 0,
|
|
1802
|
-
preserve_newlines: true, // Preserve existing newlines
|
|
1803
|
-
});
|
|
1804
|
-
|
|
1805
|
-
// Apply vertical layout to the <input> element only
|
|
1806
|
-
formattedHtml = formattedHtml.replace(/<input\s+([^>]*)\/>/, (match, p1) => {
|
|
1807
|
-
// Reformat attributes into a vertical layout
|
|
1808
|
-
const attributes = p1.trim().split(/\s+/).map(attr => ` ${attr}`).join('\n');
|
|
1809
|
-
return `<input\n${attributes}\n/>`;
|
|
1810
|
-
});
|
|
1811
|
-
|
|
1812
|
-
// Ensure the <div> block starts on a new line and remove extra blank lines
|
|
1813
|
-
formattedHtml = formattedHtml.replace(/(<div\s+[^>]*>)/g, (match) => {
|
|
1814
|
-
// Ensure <div> starts on a new line
|
|
1815
|
-
return `\n${match}\n`;
|
|
1816
|
-
}).replace(/\n\s*\n/g, '\n'); // Remove extra blank lines
|
|
1817
|
-
|
|
1818
|
-
return formattedHtml;
|
|
1819
|
-
}
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
renderHiddenField(type, name, label, validate, attributes, bindingSyntax) {
|
|
1826
|
-
// Define valid attributes for the hidden input type
|
|
1827
|
-
const validAttributes = [
|
|
1828
|
-
'type',
|
|
1829
|
-
'name',
|
|
1830
|
-
'value',
|
|
1831
|
-
'id',
|
|
1832
|
-
'class',
|
|
1833
|
-
'style',
|
|
1834
|
-
'required',
|
|
1835
|
-
'readonly',
|
|
1836
|
-
'disabled',
|
|
1837
|
-
'tabindex',
|
|
1838
|
-
];
|
|
1839
|
-
|
|
1840
|
-
// Construct validation attributes
|
|
1841
|
-
let validationAttrs = '';
|
|
1842
|
-
if (validate) {
|
|
1843
|
-
Object.entries(validate).forEach(([key, value]) => {
|
|
1844
|
-
if (validAttributes.includes(key)) {
|
|
1845
|
-
if (typeof value === 'boolean' && value) {
|
|
1846
|
-
validationAttrs += ` ${key}\n`;
|
|
1847
|
-
} else {
|
|
1848
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type '${type}'.\x1b[0m`);
|
|
1849
|
-
}
|
|
1850
|
-
} else {
|
|
1851
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type '${type}'.\x1b[0m`);
|
|
1852
|
-
}
|
|
1853
|
-
});
|
|
1854
|
-
}
|
|
1855
|
-
|
|
1856
|
-
// Handle the binding syntax
|
|
1857
|
-
let bindingDirective = '';
|
|
1858
|
-
if (bindingSyntax === 'bind:value') {
|
|
1859
|
-
bindingDirective = ` bind:value="${name}"\n`;
|
|
1860
|
-
} if (bindingSyntax.startsWith('::') && name) {
|
|
1861
|
-
bindingDirective = ` bind:value="${name}"\n`;
|
|
1862
|
-
}
|
|
1863
|
-
if (bindingSyntax && !name) {
|
|
1864
|
-
console.log(`\x1b[31m%s\x1b[0m`, `You cannot set binding value when there is no name attribute defined in ${name} ${type} field.`);
|
|
1865
|
-
return;
|
|
1866
|
-
}
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
// Get the id from attributes or fall back to name
|
|
1870
|
-
let id = attributes.id || name;
|
|
1871
|
-
|
|
1872
|
-
// Construct additional attributes dynamically
|
|
1873
|
-
let additionalAttrs = '';
|
|
1874
|
-
for (const [key, value] of Object.entries(attributes)) {
|
|
1875
|
-
if (key !== 'id' && value !== undefined) {
|
|
1876
|
-
if (key.startsWith('on')) {
|
|
1877
|
-
// Handle event attributes
|
|
1878
|
-
const eventValue = value.endsWith('()') ? value.slice(0, -2) : value;
|
|
1879
|
-
additionalAttrs += ` @${key.replace(/^on/, '')}={${eventValue}}\n`;
|
|
1880
|
-
} else {
|
|
1881
|
-
// Handle boolean attributes
|
|
1882
|
-
if (value === true) {
|
|
1883
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}\n`;
|
|
1884
|
-
} else if (value !== false) {
|
|
1885
|
-
// Convert underscores to hyphens and set the attribute
|
|
1886
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}="${value}"\n`;
|
|
1887
|
-
}
|
|
1888
|
-
}
|
|
1889
|
-
}
|
|
1890
|
-
}
|
|
1891
|
-
|
|
1892
|
-
// Construct the final HTML string
|
|
1893
|
-
let formHTML = `
|
|
1894
|
-
<div class="${this.divClass}">
|
|
1895
|
-
<label for="${id}">${label}</label>
|
|
1896
|
-
<input
|
|
1897
|
-
type="${type}"
|
|
1898
|
-
name="${name}"
|
|
1899
|
-
${bindingDirective}
|
|
1900
|
-
id="${id}"
|
|
1901
|
-
${additionalAttrs}
|
|
1902
|
-
${validationAttrs}
|
|
1903
|
-
/>
|
|
1904
|
-
</div>
|
|
1905
|
-
`.replace(/^\s*\n/gm, '').trim();
|
|
1906
|
-
|
|
1907
|
-
// Format the entire HTML using pretty
|
|
1908
|
-
let formattedHtml = pretty(formHTML, {
|
|
1909
|
-
indent_size: 2,
|
|
1910
|
-
wrap_line_length: 0,
|
|
1911
|
-
preserve_newlines: true, // Preserve existing newlines
|
|
1912
|
-
});
|
|
1913
|
-
|
|
1914
|
-
// Apply vertical layout to the <input> element only
|
|
1915
|
-
formattedHtml = formattedHtml.replace(/<input\s+([^>]*)\/>/, (match, p1) => {
|
|
1916
|
-
// Reformat attributes into a vertical layout
|
|
1917
|
-
const attributes = p1.trim().split(/\s+/).map(attr => ` ${attr}`).join('\n');
|
|
1918
|
-
return `<input\n${attributes}\n/>`;
|
|
1919
|
-
});
|
|
1920
|
-
|
|
1921
|
-
// Ensure the <div> block starts on a new line and remove extra blank lines
|
|
1922
|
-
formattedHtml = formattedHtml.replace(/(<div\s+[^>]*>)/g, (match) => {
|
|
1923
|
-
// Ensure <div> starts on a new line
|
|
1924
|
-
return `\n${match}\n`;
|
|
1925
|
-
}).replace(/\n\s*\n/g, '\n'); // Remove extra blank lines
|
|
1926
|
-
|
|
1927
|
-
return formattedHtml;
|
|
1928
|
-
}
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
renderImageField(type, name, label, validate, attributes, bindingSyntax) {
|
|
1933
|
-
// Define valid validation attributes for image upload
|
|
1934
|
-
const imageUploadValidationAttributes = [
|
|
1935
|
-
'accept',
|
|
1936
|
-
'required',
|
|
1937
|
-
'minwidth',
|
|
1938
|
-
'maxwidth',
|
|
1939
|
-
'minheight',
|
|
1940
|
-
'maxheight',
|
|
1941
|
-
];
|
|
1942
|
-
|
|
1943
|
-
// Construct validation attributes
|
|
1944
|
-
let validationAttrs = '';
|
|
1945
|
-
if (validate) {
|
|
1946
|
-
Object.entries(validate).forEach(([key, value]) => {
|
|
1947
|
-
if (imageUploadValidationAttributes.includes(key)) {
|
|
1948
|
-
if (key === 'accept') {
|
|
1949
|
-
validationAttrs += `accept="${value}"\n`;
|
|
1950
|
-
} else if (['required', 'minwidth', 'maxwidth', 'minheight', 'maxheight'].includes(key)) {
|
|
1951
|
-
validationAttrs += `${key}="${value}"\n`;
|
|
1952
|
-
} else {
|
|
1953
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type '${type}'.\x1b[0m`);
|
|
1954
|
-
}
|
|
1955
|
-
} else {
|
|
1956
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type '${type}'.\x1b[0m`);
|
|
1957
|
-
}
|
|
1958
|
-
});
|
|
1959
|
-
}
|
|
1960
|
-
|
|
1961
|
-
// Handle the binding syntax
|
|
1962
|
-
let bindingDirective = '';
|
|
1963
|
-
if (bindingSyntax === 'bind:value') {
|
|
1964
|
-
bindingDirective = ` bind:value="${name}"`;
|
|
1965
|
-
} else if (bindingSyntax.startsWith('::')) {
|
|
1966
|
-
bindingDirective = ` bind:value="${name}"`;
|
|
1967
|
-
}
|
|
1968
|
-
|
|
1969
|
-
// Get the id from attributes or fall back to name
|
|
1970
|
-
let id = attributes.id || name;
|
|
1971
|
-
|
|
1972
|
-
// Construct additional attributes dynamically
|
|
1973
|
-
let additionalAttrs = '';
|
|
1974
|
-
for (const [key, value] of Object.entries(attributes)) {
|
|
1975
|
-
if (key !== 'id' && value !== undefined) {
|
|
1976
|
-
if (key.startsWith('on')) {
|
|
1977
|
-
// Handle event attributes
|
|
1978
|
-
const eventValue = value.endsWith('()') ? value.slice(0, -2) : value;
|
|
1979
|
-
additionalAttrs += ` @${key.replace(/^on/, '')}={${eventValue}}\n`;
|
|
1980
|
-
} else {
|
|
1981
|
-
// Handle boolean attributes
|
|
1982
|
-
if (value === true) {
|
|
1983
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}\n`;
|
|
1984
|
-
} else if (value !== false) {
|
|
1985
|
-
// Convert underscores to hyphens and set the attribute
|
|
1986
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}="${value}"\n`;
|
|
1987
|
-
}
|
|
1988
|
-
}
|
|
1989
|
-
}
|
|
1990
|
-
}
|
|
1991
|
-
|
|
1992
|
-
// Construct the final HTML string
|
|
1993
|
-
let formHTML = `
|
|
1994
|
-
<div class="${this.divClass}">
|
|
1995
|
-
<label for="${id}">${label}</label>
|
|
1996
|
-
<input
|
|
1997
|
-
type="${type}"
|
|
1998
|
-
name="${name}"
|
|
1999
|
-
${bindingDirective}
|
|
2000
|
-
id="${id}"
|
|
2001
|
-
${additionalAttrs}
|
|
2002
|
-
${validationAttrs}
|
|
2003
|
-
/>
|
|
2004
|
-
</div>
|
|
2005
|
-
`.replace(/^\s*\n/gm, '').trim();
|
|
2006
|
-
|
|
2007
|
-
// Format the entire HTML using pretty
|
|
2008
|
-
let formattedHtml = pretty(formHTML, {
|
|
2009
|
-
indent_size: 2,
|
|
2010
|
-
wrap_line_length: 0,
|
|
2011
|
-
preserve_newlines: true, // Preserve existing newlines
|
|
2012
|
-
});
|
|
2013
|
-
|
|
2014
|
-
// Apply vertical layout to the <input> element only
|
|
2015
|
-
formattedHtml = formattedHtml.replace(/<input\s+([^>]*)\/>/, (match, p1) => {
|
|
2016
|
-
// Reformat attributes into a vertical layout
|
|
2017
|
-
const attributes = p1.trim().split(/\s+/).map(attr => ` ${attr}`).join('\n');
|
|
2018
|
-
return `<input\n${attributes}\n/>`;
|
|
2019
|
-
});
|
|
2020
|
-
|
|
2021
|
-
// Ensure the <div> block starts on a new line and remove extra blank lines
|
|
2022
|
-
formattedHtml = formattedHtml.replace(/(<div\s+[^>]*>)/g, (match) => {
|
|
2023
|
-
// Ensure <div> starts on a new line
|
|
2024
|
-
return `\n${match}\n`;
|
|
2025
|
-
}).replace(/\n\s*\n/g, '\n'); // Remove extra blank lines
|
|
2026
|
-
|
|
2027
|
-
return formattedHtml;
|
|
2028
|
-
}
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
renderImageField(type, name, label, validate, attributes, bindingSyntax) {
|
|
2034
|
-
// Define valid validation attributes for image upload
|
|
2035
|
-
const imageUploadValidationAttributes = [
|
|
2036
|
-
'accept',
|
|
2037
|
-
'required',
|
|
2038
|
-
'minwidth',
|
|
2039
|
-
'maxwidth',
|
|
2040
|
-
'minheight',
|
|
2041
|
-
'maxheight',
|
|
2042
|
-
];
|
|
2043
|
-
|
|
2044
|
-
// Construct validation attributes
|
|
2045
|
-
let validationAttrs = '';
|
|
2046
|
-
if (validate) {
|
|
2047
|
-
Object.entries(validate).forEach(([key, value]) => {
|
|
2048
|
-
if (imageUploadValidationAttributes.includes(key)) {
|
|
2049
|
-
validationAttrs += `${key}="${value}"\n`;
|
|
2050
|
-
} else {
|
|
2051
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type '${type}'.\x1b[0m`);
|
|
2052
|
-
}
|
|
2053
|
-
});
|
|
2054
|
-
}
|
|
2055
|
-
|
|
2056
|
-
// Handle the binding syntax
|
|
2057
|
-
let bindingDirective = '';
|
|
2058
|
-
if (bindingSyntax === 'bind:value' || bindingSyntax.startsWith('::')) {
|
|
2059
|
-
bindingDirective = `bind:value="${name}"\n`;
|
|
2060
|
-
}
|
|
2061
|
-
|
|
2062
|
-
// Get the id from attributes or fall back to name
|
|
2063
|
-
let id = attributes.id || name;
|
|
2064
|
-
|
|
2065
|
-
// Construct additional attributes dynamically
|
|
2066
|
-
let additionalAttrs = '';
|
|
2067
|
-
for (const [key, value] of Object.entries(attributes)) {
|
|
2068
|
-
if (key !== 'id' && value !== undefined) {
|
|
2069
|
-
if (key.startsWith('on')) {
|
|
2070
|
-
// Handle event attributes
|
|
2071
|
-
const eventValue = value.endsWith('()') ? value.slice(0, -2) : value;
|
|
2072
|
-
additionalAttrs += ` @${key.replace(/^on/, '')}={${eventValue}}\n`;
|
|
2073
|
-
} else {
|
|
2074
|
-
// Handle boolean attributes
|
|
2075
|
-
if (value === true) {
|
|
2076
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}\n`;
|
|
2077
|
-
} else if (value !== false) {
|
|
2078
|
-
// Convert underscores to hyphens and set the attribute
|
|
2079
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}="${value}"\n`;
|
|
2080
|
-
}
|
|
2081
|
-
}
|
|
2082
|
-
}
|
|
2083
|
-
}
|
|
2084
|
-
|
|
2085
|
-
// Construct the final HTML string
|
|
2086
|
-
let formHTML = `
|
|
2087
|
-
<div class="${this.divClass}">
|
|
2088
|
-
<label for="${id}">${label}</label>
|
|
2089
|
-
<input
|
|
2090
|
-
type="${type}"
|
|
2091
|
-
name="${name}"
|
|
2092
|
-
${bindingDirective}
|
|
2093
|
-
id="${id}"
|
|
2094
|
-
${additionalAttrs}
|
|
2095
|
-
${validationAttrs}
|
|
2096
|
-
/>
|
|
2097
|
-
</div>
|
|
2098
|
-
`.replace(/^\s*\n/gm, '').trim();
|
|
2099
|
-
|
|
2100
|
-
// Format the entire HTML using pretty
|
|
2101
|
-
let formattedHtml = pretty(formHTML, {
|
|
2102
|
-
indent_size: 2,
|
|
2103
|
-
wrap_line_length: 0,
|
|
2104
|
-
preserve_newlines: true, // Preserve existing newlines
|
|
2105
|
-
});
|
|
2106
|
-
|
|
2107
|
-
// Apply vertical layout to the <input> element only
|
|
2108
|
-
formattedHtml = formattedHtml.replace(/<input\s+([^>]*)\/>/, (match, p1) => {
|
|
2109
|
-
// Reformat attributes into a vertical layout
|
|
2110
|
-
const attributes = p1.trim().split(/\s+/).map(attr => ` ${attr}`).join('\n');
|
|
2111
|
-
return `<input\n${attributes}\n/>`;
|
|
2112
|
-
});
|
|
2113
|
-
|
|
2114
|
-
// Ensure the <div> block starts on a new line and remove extra blank lines
|
|
2115
|
-
formattedHtml = formattedHtml.replace(/(<div\s+[^>]*>)/g, (match) => {
|
|
2116
|
-
// Ensure <div> starts on a new line
|
|
2117
|
-
return `\n${match}\n`;
|
|
2118
|
-
}).replace(/\n\s*\n/g, '\n'); // Remove extra blank lines
|
|
2119
|
-
|
|
2120
|
-
return formattedHtml;
|
|
2121
|
-
}
|
|
2122
|
-
|
|
2123
|
-
renderTextareaField(type, name, label, validate, attributes, bindingSyntax) {
|
|
2124
|
-
// Define valid validation attributes for textarea
|
|
2125
|
-
const textareaValidationAttributes = [
|
|
2126
|
-
'required',
|
|
2127
|
-
'minlength',
|
|
2128
|
-
'maxlength',
|
|
2129
|
-
'rows',
|
|
2130
|
-
'cols',
|
|
2131
|
-
];
|
|
2132
|
-
|
|
2133
|
-
// Construct validation and dimension attributes
|
|
2134
|
-
let validationAttrs = '';
|
|
2135
|
-
let dimensionAttrs = '';
|
|
2136
|
-
|
|
2137
|
-
if (validate) {
|
|
2138
|
-
Object.entries(validate).forEach(([key, value]) => {
|
|
2139
|
-
if (textareaValidationAttributes.includes(key)) {
|
|
2140
|
-
if (key === 'required') {
|
|
2141
|
-
validationAttrs += `required\n`;
|
|
2142
|
-
} else if (['minlength', 'maxlength'].includes(key)) {
|
|
2143
|
-
validationAttrs += `${key}="${value}"\n`;
|
|
2144
|
-
} else if (['rows', 'cols'].includes(key)) {
|
|
2145
|
-
dimensionAttrs += `${key}="${value}"\n`;
|
|
2146
|
-
}
|
|
2147
|
-
} else {
|
|
2148
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type '${type}'.\x1b[0m`);
|
|
2149
|
-
}
|
|
2150
|
-
});
|
|
2151
|
-
}
|
|
2152
|
-
|
|
2153
|
-
// Handle the binding syntax
|
|
2154
|
-
let bindingDirective = '';
|
|
2155
|
-
if (bindingSyntax === 'bind:value' || bindingSyntax.startsWith('::')) {
|
|
2156
|
-
bindingDirective = `bind:value="${name}"\n`;
|
|
2157
|
-
}
|
|
2158
|
-
|
|
2159
|
-
// Get the id from attributes or fall back to name
|
|
2160
|
-
let id = attributes.id || name;
|
|
2161
|
-
|
|
2162
|
-
// Construct additional attributes dynamically
|
|
2163
|
-
let additionalAttrs = '';
|
|
2164
|
-
for (const [key, value] of Object.entries(attributes)) {
|
|
2165
|
-
if (key !== 'id' && value !== undefined) {
|
|
2166
|
-
if (key.startsWith('on')) {
|
|
2167
|
-
// Handle event attributes
|
|
2168
|
-
const eventValue = value.endsWith('()') ? value.slice(0, -2) : value;
|
|
2169
|
-
additionalAttrs += ` @${key.replace(/^on/, '')}={${eventValue}}\n`;
|
|
2170
|
-
} else {
|
|
2171
|
-
// Handle boolean attributes
|
|
2172
|
-
if (value === true) {
|
|
2173
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}\n`;
|
|
2174
|
-
} else if (value !== false) {
|
|
2175
|
-
// Convert underscores to hyphens and set the attribute
|
|
2176
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}="${value}"\n`;
|
|
2177
|
-
}
|
|
2178
|
-
}
|
|
2179
|
-
}
|
|
2180
|
-
}
|
|
2181
|
-
|
|
2182
|
-
// Construct the final HTML string
|
|
2183
|
-
let formHTML = `
|
|
2184
|
-
<div class="${this.divClass}">
|
|
2185
|
-
<label for="${id}">${label}</label>
|
|
2186
|
-
<textarea
|
|
2187
|
-
name="${name}"
|
|
2188
|
-
${bindingDirective}
|
|
2189
|
-
${dimensionAttrs}
|
|
2190
|
-
id="${id}"
|
|
2191
|
-
${additionalAttrs}
|
|
2192
|
-
${validationAttrs}
|
|
2193
|
-
></textarea>
|
|
2194
|
-
</div>
|
|
2195
|
-
`.replace(/^\s*\n/gm, '').trim();
|
|
2196
|
-
|
|
2197
|
-
// Format the entire HTML using pretty
|
|
2198
|
-
let formattedHtml = pretty(formHTML, {
|
|
2199
|
-
indent_size: 2,
|
|
2200
|
-
wrap_line_length: 0,
|
|
2201
|
-
preserve_newlines: true, // Preserve existing newlines
|
|
2202
|
-
});
|
|
2203
|
-
|
|
2204
|
-
// Apply vertical layout to the <textarea> element only
|
|
2205
|
-
formattedHtml = formattedHtml.replace(/<textarea\s+([^>]*)<\/textarea>/, (match, p1) => {
|
|
2206
|
-
// Reformat attributes into a vertical layout
|
|
2207
|
-
const attributes = p1.trim().split(/\s+/).map(attr => ` ${attr}`).join('\n');
|
|
2208
|
-
return `<textarea\n${attributes}\n></textarea>`;
|
|
2209
|
-
});
|
|
2210
|
-
|
|
2211
|
-
// Ensure the <div> block starts on a new line and remove extra blank lines
|
|
2212
|
-
formattedHtml = formattedHtml.replace(/(<div\s+[^>]*>)/g, (match) => {
|
|
2213
|
-
// Ensure <div> starts on a new line
|
|
2214
|
-
return `\n${match}\n`;
|
|
2215
|
-
}).replace(/\n\s*\n/g, '\n'); // Remove extra blank lines
|
|
2216
|
-
|
|
2217
|
-
return formattedHtml;
|
|
2218
|
-
}
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
renderRadioField(type, name, label, validate, attributes, bindingSyntax, options) {
|
|
2224
|
-
// Define valid validation attributes for radio fields
|
|
2225
|
-
const radioValidationAttributes = ['required'];
|
|
2226
|
-
|
|
2227
|
-
// Construct validation attributes
|
|
2228
|
-
let validationAttrs = '';
|
|
2229
|
-
if (validate) {
|
|
2230
|
-
Object.entries(validate).forEach(([key, value]) => {
|
|
2231
|
-
if (radioValidationAttributes.includes(key)) {
|
|
2232
|
-
if (key === 'required') {
|
|
2233
|
-
validationAttrs += `required\n`;
|
|
2234
|
-
}
|
|
2235
|
-
} else {
|
|
2236
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type '${type}'.\x1b[0m`);
|
|
2237
|
-
}
|
|
2238
|
-
});
|
|
2239
|
-
}
|
|
2240
|
-
|
|
2241
|
-
// Handle the binding syntax
|
|
2242
|
-
let bindingDirective = '';
|
|
2243
|
-
if (bindingSyntax === 'bind:value') {
|
|
2244
|
-
bindingDirective = ` bind:value="${name}"\n`;
|
|
2245
|
-
} else if (bindingSyntax.startsWith('::')) {
|
|
2246
|
-
bindingDirective = ` bind:value="${name}"\n`;
|
|
2247
|
-
}
|
|
2248
|
-
|
|
2249
|
-
// Define attributes for the radio inputs
|
|
2250
|
-
let id = attributes.id || name;
|
|
2251
|
-
|
|
2252
|
-
// Handle additional attributes
|
|
2253
|
-
let additionalAttrs = '';
|
|
2254
|
-
for (const [key, value] of Object.entries(attributes)) {
|
|
2255
|
-
if (key !== 'id' && value !== undefined) {
|
|
2256
|
-
if (key.startsWith('on')) {
|
|
2257
|
-
// Handle event attributes
|
|
2258
|
-
const eventValue = value.endsWith('()') ? value.slice(0, -2) : value;
|
|
2259
|
-
additionalAttrs += ` @${key.replace(/^on/, '')}={${eventValue}}\n`;
|
|
2260
|
-
} else {
|
|
2261
|
-
// Handle boolean attributes
|
|
2262
|
-
if (value === true) {
|
|
2263
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}\n`;
|
|
2264
|
-
} else if (value !== false) {
|
|
2265
|
-
// Convert underscores to hyphens and set the attribute
|
|
2266
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}="${value}"\n`;
|
|
2267
|
-
}
|
|
2268
|
-
}
|
|
2269
|
-
}
|
|
2270
|
-
}
|
|
2271
|
-
|
|
2272
|
-
// Construct radio button HTML based on options
|
|
2273
|
-
let optionsHTML = '';
|
|
2274
|
-
if (options && options.length) {
|
|
2275
|
-
optionsHTML = options.map((option) => {
|
|
2276
|
-
return `
|
|
2277
|
-
<div>
|
|
2278
|
-
<input type="radio" name="${name}" value="${option.value}"${bindingDirective} ${additionalAttrs}
|
|
2279
|
-
${attributes.id ? `id="${id}-${option.value}"` : `id="${id}-${option.value}"`}
|
|
2280
|
-
/>
|
|
2281
|
-
<label for="${attributes.id ? `${id}-${option.value}` : `${id}-${option.value}`}">${option.label}</label>
|
|
2282
|
-
</div>
|
|
2283
|
-
`;
|
|
2284
|
-
}).join('');
|
|
2285
|
-
}
|
|
2286
|
-
|
|
2287
|
-
// Construct the final HTML string
|
|
2288
|
-
let formHTML = `
|
|
2289
|
-
<fieldset class="${this.radioGroupClass}">
|
|
2290
|
-
<legend>${label}</legend>
|
|
2291
|
-
${optionsHTML}
|
|
2292
|
-
</fieldset>
|
|
2293
|
-
`.replace(/^\s*\n/gm, '').trim();
|
|
2294
|
-
|
|
2295
|
-
// Format the entire HTML using pretty
|
|
2296
|
-
let formattedHtml = pretty(formHTML, {
|
|
2297
|
-
indent_size: 2,
|
|
2298
|
-
wrap_line_length: 0,
|
|
2299
|
-
preserve_newlines: true, // Preserve existing newlines
|
|
2300
|
-
});
|
|
2301
|
-
|
|
2302
|
-
// Apply vertical layout to the <input> elements only
|
|
2303
|
-
formattedHtml = formattedHtml.replace(/<input\s+([^>]*)\/>/g, (match, p1) => {
|
|
2304
|
-
// Reformat attributes into a vertical layout
|
|
2305
|
-
const attributes = p1.trim().split(/\s+/).map(attr => ` ${attr}`).join('\n');
|
|
2306
|
-
return `<input\n${attributes}\n/>`;
|
|
2307
|
-
});
|
|
2308
|
-
|
|
2309
|
-
// Ensure the <fieldset> block starts on a new line and remove extra blank lines
|
|
2310
|
-
formattedHtml = formattedHtml.replace(/(<fieldset\s+[^>]*>)/g, (match) => {
|
|
2311
|
-
// Ensure <fieldset> starts on a new line
|
|
2312
|
-
return `\n${match}\n`;
|
|
2313
|
-
}).replace(/\n\s*\n/g, '\n'); // Remove extra blank lines
|
|
2314
|
-
|
|
2315
|
-
return formattedHtml;
|
|
2316
|
-
}
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
renderCheckboxField(type, name, label, validate, attributes, bindingSyntax, options) {
|
|
2320
|
-
// Define valid validation attributes for checkbox fields
|
|
2321
|
-
const checkboxValidationAttributes = ['required'];
|
|
2322
|
-
|
|
2323
|
-
// Construct validation attributes
|
|
2324
|
-
let validationAttrs = '';
|
|
2325
|
-
if (validate) {
|
|
2326
|
-
Object.entries(validate).forEach(([key, value]) => {
|
|
2327
|
-
if (checkboxValidationAttributes.includes(key)) {
|
|
2328
|
-
if (key === 'required') {
|
|
2329
|
-
validationAttrs += `${key}\n`;
|
|
2330
|
-
}
|
|
2331
|
-
} else {
|
|
2332
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type '${type}'.\x1b[0m`);
|
|
2333
|
-
}
|
|
2334
|
-
});
|
|
2335
|
-
}
|
|
2336
|
-
|
|
2337
|
-
// Handle the binding syntax
|
|
2338
|
-
let bindingDirective = '';
|
|
2339
|
-
if (bindingSyntax === 'bind:checked') {
|
|
2340
|
-
bindingDirective = ` bind:checked="${name}"\n`;
|
|
2341
|
-
} else if (bindingSyntax.startsWith('::')) {
|
|
2342
|
-
bindingDirective = ` bind:checked="${name}"\n`;
|
|
2343
|
-
}
|
|
2344
|
-
|
|
2345
|
-
// Define attributes for the checkbox inputs
|
|
2346
|
-
let id = attributes.id || name;
|
|
2347
|
-
|
|
2348
|
-
// Handle additional attributes
|
|
2349
|
-
let additionalAttrs = '';
|
|
2350
|
-
for (const [key, value] of Object.entries(attributes)) {
|
|
2351
|
-
if (key !== 'id' && value !== undefined) {
|
|
2352
|
-
if (key.startsWith('on')) {
|
|
2353
|
-
// Handle event attributes
|
|
2354
|
-
const eventValue = value.endsWith('()') ? value.slice(0, -2) : value;
|
|
2355
|
-
additionalAttrs += ` @${key.replace(/^on/, '')}={${eventValue}}\n`;
|
|
2356
|
-
} else {
|
|
2357
|
-
// Handle boolean attributes
|
|
2358
|
-
if (value === true) {
|
|
2359
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}\n`;
|
|
2360
|
-
} else if (value !== false) {
|
|
2361
|
-
// Convert underscores to hyphens and set the attribute
|
|
2362
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}="${value}"\n`;
|
|
2363
|
-
}
|
|
2364
|
-
}
|
|
2365
|
-
}
|
|
2366
|
-
}
|
|
2367
|
-
|
|
2368
|
-
// Construct checkbox HTML based on options
|
|
2369
|
-
let optionsHTML = '';
|
|
2370
|
-
if (Array.isArray(options)) {
|
|
2371
|
-
optionsHTML = options.map((option) => {
|
|
2372
|
-
const optionId = `${id}-${option.value}`;
|
|
2373
|
-
return `
|
|
2374
|
-
<div>
|
|
2375
|
-
<input type="checkbox" name="${name}" value="${option.value}"${bindingDirective} ${additionalAttrs}
|
|
2376
|
-
${attributes.id ? `id="${optionId}"` : `id="${optionId}"`}
|
|
2377
|
-
/>
|
|
2378
|
-
<label for="${optionId}">${option.label}</label>
|
|
2379
|
-
</div>
|
|
2380
|
-
`;
|
|
2381
|
-
}).join('');
|
|
2382
|
-
}
|
|
2383
|
-
|
|
2384
|
-
// Construct the final HTML string
|
|
2385
|
-
let formHTML = `
|
|
2386
|
-
<fieldset class="${this.checkboxGroupClass}">
|
|
2387
|
-
<legend>${label}</legend>
|
|
2388
|
-
${optionsHTML}
|
|
2389
|
-
</fieldset>
|
|
2390
|
-
`.replace(/^\s*\n/gm, '').trim();
|
|
2391
|
-
|
|
2392
|
-
// Format the entire HTML using pretty
|
|
2393
|
-
let formattedHtml = pretty(formHTML, {
|
|
2394
|
-
indent_size: 2,
|
|
2395
|
-
wrap_line_length: 0,
|
|
2396
|
-
preserve_newlines: true, // Preserve existing newlines
|
|
2397
|
-
});
|
|
2398
|
-
|
|
2399
|
-
// Apply vertical layout to the <input> elements only
|
|
2400
|
-
formattedHtml = formattedHtml.replace(/<input\s+([^>]*)\/>/g, (match, p1) => {
|
|
2401
|
-
// Reformat attributes into a vertical layout
|
|
2402
|
-
const attributes = p1.trim().split(/\s+/).map(attr => ` ${attr}`).join('\n');
|
|
2403
|
-
return `<input\n${attributes}\n/>`;
|
|
2404
|
-
});
|
|
2405
|
-
|
|
2406
|
-
// Ensure the <fieldset> block starts on a new line and remove extra blank lines
|
|
2407
|
-
formattedHtml = formattedHtml.replace(/(<fieldset\s+[^>]*>)/g, (match) => {
|
|
2408
|
-
// Ensure <fieldset> starts on a new line
|
|
2409
|
-
return `\n${match}\n`;
|
|
2410
|
-
}).replace(/\n\s*\n/g, '\n'); // Remove extra blank lines
|
|
2411
|
-
|
|
2412
|
-
return formattedHtml;
|
|
2413
|
-
}
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
renderSingleSelectField(type, name, label, validate, attributes, bindingSyntax, options) {
|
|
2418
|
-
// Define valid validation attributes for select fields
|
|
2419
|
-
const selectValidationAttributes = ['required'];
|
|
2420
|
-
|
|
2421
|
-
// Construct validation attributes
|
|
2422
|
-
let validationAttrs = '';
|
|
2423
|
-
if (validate) {
|
|
2424
|
-
Object.entries(validate).forEach(([key, value]) => {
|
|
2425
|
-
if (selectValidationAttributes.includes(key)) {
|
|
2426
|
-
if (key === 'required') {
|
|
2427
|
-
validationAttrs += `${key} `;
|
|
2428
|
-
}
|
|
2429
|
-
} else {
|
|
2430
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type '${type}'.\x1b[0m`);
|
|
2431
|
-
}
|
|
2432
|
-
});
|
|
2433
|
-
}
|
|
2434
|
-
|
|
2435
|
-
// Handle the binding syntax
|
|
2436
|
-
let bindingDirective = '';
|
|
2437
|
-
if (typeof bindingSyntax === 'string' && bindingSyntax.startsWith('::')) {
|
|
2438
|
-
bindingDirective = ` bind:value="${name}" `;
|
|
2439
|
-
}
|
|
2440
|
-
|
|
2441
|
-
// Define attributes for the select field
|
|
2442
|
-
let id = attributes.id || name;
|
|
2443
|
-
let dimensionAttrs = ''; // No dimension attributes applicable for select fields
|
|
2444
|
-
|
|
2445
|
-
// Handle additional attributes
|
|
2446
|
-
let additionalAttrs = '';
|
|
2447
|
-
for (const [key, value] of Object.entries(attributes)) {
|
|
2448
|
-
if (key !== 'id' && value !== undefined) {
|
|
2449
|
-
if (key.startsWith('on')) {
|
|
2450
|
-
// Handle event attributes
|
|
2451
|
-
const eventValue = value.endsWith('()') ? value.slice(0, -2) : value;
|
|
2452
|
-
additionalAttrs += ` @${key.replace(/^on/, '')}={${eventValue}}\n`;
|
|
2453
|
-
} else {
|
|
2454
|
-
// Handle boolean attributes
|
|
2455
|
-
if (value === true) {
|
|
2456
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}\n`;
|
|
2457
|
-
} else if (value !== false) {
|
|
2458
|
-
// Convert underscores to hyphens and set the attribute
|
|
2459
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}="${value}"\n`;
|
|
2460
|
-
}
|
|
2461
|
-
}
|
|
2462
|
-
}
|
|
2463
|
-
}
|
|
2464
|
-
|
|
2465
|
-
// Construct select options HTML based on options
|
|
2466
|
-
let selectHTML = '';
|
|
2467
|
-
if (Array.isArray(options)) {
|
|
2468
|
-
// Add a default option
|
|
2469
|
-
selectHTML += `
|
|
2470
|
-
<option value="">Choose an option</option>
|
|
2471
|
-
`;
|
|
2472
|
-
|
|
2473
|
-
// Add the provided options
|
|
2474
|
-
selectHTML += options.map((option) => {
|
|
2475
|
-
const isSelected = option.selected ? ' selected' : '';
|
|
2476
|
-
return `
|
|
2477
|
-
<option value="${option.value}"${isSelected}>${option.label}</option>
|
|
2478
|
-
`;
|
|
2479
|
-
}).join('');
|
|
2480
|
-
}
|
|
2481
|
-
|
|
2482
|
-
// Construct the final HTML string
|
|
2483
|
-
let formHTML = `
|
|
2484
|
-
<fieldset class="${this.selectGroupClass}">
|
|
2485
|
-
<label for="${id}">${label}</label>
|
|
2486
|
-
<select name="${name}"
|
|
2487
|
-
${bindingDirective}
|
|
2488
|
-
${dimensionAttrs}
|
|
2489
|
-
id="${id}"
|
|
2490
|
-
${additionalAttrs}
|
|
2491
|
-
${validationAttrs}
|
|
2492
|
-
>
|
|
2493
|
-
${selectHTML}
|
|
2494
|
-
</select>
|
|
2495
|
-
</fieldset>
|
|
2496
|
-
`.replace(/^\s*\n/gm, '').trim();
|
|
2497
|
-
|
|
2498
|
-
// Format the entire HTML using pretty
|
|
2499
|
-
let formattedHtml = pretty(formHTML, {
|
|
2500
|
-
indent_size: 2,
|
|
2501
|
-
wrap_line_length: 0,
|
|
2502
|
-
preserve_newlines: true, // Preserve existing newlines
|
|
2503
|
-
});
|
|
2504
|
-
|
|
2505
|
-
// Apply vertical layout to the <select> element and its children
|
|
2506
|
-
formattedHtml = formattedHtml.replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g, (match, p1, p2) => {
|
|
2507
|
-
// Reformat attributes into a vertical layout
|
|
2508
|
-
const attributes = p1.trim().split(/\s+/).map(attr => ` ${attr}`).join('\n');
|
|
2509
|
-
return `<select\n${attributes}\n>\n${p2.trim()}\n</select>`;
|
|
2510
|
-
});
|
|
2511
|
-
|
|
2512
|
-
// Ensure the <fieldset> block starts on a new line and remove extra blank lines
|
|
2513
|
-
formattedHtml = formattedHtml.replace(/(<fieldset\s+[^>]*>)/g, (match) => {
|
|
2514
|
-
// Ensure <fieldset> starts on a new line
|
|
2515
|
-
return `\n${match}\n`;
|
|
2516
|
-
}).replace(/\n\s*\n/g, '\n'); // Remove extra blank lines
|
|
2517
|
-
|
|
2518
|
-
return formattedHtml;
|
|
2519
|
-
}
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
renderMultipleSelectField(type, name, label, validate, attributes, bindingSyntax, options) {
|
|
2525
|
-
// Define valid validation attributes for multiple select fields
|
|
2526
|
-
const selectValidationAttributes = ['required', 'minlength', 'maxlength'];
|
|
2527
|
-
|
|
2528
|
-
// Construct validation attributes
|
|
2529
|
-
let validationAttrs = '';
|
|
2530
|
-
if (validate) {
|
|
2531
|
-
Object.entries(validate).forEach(([key, value]) => {
|
|
2532
|
-
if (selectValidationAttributes.includes(key)) {
|
|
2533
|
-
if (key === 'required') {
|
|
2534
|
-
validationAttrs += `${key} `;
|
|
2535
|
-
} else if (key === 'minlength') {
|
|
2536
|
-
validationAttrs += `minlength="${value}" `;
|
|
2537
|
-
} else if (key === 'maxlength') {
|
|
2538
|
-
validationAttrs += `maxlength="${value}" `;
|
|
2539
|
-
}
|
|
2540
|
-
} else {
|
|
2541
|
-
console.warn(`\x1b[31mUnsupported validation attribute '${key}' for field '${name}' of type '${type}'.\x1b[0m`);
|
|
2542
|
-
}
|
|
2543
|
-
});
|
|
2544
|
-
}
|
|
2545
|
-
|
|
2546
|
-
// Handle the binding syntax
|
|
2547
|
-
let bindingDirective = '';
|
|
2548
|
-
if (typeof bindingSyntax === 'string' && bindingSyntax.startsWith('::')) {
|
|
2549
|
-
bindingDirective = ` bind:value="${name}" `;
|
|
2550
|
-
}
|
|
2551
|
-
|
|
2552
|
-
// Define attributes for the select field
|
|
2553
|
-
let id = attributes.id || name;
|
|
2554
|
-
let dimensionAttrs = ''; // No dimension attributes applicable for select fields
|
|
2555
|
-
|
|
2556
|
-
// Handle additional attributes
|
|
2557
|
-
let additionalAttrs = '';
|
|
2558
|
-
for (const [key, value] of Object.entries(attributes)) {
|
|
2559
|
-
if (key !== 'id' && value !== undefined) {
|
|
2560
|
-
if (key.startsWith('on')) {
|
|
2561
|
-
// Handle event attributes
|
|
2562
|
-
const eventValue = value.endsWith('()') ? value.slice(0, -2) : value;
|
|
2563
|
-
additionalAttrs += ` @${key.replace(/^on/, '')}={${eventValue}}\n`;
|
|
2564
|
-
} else {
|
|
2565
|
-
// Handle boolean attributes
|
|
2566
|
-
if (value === true) {
|
|
2567
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}\n`;
|
|
2568
|
-
} else if (value !== false) {
|
|
2569
|
-
// Convert underscores to hyphens and set the attribute
|
|
2570
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}="${value}"\n`;
|
|
2571
|
-
}
|
|
2572
|
-
}
|
|
2573
|
-
}
|
|
2574
|
-
}
|
|
2575
|
-
|
|
2576
|
-
// Construct select options HTML based on options
|
|
2577
|
-
let selectHTML = '';
|
|
2578
|
-
if (Array.isArray(options)) {
|
|
2579
|
-
selectHTML = options.map((option) => {
|
|
2580
|
-
const isSelected = option.selected ? ' selected' : '';
|
|
2581
|
-
return `
|
|
2582
|
-
<option value="${option.value}"${isSelected}>${option.label}</option>
|
|
2583
|
-
`;
|
|
2584
|
-
}).join('');
|
|
2585
|
-
}
|
|
2586
|
-
|
|
2587
|
-
// Define multiple attribute for multi-select
|
|
2588
|
-
const multipleAttr = 'multiple';
|
|
2589
|
-
|
|
2590
|
-
// Construct the final HTML string
|
|
2591
|
-
let formHTML = `
|
|
2592
|
-
<fieldset class="${this.selectGroupClass}">
|
|
2593
|
-
<label for="${id}">${label}</label>
|
|
2594
|
-
<select name="${name}"
|
|
2595
|
-
${bindingDirective}
|
|
2596
|
-
${dimensionAttrs}
|
|
2597
|
-
id="${id}"
|
|
2598
|
-
${additionalAttrs}
|
|
2599
|
-
${validationAttrs}
|
|
2600
|
-
${multipleAttr}
|
|
2601
|
-
>
|
|
2602
|
-
${selectHTML}
|
|
2603
|
-
</select>
|
|
2604
|
-
</fieldset>
|
|
2605
|
-
`.replace(/^\s*\n/gm, '').trim();
|
|
2606
|
-
|
|
2607
|
-
// Format the entire HTML using pretty
|
|
2608
|
-
let formattedHtml = pretty(formHTML, {
|
|
2609
|
-
indent_size: 2,
|
|
2610
|
-
wrap_line_length: 0,
|
|
2611
|
-
preserve_newlines: true, // Preserve existing newlines
|
|
2612
|
-
});
|
|
2613
|
-
|
|
2614
|
-
// Apply vertical layout to the <select> element and its children
|
|
2615
|
-
formattedHtml = formattedHtml.replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g, (match, p1, p2) => {
|
|
2616
|
-
// Reformat attributes into a vertical layout
|
|
2617
|
-
const attributes = p1.trim().split(/\s+/).map(attr => ` ${attr}`).join('\n');
|
|
2618
|
-
return `<select\n${attributes}\n>\n${p2.trim()}\n</select>`;
|
|
2619
|
-
});
|
|
2620
|
-
|
|
2621
|
-
// Ensure the <fieldset> block starts on a new line and remove extra blank lines
|
|
2622
|
-
formattedHtml = formattedHtml.replace(/(<fieldset\s+[^>]*>)/g, (match) => {
|
|
2623
|
-
// Ensure <fieldset> starts on a new line
|
|
2624
|
-
return `\n${match}\n`;
|
|
2625
|
-
}).replace(/\n\s*\n/g, '\n'); // Remove extra blank lines
|
|
2626
|
-
|
|
2627
|
-
return formattedHtml;
|
|
2628
|
-
}
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
renderSubmitButton(type, name, label, attributes) {
|
|
2633
|
-
// Define id attribute or fallback to name
|
|
2634
|
-
const id = attributes.id || name;
|
|
2635
|
-
|
|
2636
|
-
// Handle additional attributes
|
|
2637
|
-
let additionalAttrs = '';
|
|
2638
|
-
for (const [key, value] of Object.entries(attributes)) {
|
|
2639
|
-
if (key !== 'id' && value !== undefined) {
|
|
2640
|
-
if (key.startsWith('on')) {
|
|
2641
|
-
// Handle event attributes
|
|
2642
|
-
const eventValue = value.endsWith('()') ? value.slice(0, -2) : value;
|
|
2643
|
-
additionalAttrs += ` ${key}="${eventValue}"`;
|
|
2644
|
-
} else {
|
|
2645
|
-
// Handle boolean attributes
|
|
2646
|
-
if (value === true) {
|
|
2647
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}`;
|
|
2648
|
-
} else if (value !== false) {
|
|
2649
|
-
// Convert underscores to hyphens and set the attribute
|
|
2650
|
-
additionalAttrs += ` ${key.replace(/_/g, '-')}="${value}"`;
|
|
2651
|
-
}
|
|
2652
|
-
}
|
|
2653
|
-
}
|
|
2654
|
-
}
|
|
2655
|
-
|
|
2656
|
-
// Construct the final HTML string
|
|
2657
|
-
const formHTML = `
|
|
2658
|
-
<input type="${type}"
|
|
2659
|
-
id="${id}"
|
|
2660
|
-
value="${label}"
|
|
2661
|
-
${additionalAttrs}
|
|
2662
|
-
/>
|
|
2663
|
-
`.replace(/^\s*\n/gm, '').trim();
|
|
2664
|
-
|
|
2665
|
-
// Format the entire HTML using pretty
|
|
2666
|
-
const formattedHtml = pretty(formHTML, {
|
|
2667
|
-
indent_size: 2,
|
|
2668
|
-
wrap_line_length: 0,
|
|
2669
|
-
preserve_newlines: true, // Preserve existing newlines
|
|
2670
|
-
});
|
|
2671
|
-
|
|
2672
|
-
return formattedHtml;
|
|
2673
|
-
}
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
renderFormHTML () {
|
|
2680
|
-
|
|
2681
|
-
this.formMarkUp+= '</form>';
|
|
2682
|
-
const formContainer = document.getElementById('formique');
|
|
2683
|
-
formContainer.innerHTML = this.formMarkUp;
|
|
2684
|
-
//return this.formMarkUp;
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
}
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
// no renderMethod below here
|
|
2693
|
-
}
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
export default Formique;
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
/*
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
const formSchema = [
|
|
2716
|
-
['text', 'firstName', 'First Name', { minlength: 2, maxlength: 5, required: true, disabled: true}, { value: "John", id: 'firstNameInput', class: 'form-input', style: 'width: 100%;', oninput: "incrementer()"}, '::firstName'],
|
|
2717
|
-
['email', 'email', 'Email', { required: true}, { class: 'form-input', style: 'width: 100%;'}, '::emailValue'],
|
|
2718
|
-
['number', 'age', 'Your Age', {required: false}, { id: 'age12'}, '::age'],
|
|
2719
|
-
['password', 'password', 'Password', { minlength: 8, required: true }, { class: 'form-control', style: 'width: 100%;' }, '::passwordValue'],
|
|
2720
|
-
['tel', 'phoneNumber', 'Phone Number', { required: true }, { class: 'form-control', style: 'width: 100%;' }, '::telValue'],
|
|
2721
|
-
['date', 'birthdate', 'Birth Date', { required: true }, { id: 'birthdateInput', class: 'form-control', style: 'width: 100%;' }, '::date'],
|
|
2722
|
-
['time', 'meetingTime', 'Meeting Time', { required: true }, { id: 'meetingTimeInput', class: 'form-control', style: 'width: 100%;' }, '::time'],
|
|
2723
|
-
['datetime-local', 'meetingDateTime', 'Meeting Date & Time', { required: true }, { id: 'meetingDateTimeInput', class: 'form-control', style: 'width: 100%;' }, '::meetingDateTime'],
|
|
2724
|
-
['month', 'eventMonth', 'Event Month', { required: true }, { id: 'eventMonthInput', class: 'form-control', style: 'width: 100%;' }, '::eventMonth'],
|
|
2725
|
-
['week', 'eventWeek', 'Event Week', { required: true }, { id: 'eventWeekInput', class: 'form-control', style: 'width: 100%;' }, '::eventWeek'],
|
|
2726
|
-
['url', 'websiteUrl', 'Website URL', { required: true}, { id: 'websiteUrlInput', class: 'form-control', style: 'width: 100%;' }, 'bind:value'],
|
|
2727
|
-
['search', 'searchQuery', 'Search', { required: true }, { id: 'searchQueryInput', class: 'form-control', style: 'width: 100%;' }, '::searchQuery'],
|
|
2728
|
-
['color', 'colorPicker', 'Pick a Color', { required: true }, { id: 'colorPickerInput', class: 'form-control', style: 'width: 100%;' }, '::colorValue'],
|
|
2729
|
-
['file', 'terms', 'Upload File', { required: true }, { id: 'my-file', class: 'form-control', style: 'width: 100%;' }, 'bind:value'],
|
|
2730
|
-
['hidden', 'user_id', '', { required: true }, {}, '::user_id'],
|
|
2731
|
-
['image','profilePicture','Profile Picture', { required: true, accept: 'image/*' },
|
|
2732
|
-
{ id: 'profilePictureInput', class: 'form-control', style: 'width: 100%;' },
|
|
2733
|
-
'bind:value'],
|
|
2734
|
-
['textarea', 'comments', 'Comments',
|
|
2735
|
-
{ required: true, minlength: 10, maxlength: 200, rows: 4, cols: 50 },
|
|
2736
|
-
{ id: 'commentsTextarea', class: 'form-control', style: 'width: 100%; height: 100px;' },
|
|
2737
|
-
'::comments'],
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
[
|
|
2741
|
-
'radio',
|
|
2742
|
-
'gender',
|
|
2743
|
-
'Gender',
|
|
2744
|
-
{ required: true },
|
|
2745
|
-
{ id: 'genderRadio', class: 'form-radio-input', style: 'margin-left: 1rem;', onchange: 'actioner()' },
|
|
2746
|
-
'::gender',
|
|
2747
|
-
[
|
|
2748
|
-
{ value: 'male', label: 'Male' },
|
|
2749
|
-
{ value: 'female', label: 'Female' },
|
|
2750
|
-
{ value: 'other', label: 'Other' },
|
|
2751
|
-
]
|
|
2752
|
-
],
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
[
|
|
2756
|
-
'checkbox',
|
|
2757
|
-
'preferences',
|
|
2758
|
-
'Preferences',
|
|
2759
|
-
{ required: true },
|
|
2760
|
-
{ id: 'preferencesCheckbox', class: 'form-checkbox-input', style: 'margin-left: 1rem;', onchange: 'submit' },
|
|
2761
|
-
'::preferences',
|
|
2762
|
-
[
|
|
2763
|
-
{ value: 'news', label: 'Newsletter' },
|
|
2764
|
-
{ value: 'updates', label: 'Product Updates' },
|
|
2765
|
-
{ value: 'offers', label: 'Special Offers' },
|
|
2766
|
-
]
|
|
2767
|
-
],
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
[
|
|
2772
|
-
'singleSelect',
|
|
2773
|
-
'colors',
|
|
2774
|
-
'Colors',
|
|
2775
|
-
{ required: true }, // Validation options
|
|
2776
|
-
{ id: 'colorsSelect', class: 'form-select-input', style: 'margin-left: 1rem;', onchange: 'trigger' }, // Attributes
|
|
2777
|
-
'::colors', // Binding syntax
|
|
2778
|
-
[
|
|
2779
|
-
{ value: 'red', label: 'Red', selected: false },
|
|
2780
|
-
{ value: 'green', label: 'Green'},
|
|
2781
|
-
{ value: 'blue', label: 'Blue', selected: true},
|
|
2782
|
-
] // Options
|
|
2783
|
-
],
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
[
|
|
2788
|
-
'multipleSelect', // Type of field
|
|
2789
|
-
'colors', // Name/identifier of the field
|
|
2790
|
-
'Colors', // Label of the field
|
|
2791
|
-
{ required: true, min: 2, max: 3 }, // Validation options
|
|
2792
|
-
{ id: 'colorsSelect', class: 'form-select-input', style: 'margin-left: 1rem;', onchange: 'alerter' }, // Attributes
|
|
2793
|
-
'::colors', // Binding syntax
|
|
2794
|
-
[
|
|
2795
|
-
{ value: 'red', label: 'Red' },
|
|
2796
|
-
{ value: 'green', label: 'Green' },
|
|
2797
|
-
{ value: 'blue', label: 'Blue', selected: false },
|
|
2798
|
-
{ value: 'yellow', label: 'Yellow', selected: false },
|
|
2799
|
-
] // Options
|
|
2800
|
-
],
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
[
|
|
2804
|
-
'submit',
|
|
2805
|
-
'submitButton',
|
|
2806
|
-
'Submit',
|
|
2807
|
-
{ required: true },
|
|
2808
|
-
{ id: 'submitBtn', class: 'form-submit-btn', style: 'margin-top: 1rem;' }
|
|
2809
|
-
],
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
];
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
*/
|
|
2818
|
-
|
|
2819
|
-
const formSchema = [
|
|
2820
|
-
// Text Input Field
|
|
2821
|
-
[
|
|
2822
|
-
'text',
|
|
2823
|
-
'firstName',
|
|
2824
|
-
'First Name',
|
|
2825
|
-
{ minlength: 2, maxlength: 5, required: true, disabled: true }, // Validation options
|
|
2826
|
-
{ value: "John", id: 'firstNameInput', class: 'form-input', style: 'width: 100%;', oninput: "incrementer()" }, // Attributes
|
|
2827
|
-
'::firstName' // Binding syntax
|
|
2828
|
-
],
|
|
2829
|
-
|
|
2830
|
-
// URL Input Field
|
|
2831
|
-
[
|
|
2832
|
-
'url',
|
|
2833
|
-
'websiteUrl',
|
|
2834
|
-
'Website URL',
|
|
2835
|
-
{ required: true }, // Validation options
|
|
2836
|
-
{ id: 'websiteUrlInput', class: 'form-control', style: 'width: 100%;' }, // Attributes
|
|
2837
|
-
'bind:value' // Binding syntax
|
|
2838
|
-
],
|
|
2839
|
-
|
|
2840
|
-
// Radio Input Field
|
|
2841
|
-
[
|
|
2842
|
-
'radio',
|
|
2843
|
-
'gender',
|
|
2844
|
-
'Gender',
|
|
2845
|
-
{ required: true }, // Validation options
|
|
2846
|
-
{ id: 'genderRadio', class: 'form-radio-input', style: 'margin-left: 1rem;', onchange: 'actioner()' }, // Attributes
|
|
2847
|
-
'::gender', // Binding syntax
|
|
2848
|
-
[
|
|
2849
|
-
{ value: 'male', label: 'Male' }, // Options
|
|
2850
|
-
{ value: 'female', label: 'Female' },
|
|
2851
|
-
{ value: 'other', label: 'Other' }
|
|
2852
|
-
]
|
|
2853
|
-
],
|
|
2854
|
-
|
|
2855
|
-
// Checkbox Input Field
|
|
2856
|
-
[
|
|
2857
|
-
'checkbox',
|
|
2858
|
-
'preferences',
|
|
2859
|
-
'Preferences',
|
|
2860
|
-
{ required: true }, // Validation options
|
|
2861
|
-
{ id: 'preferencesCheckbox', class: 'form-checkbox-input', style: 'margin-left: 1rem;', onchange: 'submit' }, // Attributes
|
|
2862
|
-
'::preferences', // Binding syntax
|
|
2863
|
-
[
|
|
2864
|
-
{ value: 'news', label: 'Newsletter' }, // Options
|
|
2865
|
-
{ value: 'updates', label: 'Product Updates' },
|
|
2866
|
-
{ value: 'offers', label: 'Special Offers' }
|
|
2867
|
-
]
|
|
2868
|
-
],
|
|
2869
|
-
|
|
2870
|
-
// Single Select Input Field
|
|
2871
|
-
[
|
|
2872
|
-
'singleSelect',
|
|
2873
|
-
'colors',
|
|
2874
|
-
'Colors',
|
|
2875
|
-
{ required: true }, // Validation options
|
|
2876
|
-
{ id: 'colorsSelect', class: 'form-select-input', style: 'margin-left: 1rem;', onchange: 'trigger' }, // Attributes
|
|
2877
|
-
'::colors', // Binding syntax
|
|
2878
|
-
[
|
|
2879
|
-
{ value: 'red', label: 'Red' }, // Options
|
|
2880
|
-
{ value: 'green', label: 'Green' },
|
|
2881
|
-
{ value: 'blue', label: 'Blue', selected: true }
|
|
2882
|
-
]
|
|
2883
|
-
],
|
|
2884
|
-
|
|
2885
|
-
// Multiple Select Input Field
|
|
2886
|
-
[
|
|
2887
|
-
'multipleSelect', // Type of field
|
|
2888
|
-
'colors', // Name/identifier of the field
|
|
2889
|
-
'Colors', // Label of the field
|
|
2890
|
-
{ required: true, min: 2, max: 3 }, // Validation options
|
|
2891
|
-
{ id: 'colorsSelect', class: 'form-select-input', style: 'margin-left: 1rem;', onchange: 'alerter' }, // Attributes
|
|
2892
|
-
'::colors', // Binding syntax
|
|
2893
|
-
[
|
|
2894
|
-
{ value: 'red', label: 'Red' }, // Options
|
|
2895
|
-
{ value: 'green', label: 'Green' },
|
|
2896
|
-
{ value: 'blue', label: 'Blue' },
|
|
2897
|
-
{ value: 'yellow', label: 'Yellow' }
|
|
2898
|
-
]
|
|
2899
|
-
],
|
|
2900
|
-
|
|
2901
|
-
// Submit Button
|
|
2902
|
-
[
|
|
2903
|
-
'submit',
|
|
2904
|
-
'submitButton',
|
|
2905
|
-
'Submit',
|
|
2906
|
-
{ required: true }, // Validation options
|
|
2907
|
-
{ id: 'submitBtn', class: 'form-submit-btn', style: 'margin-top: 1rem;' } // Attributes
|
|
2908
|
-
]
|
|
2909
|
-
];
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
const formParams= {
|
|
2914
|
-
method: 'post',
|
|
2915
|
-
action: 'submit.js',
|
|
2916
|
-
id: 'myForm',
|
|
2917
|
-
class: 'form',
|
|
2918
|
-
semantq: true,
|
|
2919
|
-
style: 'width: 100%; font-size: 14px;',
|
|
2920
|
-
//enctype: 'multipart/form-data',
|
|
2921
|
-
//target: '_blank',
|
|
2922
|
-
//nonvalidate: true,
|
|
2923
|
-
//accept_charset: 'UTF-8',
|
|
2924
|
-
};
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
// Instantiate the form
|
|
2928
|
-
const form = new Formique(formParams, formSchema);
|
|
2929
|
-
const formHTML = form.renderFormHTML();
|
|
2930
|
-
console.log(formHTML);
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|