voc-lib-js 1.0.20 → 1.0.22
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 +188 -120
- package/dist/main.global.js +2 -1
- package/dist/main.js +2 -1
- package/dist/main.mjs +2 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,195 +1,263 @@
|
|
|
1
1
|
# Vocphone JavaScript Library
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Lightweight form rendering and submission helper for VocPhone projects. This library renders JSON-driven forms into the DOM, collects values (FormData or plain objects), and supports auto-submit to an API endpoint.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Quick start
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Install dependencies and build (if developing locally):
|
|
8
|
+
|
|
9
|
+
```powershell
|
|
8
10
|
npm install
|
|
11
|
+
npm run build
|
|
9
12
|
```
|
|
10
13
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
## CDN
|
|
14
|
+
Include the bundle from a CDN (UMD/global) or import as a module in your app.
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
## CDN usage
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
CommonJS (global UMD bundle):
|
|
18
19
|
|
|
19
20
|
```html
|
|
20
21
|
<div id="render-form"></div>
|
|
21
|
-
|
|
22
22
|
<script src="https://cdn.jsdelivr.net/npm/voc-lib-js@latest/dist/main.global.js"></script>
|
|
23
23
|
<script>
|
|
24
|
-
VocLibJs
|
|
24
|
+
// global namespace is `VocLibJs` (example)
|
|
25
|
+
const rendered = VocLibJs.FormsLib.renderForm('#render-form', formSchema);
|
|
26
|
+
rendered.onSubmit((data) => {
|
|
27
|
+
// `data` is a FormData by default
|
|
28
|
+
console.log([...data.entries()]);
|
|
29
|
+
});
|
|
25
30
|
</script>
|
|
26
31
|
```
|
|
27
32
|
|
|
28
|
-
|
|
33
|
+
ES Module (module bundle):
|
|
29
34
|
|
|
30
35
|
```html
|
|
31
|
-
<div id="
|
|
36
|
+
<div id="render-form"></div>
|
|
32
37
|
<script type="module">
|
|
33
|
-
import { FormsLib } from
|
|
34
|
-
|
|
35
|
-
|
|
38
|
+
import { FormsLib } from 'https://cdn.jsdelivr.net/npm/voc-lib-js@latest/dist/main.mjs';
|
|
39
|
+
const rendered = FormsLib.renderForm('#render-form', formSchema);
|
|
40
|
+
// use rendered as needed
|
|
41
|
+
console.log(rendered.getValues(false)); // plain object
|
|
36
42
|
</script>
|
|
37
43
|
```
|
|
38
44
|
|
|
39
|
-
##
|
|
40
|
-
|
|
41
|
-
We can also use the package on any frontend framework like React, Angular, Vue, or vanilla.
|
|
45
|
+
## NPM / Framework usage
|
|
42
46
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
```bash
|
|
47
|
+
Install:
|
|
46
48
|
|
|
49
|
+
```powershell
|
|
47
50
|
npm install voc-lib-js
|
|
48
51
|
```
|
|
49
52
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
Example using Vue, this will work with any frontend framework
|
|
53
|
+
Example using Vue (works the same in React, Angular, Svelte, or vanilla JS):
|
|
53
54
|
|
|
54
55
|
```vue
|
|
55
56
|
<script setup>
|
|
56
|
-
import { onMounted, ref } from
|
|
57
|
-
import { FormsLib } from
|
|
57
|
+
import { onMounted, ref } from 'vue';
|
|
58
|
+
import { FormsLib } from 'voc-lib-js';
|
|
58
59
|
|
|
59
|
-
const
|
|
60
|
+
const formRef = ref(null);
|
|
60
61
|
|
|
61
62
|
onMounted(() => {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const values = form.value.getValues();
|
|
66
|
-
console.log("Initial form values:", values);
|
|
63
|
+
formRef.value = FormsLib.renderForm('#render-form', formSchema);
|
|
64
|
+
console.log('Initial values (object):', formRef.value.getValues(false));
|
|
67
65
|
});
|
|
68
66
|
</script>
|
|
69
67
|
|
|
70
68
|
<template>
|
|
71
|
-
<
|
|
72
|
-
<div id="render-form"></div>
|
|
73
|
-
</main>
|
|
69
|
+
<div id="render-form"></div>
|
|
74
70
|
</template>
|
|
75
71
|
```
|
|
76
72
|
|
|
77
|
-
##
|
|
73
|
+
## API Reference
|
|
78
74
|
|
|
79
|
-
|
|
75
|
+
Main function
|
|
80
76
|
|
|
81
|
-
|
|
77
|
+
renderForm(element, data, options?) => RenderedForm | null
|
|
82
78
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
79
|
+
- element: CSS selector string or HTMLElement
|
|
80
|
+
- data: form schema object (see 'Form schema' below)
|
|
81
|
+
- options: optional object
|
|
82
|
+
- onSubmit?: callback when auto-submit used
|
|
83
|
+
- onSubmitResult?: callback that receives (response, error) when submitConfig is used
|
|
84
|
+
- enableAutoSubmit?: boolean
|
|
85
|
+
- style?: "bootstrap" — add Bootstrap classes to inputs
|
|
86
|
+
- submitConfig?: SubmitConfig — alternative place to pass submit configuration
|
|
87
87
|
|
|
88
|
-
|
|
89
|
-
formRendered.onSubmit((data) => {
|
|
90
|
-
// `data` is a FormData instance
|
|
91
|
-
console.log(data.get('first_name'));
|
|
88
|
+
RenderedForm (returned object)
|
|
92
89
|
|
|
93
|
-
|
|
94
|
-
|
|
90
|
+
- element: HTMLFormElement — the generated form element
|
|
91
|
+
- validate(): returns Array<{ element: HTMLElement, message: string }> — list of invalid fields and messages
|
|
92
|
+
- getValues(asFormData = true): FormData | Record<string, any> — read form values. Default returns FormData. Pass false to get a plain object.
|
|
93
|
+
- onSubmit(callback): attach a submit listener that receives (data, event)
|
|
95
94
|
|
|
96
|
-
|
|
97
|
-
const file = data.get('upload'); // single File or null
|
|
98
|
-
const files = data.getAll('upload'); // array of File objects
|
|
95
|
+
SubmitConfig
|
|
99
96
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
</script>
|
|
105
|
-
```
|
|
97
|
+
- url: string — endpoint to post to
|
|
98
|
+
- method: one of GET | POST | PUT | PATCH | DELETE
|
|
99
|
+
- api_token?: string — optional Authorization token
|
|
100
|
+
- additional_data?: Record<string, any> — merged into payload
|
|
106
101
|
|
|
107
|
-
|
|
102
|
+
## Form schema
|
|
108
103
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
```
|
|
104
|
+
Top-level form object (Type: FormData in source)
|
|
105
|
+
|
|
106
|
+
- id: string — unique id for the form element
|
|
107
|
+
- code: string — optional code reference
|
|
108
|
+
- form_name: string — title displayed as an H2 inside the form
|
|
109
|
+
- default_values?: object — map of field name -> default value
|
|
110
|
+
- submit_config?: SubmitConfig — server submit configuration (optional)
|
|
111
|
+
- fields: array — list of Field objects (see below)
|
|
112
|
+
|
|
113
|
+
Field (BaseField)
|
|
120
114
|
|
|
121
|
-
|
|
122
|
-
-
|
|
123
|
-
-
|
|
124
|
-
-
|
|
115
|
+
- label?: string — visible label
|
|
116
|
+
- key: string — name for the input (used as name/id). If you need a different name, use `name`.
|
|
117
|
+
- name?: string — alternative to `key` (backwards compatibility)
|
|
118
|
+
- type?: string — one of: text, email, password, textarea, radio, select, checkbox, file, row
|
|
119
|
+
- placeholder?: string
|
|
120
|
+
- required?: boolean
|
|
121
|
+
- validation?: { min_length?: number, max_length?: number, regex?: string }
|
|
122
|
+
- hint_text?: string — small helper text below input
|
|
123
|
+
- direction?: 'horizontal' | 'vertical' — for radio/checkbox/row
|
|
124
|
+
- options?: [{ label, value }] — for radio/select/checkbox groups
|
|
125
|
+
- default?: string — default value for the field
|
|
126
|
+
- width?: string — CSS width (e.g. '100px', '50%')
|
|
127
|
+
- accept?: string — for file inputs (e.g. 'image/*')
|
|
128
|
+
- multiple?: boolean — for file inputs or multi-value fields
|
|
125
129
|
|
|
126
|
-
|
|
130
|
+
RowField (type: 'row') — contains `items: BaseField[]` and renders them horizontally by default.
|
|
127
131
|
|
|
128
|
-
##
|
|
132
|
+
## Example form schemas
|
|
129
133
|
|
|
130
|
-
|
|
134
|
+
1) Simple registration form
|
|
131
135
|
|
|
132
136
|
```json
|
|
133
137
|
{
|
|
138
|
+
"id": "user-registration",
|
|
139
|
+
"code": "reg_001",
|
|
134
140
|
"form_name": "User Registration",
|
|
135
|
-
|
|
141
|
+
"default_values": {
|
|
142
|
+
"country": "usa"
|
|
143
|
+
},
|
|
144
|
+
"fields": [
|
|
145
|
+
{ "label": "First name", "key": "first_name", "type": "text", "required": true },
|
|
146
|
+
{ "label": "Last name", "key": "last_name", "type": "text", "required": true },
|
|
147
|
+
{ "label": "Email", "key": "email", "type": "email", "required": true },
|
|
148
|
+
{ "label": "Password", "key": "password", "type": "password", "required": true },
|
|
149
|
+
{
|
|
150
|
+
"label": "Country",
|
|
151
|
+
"key": "country",
|
|
152
|
+
"type": "select",
|
|
153
|
+
"options": [
|
|
154
|
+
{ "label": "United States", "value": "usa" },
|
|
155
|
+
{ "label": "Canada", "value": "canada" }
|
|
156
|
+
]
|
|
157
|
+
}
|
|
158
|
+
]
|
|
136
159
|
}
|
|
137
160
|
```
|
|
138
161
|
|
|
139
|
-
|
|
162
|
+
2) Complex form: row, radio, checkbox, file
|
|
140
163
|
|
|
141
|
-
```
|
|
142
|
-
|
|
164
|
+
```json
|
|
165
|
+
{
|
|
166
|
+
"id": "survey-1",
|
|
167
|
+
"form_name": "Survey",
|
|
168
|
+
"fields": [
|
|
169
|
+
{
|
|
170
|
+
"type": "row",
|
|
171
|
+
"label": "Personal info",
|
|
172
|
+
"items": [
|
|
173
|
+
{ "label": "First name", "key": "first_name", "type": "text" },
|
|
174
|
+
{ "label": "Last name", "key": "last_name", "type": "text" }
|
|
175
|
+
]
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
"label": "Gender",
|
|
179
|
+
"key": "gender",
|
|
180
|
+
"type": "radio",
|
|
181
|
+
"options": [
|
|
182
|
+
{ "label": "Male", "value": "male" },
|
|
183
|
+
{ "label": "Female", "value": "female" }
|
|
184
|
+
],
|
|
185
|
+
"direction": "horizontal"
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
"label": "Hobbies",
|
|
189
|
+
"key": "hobbies",
|
|
190
|
+
"type": "checkbox",
|
|
191
|
+
"options": [
|
|
192
|
+
{ "label": "Sports", "value": "sports" },
|
|
193
|
+
{ "label": "Music", "value": "music" }
|
|
194
|
+
]
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
"label": "Upload resume",
|
|
198
|
+
"key": "resume",
|
|
199
|
+
"type": "file",
|
|
200
|
+
"accept": ".pdf,.doc,.docx"
|
|
201
|
+
}
|
|
202
|
+
]
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Handling values and submission
|
|
207
|
+
|
|
208
|
+
Use getValues() to retrieve form values. By default it returns a FormData instance which is ideal for file uploads. Pass false to get a plain object where repeated keys become arrays.
|
|
209
|
+
|
|
210
|
+
Example reading values:
|
|
211
|
+
|
|
212
|
+
```js
|
|
213
|
+
const rendered = FormsLib.renderForm('#render-form', formSchema);
|
|
214
|
+
// FormData (default)
|
|
215
|
+
const data = rendered.getValues();
|
|
216
|
+
console.log(data.get('email'));
|
|
217
|
+
|
|
218
|
+
// Plain object
|
|
219
|
+
const obj = rendered.getValues(false);
|
|
220
|
+
console.log(obj);
|
|
221
|
+
|
|
222
|
+
// Attach submit handler
|
|
223
|
+
rendered.onSubmit((data, event) => {
|
|
224
|
+
// If auto-submit isn't enabled, you can manually POST `data` using fetch.
|
|
225
|
+
console.log(data);
|
|
226
|
+
});
|
|
143
227
|
```
|
|
144
228
|
|
|
145
|
-
|
|
229
|
+
Auto-submit
|
|
146
230
|
|
|
147
|
-
|
|
231
|
+
If the schema includes `submit_config` or you pass `submitConfig` in options, the library will intercept the form submit and call the internal submit helper which posts to the configured endpoint. You can pass `onSubmitResult` in options to receive (response, error).
|
|
148
232
|
|
|
149
|
-
|
|
233
|
+
Example submit_config on the schema:
|
|
150
234
|
|
|
151
235
|
```json
|
|
152
236
|
{
|
|
153
|
-
|
|
237
|
+
"submit_config": {
|
|
238
|
+
"url": "https://api.example.com/forms/submit",
|
|
239
|
+
"method": "POST",
|
|
240
|
+
"api_token": "<token>",
|
|
241
|
+
"additional_data": { "source": "website" }
|
|
242
|
+
},
|
|
154
243
|
"fields": [
|
|
155
|
-
{
|
|
156
|
-
"label": "First Name",
|
|
157
|
-
"key": "first_name",
|
|
158
|
-
"type": "text",
|
|
159
|
-
"required": true
|
|
160
|
-
},
|
|
161
|
-
{
|
|
162
|
-
"label": "Last Name",
|
|
163
|
-
"key": "last_name",
|
|
164
|
-
"type": "text",
|
|
165
|
-
"required": true
|
|
166
|
-
},
|
|
167
244
|
...
|
|
168
245
|
]
|
|
169
246
|
}
|
|
170
247
|
```
|
|
171
248
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
-
|
|
175
|
-
-
|
|
176
|
-
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
- direction: string - horizontal or vertical - this mostly works when type is `row`, `radio`, or `checkbox` this will be the direction of the row.
|
|
188
|
-
- items: array - this will be used when type is `row`. the array contains object of fields.
|
|
189
|
-
- options: array - this will be used when type is `radio` or `select`. the array contains object of options.
|
|
190
|
-
- label: string - the label of the option
|
|
191
|
-
- value: string - the value of the option
|
|
192
|
-
- validation: object
|
|
193
|
-
- min_length: number
|
|
194
|
-
- max_length: number
|
|
195
|
-
- regex: string
|
|
249
|
+
## Developer notes / edge cases
|
|
250
|
+
|
|
251
|
+
- File inputs cannot be programmatically pre-filled for security reasons. Use `default_values` to display a filename elsewhere if needed.
|
|
252
|
+
- Validation: `validation.min_length` and `validation.max_length` map to element `minLength` and `maxLength`. `validation.regex` maps to `pattern` for inputs; for textareas it's stored in `data-pattern`.
|
|
253
|
+
- For checkbox groups, `getValues(false)` will return arrays when multiple options are checked.
|
|
254
|
+
|
|
255
|
+
## Contributing
|
|
256
|
+
|
|
257
|
+
1. Fork the repo and create a feature branch.
|
|
258
|
+
2. Run `npm install` and `npm run build` to test locally.
|
|
259
|
+
3. Open a PR with a clear description and include tests for new behavior where appropriate.
|
|
260
|
+
|
|
261
|
+
## License
|
|
262
|
+
|
|
263
|
+
MIT
|
package/dist/main.global.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
"use strict";var VocLibJs=(()=>{var w=Object.defineProperty;var
|
|
1
|
+
"use strict";var VocLibJs=(()=>{var w=Object.defineProperty;var q=Object.getOwnPropertyDescriptor;var D=Object.getOwnPropertyNames;var N=Object.prototype.hasOwnProperty;var $=(h,a)=>{for(var m in a)w(h,m,{get:a[m],enumerable:!0})},B=(h,a,m,d)=>{if(a&&typeof a=="object"||typeof a=="function")for(let f of D(a))!N.call(h,f)&&f!==m&&w(h,f,{get:()=>a[f],enumerable:!(d=q(a,f))||d.enumerable});return h};var V=h=>B(w({},"__esModule",{value:!0}),h);var O={};$(O,{FormsLib:()=>z,default:()=>P});function L(h,a=!0){let m=new FormData(h);if(a)return m;let d={};return m.forEach((f,u)=>{let g=(f instanceof File,f);Object.prototype.hasOwnProperty.call(d,u)?Array.isArray(d[u])?d[u].push(g):d[u]=[d[u],g]:d[u]=g}),d}async function M(h,a,m){let d=a.url,f={"Content-Type":"application/json"};a?.api_token&&(f.Authorization=`Bearer ${a.api_token}`);let u={...L(h,!1),...a.additional_data},g=JSON.stringify(u),i={method:a.method,headers:{Authorization:`Bearer ${a.api_token}`,"Content-Type":"application/json",Accept:"application/json"},...a.method==="GET"?{}:{body:g}};try{fetch(d,i).then(o=>{let y=o.headers.get("content-type");if(!o.ok){let E=o.text();throw new Error(`HTTP ${o.status}: ${E}`)}return y&&y.includes("application/json")?o.json():o.text()}).then(o=>{m&&m(o,null)}).catch(o=>{m&&m(null,o)})}catch(o){m&&m(null,o)}}function S(h,a,m){let d=[];if(typeof h=="string"?d=Array.from(document.querySelectorAll(h)):d=[h],d.length===0)return null;function f(){let i=m?.style==="bootstrap",o=document.createElement("form");o.classList.add("voc-form"),i&&o.classList.add("needs-validation"),o.id=a.id;let y=document.createElement("h2");y.textContent=a.form_name,o.appendChild(y);function E(e,l){l&&(l.min_length!==void 0&&(e.minLength=l.min_length),l.max_length!==void 0&&(e.maxLength=l.max_length),l.regex&&(e instanceof HTMLInputElement?e.pattern=l.regex:e.dataset.pattern=l.regex))}function C(e){if(!e.key&&!e.label)return null;let l=a.default_values||{},k=e.name||e.key,r=k?l[k]:void 0,b=document.createElement("div");if(b.className="voc-form-group",i&&b.classList.add("mb-3"),e.label){let t=document.createElement("label");t.classList.add("voc-form-label"),i&&t.classList.add("form-label"),e.key?e.type==="radio"?t.htmlFor="":t.htmlFor=`voc-form-${e.key}`:t.htmlFor="",t.textContent=e.label+(e.required?" *":""),b.appendChild(t)}let v=null;switch(e.type){case"checkbox":{let t=document.createElement("div");if(t.className="voc-form-checkbox-group "+(e.direction||"vertical"),e.width&&(t.style.width=e.width),e.options)e.options.forEach((n,c)=>{let p=document.createElement("label");p.classList.add("voc-form-checkbox-label"),i&&p.classList.add("form-check"),p.style.display=e.direction==="horizontal"?"inline-block":"block",e.width&&(p.style.width=e.width);let s=document.createElement("input");s.type="checkbox",s.classList.add("voc-form-checkbox"),i&&s.classList.add("form-check-input"),s.name=e.name||e.key||"",s.value=n.value,e.key&&(s.id=`voc-form-${e.key}-${c}`),e.required&&(s.required=!0),Array.isArray(r)?r.includes(n.value)&&(s.checked=!0):r!==void 0?r===n.value&&(s.checked=!0):e.default===n.value&&(s.checked=!0),p.appendChild(s),p.appendChild(document.createTextNode(n.label)),t.appendChild(p)});else{let n=document.createElement("label");n.classList.add("voc-form-checkbox-label"),i&&n.classList.add("form-check"),e.width&&(n.style.width=e.width);let c=document.createElement("input");c.type="checkbox",c.classList.add("voc-form-checkbox"),(e.key||e.name)&&(c.name=e.name||e.key,e.key&&(c.id=`voc-form-${e.key}`)),i&&c.classList.add("form-check-input"),e.required&&(c.required=!0),r!==void 0?c.checked=!!r:e.default&&(c.checked=!!e.default),n.appendChild(c),n.appendChild(document.createTextNode(e.label||"")),t.appendChild(n)}v=t;break}case"textarea":{let t=document.createElement("textarea");t.classList.add("voc-form-textarea"),i&&t.classList.add("form-control"),(e.key||e.name)&&(t.name=e.name||e.key,e.key&&(t.id=`voc-form-${e.key}`)),e.placeholder&&(t.placeholder=e.placeholder),r!=null?t.value=String(r):e.default!==void 0&&e.default!==null&&(t.value=String(e.default));let n=t.value||"";if(n&&(e.default||r)){let c=(n.match(/\n/g)||[]).length,p=80,s=n.split(`
|
|
2
|
+
`).reduce((H,R)=>Math.max(H,R.length),0),_=Math.ceil(s/p)||1,A=Math.max(2,c+_),T=20;t.rows=Math.min(A,T),t.style.height=`${T*1.2}em`,t.style.resize="vertical"}e.width&&(t.style.width=e.width),e.required&&(t.required=!0),E(t,e.validation),v=t;break}case"select":{let t=document.createElement("select");if(t.classList.add("voc-form-select"),i&&t.classList.add("form-select"),(e.key||e.name)&&(t.name=e.name||e.key,e.key&&(t.id=`voc-form-${e.key}`)),e.placeholder){let n=document.createElement("option");n.value="",n.textContent=e.placeholder,n.disabled=!0,n.selected=!0,t.appendChild(n)}e.required&&(t.required=!0),e.options&&e.options.forEach(n=>{let c=document.createElement("option");c.value=n.value,c.textContent=n.label,Array.isArray(r)?r.includes(n.value)&&(c.selected=!0):r!==void 0?r===n.value&&(c.selected=!0):e.default===n.value&&(c.selected=!0),t.appendChild(c)}),e.width&&(t.style.width=e.width),v=t;break}case"radio":{let t=document.createElement("div");t.className="voc-form-radio-group "+(e.direction||"vertical"),e.width&&(t.style.width=e.width),e.options&&e.options.forEach((n,c)=>{let p=document.createElement("label");p.classList.add("voc-form-radio-label"),i&&p.classList.add("form-check"),p.style.display=e.direction==="horizontal"?"inline-block":"block",e.width&&(p.style.width=e.width);let s=document.createElement("input");s.type="radio",s.classList.add("voc-form-radio"),i&&s.classList.add("form-check-input"),s.name=e.name||e.key||"",s.value=n.value,e.key&&(s.id=`voc-form-${e.key}-${c}`),Array.isArray(r)?r.includes(n.value)&&(s.checked=!0):r!==void 0?r===n.value&&(s.checked=!0):e.default===n.value&&(s.checked=!0),p.appendChild(s),p.appendChild(document.createTextNode(n.label)),t.appendChild(p)}),v=t;break}case"file":{let t=document.createElement("div");t.className="voc-form-file-wrapper",e.width&&(t.style.width=e.width);let n=document.createElement("input");n.type="file",n.classList.add("voc-form-file"),i&&n.classList.add("form-control"),(e.key||e.name)&&(n.name=e.name||e.key,e.key&&(n.id=`voc-form-${e.key}`)),e.width&&(n.style.width=e.width),e.required&&(n.required=!0),e.accept&&(n.accept=e.accept),e.multiple&&(n.multiple=!0),t.appendChild(n),v=t;break}default:{let t=document.createElement("input");t.type=e.type||"text",t.classList.add("voc-form-input"),i&&t.classList.add("form-control"),(e.key||e.name)&&(t.name=e.name||e.key,e.key&&(t.id=`voc-form-${e.key}`)),e.placeholder&&(t.placeholder=e.placeholder),r!=null?t.value=String(r):e.default!==void 0&&e.default!==null&&(t.value=String(e.default)),e.width&&(t.style.width=e.width),e.required&&(t.required=!0),E(t,e.validation),v=t;break}}if(v&&b.appendChild(v),e.hint_text){let t=document.createElement("small");t.className="voc-form-hint",t.textContent=e.hint_text,b.appendChild(t)}return b}a.fields.forEach(e=>{if(e.type==="row"&&"items"in e){let l=document.createElement("div");if(l.className="voc-form-group voc-form-row",i&&l.classList.add("mb-3"),e.label){let r=document.createElement("h3");r.className="voc-form-row-label",r.textContent=e.label,l.appendChild(r)}if(e.description){let r=document.createElement("p");r.className="voc-form-row-description",r.textContent=e.description,l.appendChild(r)}let k=document.createElement("div");k.className="voc-form-row-items "+(e.direction||"horizontal"),l.appendChild(k),e.items.forEach(r=>{let b=C(r);b&&k.appendChild(b)}),o.appendChild(l)}else{let l=C(e);l&&o.appendChild(l)}});let x=document.createElement("button");return x.type="submit",x.className="voc-form-submit",x.textContent="Submit",i&&x.classList.add("btn","btn-primary"),o.appendChild(x),o}let u=f();d[0].appendChild(u);let g=a?.submit_config??m?.submitConfig??null;return g&&u.addEventListener("submit",i=>{i.preventDefault(),M(u,g,(o,y)=>{m?.onSubmitResult&&m.onSubmitResult(o,y)})}),{element:u,validate:()=>{let i=[];return u.querySelectorAll(":invalid").forEach(y=>{let E=y.validationMessage;i.push({element:y,message:E})}),i},getValues:()=>L(u),onSubmit:i=>{u.addEventListener("submit",o=>{o.preventDefault();let y=L(u);i(y,o)})}}}var F={renderForm:S};var z=F,P={FormsLib:F};return V(O);})();
|
package/dist/main.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
"use strict";var w=Object.defineProperty;var
|
|
1
|
+
"use strict";var w=Object.defineProperty;var q=Object.getOwnPropertyDescriptor;var D=Object.getOwnPropertyNames;var N=Object.prototype.hasOwnProperty;var $=(h,a)=>{for(var m in a)w(h,m,{get:a[m],enumerable:!0})},B=(h,a,m,d)=>{if(a&&typeof a=="object"||typeof a=="function")for(let f of D(a))!N.call(h,f)&&f!==m&&w(h,f,{get:()=>a[f],enumerable:!(d=q(a,f))||d.enumerable});return h};var V=h=>B(w({},"__esModule",{value:!0}),h);var O={};$(O,{FormsLib:()=>z,default:()=>P});module.exports=V(O);function L(h,a=!0){let m=new FormData(h);if(a)return m;let d={};return m.forEach((f,u)=>{let g=(f instanceof File,f);Object.prototype.hasOwnProperty.call(d,u)?Array.isArray(d[u])?d[u].push(g):d[u]=[d[u],g]:d[u]=g}),d}async function M(h,a,m){let d=a.url,f={"Content-Type":"application/json"};a?.api_token&&(f.Authorization=`Bearer ${a.api_token}`);let u={...L(h,!1),...a.additional_data},g=JSON.stringify(u),i={method:a.method,headers:{Authorization:`Bearer ${a.api_token}`,"Content-Type":"application/json",Accept:"application/json"},...a.method==="GET"?{}:{body:g}};try{fetch(d,i).then(o=>{let y=o.headers.get("content-type");if(!o.ok){let E=o.text();throw new Error(`HTTP ${o.status}: ${E}`)}return y&&y.includes("application/json")?o.json():o.text()}).then(o=>{m&&m(o,null)}).catch(o=>{m&&m(null,o)})}catch(o){m&&m(null,o)}}function S(h,a,m){let d=[];if(typeof h=="string"?d=Array.from(document.querySelectorAll(h)):d=[h],d.length===0)return null;function f(){let i=m?.style==="bootstrap",o=document.createElement("form");o.classList.add("voc-form"),i&&o.classList.add("needs-validation"),o.id=a.id;let y=document.createElement("h2");y.textContent=a.form_name,o.appendChild(y);function E(e,l){l&&(l.min_length!==void 0&&(e.minLength=l.min_length),l.max_length!==void 0&&(e.maxLength=l.max_length),l.regex&&(e instanceof HTMLInputElement?e.pattern=l.regex:e.dataset.pattern=l.regex))}function C(e){if(!e.key&&!e.label)return null;let l=a.default_values||{},k=e.name||e.key,r=k?l[k]:void 0,b=document.createElement("div");if(b.className="voc-form-group",i&&b.classList.add("mb-3"),e.label){let t=document.createElement("label");t.classList.add("voc-form-label"),i&&t.classList.add("form-label"),e.key?e.type==="radio"?t.htmlFor="":t.htmlFor=`voc-form-${e.key}`:t.htmlFor="",t.textContent=e.label+(e.required?" *":""),b.appendChild(t)}let v=null;switch(e.type){case"checkbox":{let t=document.createElement("div");if(t.className="voc-form-checkbox-group "+(e.direction||"vertical"),e.width&&(t.style.width=e.width),e.options)e.options.forEach((n,c)=>{let p=document.createElement("label");p.classList.add("voc-form-checkbox-label"),i&&p.classList.add("form-check"),p.style.display=e.direction==="horizontal"?"inline-block":"block",e.width&&(p.style.width=e.width);let s=document.createElement("input");s.type="checkbox",s.classList.add("voc-form-checkbox"),i&&s.classList.add("form-check-input"),s.name=e.name||e.key||"",s.value=n.value,e.key&&(s.id=`voc-form-${e.key}-${c}`),e.required&&(s.required=!0),Array.isArray(r)?r.includes(n.value)&&(s.checked=!0):r!==void 0?r===n.value&&(s.checked=!0):e.default===n.value&&(s.checked=!0),p.appendChild(s),p.appendChild(document.createTextNode(n.label)),t.appendChild(p)});else{let n=document.createElement("label");n.classList.add("voc-form-checkbox-label"),i&&n.classList.add("form-check"),e.width&&(n.style.width=e.width);let c=document.createElement("input");c.type="checkbox",c.classList.add("voc-form-checkbox"),(e.key||e.name)&&(c.name=e.name||e.key,e.key&&(c.id=`voc-form-${e.key}`)),i&&c.classList.add("form-check-input"),e.required&&(c.required=!0),r!==void 0?c.checked=!!r:e.default&&(c.checked=!!e.default),n.appendChild(c),n.appendChild(document.createTextNode(e.label||"")),t.appendChild(n)}v=t;break}case"textarea":{let t=document.createElement("textarea");t.classList.add("voc-form-textarea"),i&&t.classList.add("form-control"),(e.key||e.name)&&(t.name=e.name||e.key,e.key&&(t.id=`voc-form-${e.key}`)),e.placeholder&&(t.placeholder=e.placeholder),r!=null?t.value=String(r):e.default!==void 0&&e.default!==null&&(t.value=String(e.default));let n=t.value||"";if(n&&(e.default||r)){let c=(n.match(/\n/g)||[]).length,p=80,s=n.split(`
|
|
2
|
+
`).reduce((H,R)=>Math.max(H,R.length),0),_=Math.ceil(s/p)||1,A=Math.max(2,c+_),T=20;t.rows=Math.min(A,T),t.style.height=`${T*1.2}em`,t.style.resize="vertical"}e.width&&(t.style.width=e.width),e.required&&(t.required=!0),E(t,e.validation),v=t;break}case"select":{let t=document.createElement("select");if(t.classList.add("voc-form-select"),i&&t.classList.add("form-select"),(e.key||e.name)&&(t.name=e.name||e.key,e.key&&(t.id=`voc-form-${e.key}`)),e.placeholder){let n=document.createElement("option");n.value="",n.textContent=e.placeholder,n.disabled=!0,n.selected=!0,t.appendChild(n)}e.required&&(t.required=!0),e.options&&e.options.forEach(n=>{let c=document.createElement("option");c.value=n.value,c.textContent=n.label,Array.isArray(r)?r.includes(n.value)&&(c.selected=!0):r!==void 0?r===n.value&&(c.selected=!0):e.default===n.value&&(c.selected=!0),t.appendChild(c)}),e.width&&(t.style.width=e.width),v=t;break}case"radio":{let t=document.createElement("div");t.className="voc-form-radio-group "+(e.direction||"vertical"),e.width&&(t.style.width=e.width),e.options&&e.options.forEach((n,c)=>{let p=document.createElement("label");p.classList.add("voc-form-radio-label"),i&&p.classList.add("form-check"),p.style.display=e.direction==="horizontal"?"inline-block":"block",e.width&&(p.style.width=e.width);let s=document.createElement("input");s.type="radio",s.classList.add("voc-form-radio"),i&&s.classList.add("form-check-input"),s.name=e.name||e.key||"",s.value=n.value,e.key&&(s.id=`voc-form-${e.key}-${c}`),Array.isArray(r)?r.includes(n.value)&&(s.checked=!0):r!==void 0?r===n.value&&(s.checked=!0):e.default===n.value&&(s.checked=!0),p.appendChild(s),p.appendChild(document.createTextNode(n.label)),t.appendChild(p)}),v=t;break}case"file":{let t=document.createElement("div");t.className="voc-form-file-wrapper",e.width&&(t.style.width=e.width);let n=document.createElement("input");n.type="file",n.classList.add("voc-form-file"),i&&n.classList.add("form-control"),(e.key||e.name)&&(n.name=e.name||e.key,e.key&&(n.id=`voc-form-${e.key}`)),e.width&&(n.style.width=e.width),e.required&&(n.required=!0),e.accept&&(n.accept=e.accept),e.multiple&&(n.multiple=!0),t.appendChild(n),v=t;break}default:{let t=document.createElement("input");t.type=e.type||"text",t.classList.add("voc-form-input"),i&&t.classList.add("form-control"),(e.key||e.name)&&(t.name=e.name||e.key,e.key&&(t.id=`voc-form-${e.key}`)),e.placeholder&&(t.placeholder=e.placeholder),r!=null?t.value=String(r):e.default!==void 0&&e.default!==null&&(t.value=String(e.default)),e.width&&(t.style.width=e.width),e.required&&(t.required=!0),E(t,e.validation),v=t;break}}if(v&&b.appendChild(v),e.hint_text){let t=document.createElement("small");t.className="voc-form-hint",t.textContent=e.hint_text,b.appendChild(t)}return b}a.fields.forEach(e=>{if(e.type==="row"&&"items"in e){let l=document.createElement("div");if(l.className="voc-form-group voc-form-row",i&&l.classList.add("mb-3"),e.label){let r=document.createElement("h3");r.className="voc-form-row-label",r.textContent=e.label,l.appendChild(r)}if(e.description){let r=document.createElement("p");r.className="voc-form-row-description",r.textContent=e.description,l.appendChild(r)}let k=document.createElement("div");k.className="voc-form-row-items "+(e.direction||"horizontal"),l.appendChild(k),e.items.forEach(r=>{let b=C(r);b&&k.appendChild(b)}),o.appendChild(l)}else{let l=C(e);l&&o.appendChild(l)}});let x=document.createElement("button");return x.type="submit",x.className="voc-form-submit",x.textContent="Submit",i&&x.classList.add("btn","btn-primary"),o.appendChild(x),o}let u=f();d[0].appendChild(u);let g=a?.submit_config??m?.submitConfig??null;return g&&u.addEventListener("submit",i=>{i.preventDefault(),M(u,g,(o,y)=>{m?.onSubmitResult&&m.onSubmitResult(o,y)})}),{element:u,validate:()=>{let i=[];return u.querySelectorAll(":invalid").forEach(y=>{let E=y.validationMessage;i.push({element:y,message:E})}),i},getValues:()=>L(u),onSubmit:i=>{u.addEventListener("submit",o=>{o.preventDefault();let y=L(u);i(y,o)})}}}var F={renderForm:S};var z=F,P={FormsLib:F};0&&(module.exports={FormsLib});
|
package/dist/main.mjs
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
function L(
|
|
1
|
+
function L(g,d=!0){let u=new FormData(g);if(d)return u;let p={};return u.forEach((v,l)=>{let y=(v instanceof File,v);Object.prototype.hasOwnProperty.call(p,l)?Array.isArray(p[l])?p[l].push(y):p[l]=[p[l],y]:p[l]=y}),p}async function T(g,d,u){let p=d.url,v={"Content-Type":"application/json"};d?.api_token&&(v.Authorization=`Bearer ${d.api_token}`);let l={...L(g,!1),...d.additional_data},y=JSON.stringify(l),a={method:d.method,headers:{Authorization:`Bearer ${d.api_token}`,"Content-Type":"application/json",Accept:"application/json"},...d.method==="GET"?{}:{body:y}};try{fetch(p,a).then(o=>{let h=o.headers.get("content-type");if(!o.ok){let E=o.text();throw new Error(`HTTP ${o.status}: ${E}`)}return h&&h.includes("application/json")?o.json():o.text()}).then(o=>{u&&u(o,null)}).catch(o=>{u&&u(null,o)})}catch(o){u&&u(null,o)}}function M(g,d,u){let p=[];if(typeof g=="string"?p=Array.from(document.querySelectorAll(g)):p=[g],p.length===0)return null;function v(){let a=u?.style==="bootstrap",o=document.createElement("form");o.classList.add("voc-form"),a&&o.classList.add("needs-validation"),o.id=d.id;let h=document.createElement("h2");h.textContent=d.form_name,o.appendChild(h);function E(e,c){c&&(c.min_length!==void 0&&(e.minLength=c.min_length),c.max_length!==void 0&&(e.maxLength=c.max_length),c.regex&&(e instanceof HTMLInputElement?e.pattern=c.regex:e.dataset.pattern=c.regex))}function F(e){if(!e.key&&!e.label)return null;let c=d.default_values||{},k=e.name||e.key,r=k?c[k]:void 0,f=document.createElement("div");if(f.className="voc-form-group",a&&f.classList.add("mb-3"),e.label){let t=document.createElement("label");t.classList.add("voc-form-label"),a&&t.classList.add("form-label"),e.key?e.type==="radio"?t.htmlFor="":t.htmlFor=`voc-form-${e.key}`:t.htmlFor="",t.textContent=e.label+(e.required?" *":""),f.appendChild(t)}let b=null;switch(e.type){case"checkbox":{let t=document.createElement("div");if(t.className="voc-form-checkbox-group "+(e.direction||"vertical"),e.width&&(t.style.width=e.width),e.options)e.options.forEach((n,s)=>{let m=document.createElement("label");m.classList.add("voc-form-checkbox-label"),a&&m.classList.add("form-check"),m.style.display=e.direction==="horizontal"?"inline-block":"block",e.width&&(m.style.width=e.width);let i=document.createElement("input");i.type="checkbox",i.classList.add("voc-form-checkbox"),a&&i.classList.add("form-check-input"),i.name=e.name||e.key||"",i.value=n.value,e.key&&(i.id=`voc-form-${e.key}-${s}`),e.required&&(i.required=!0),Array.isArray(r)?r.includes(n.value)&&(i.checked=!0):r!==void 0?r===n.value&&(i.checked=!0):e.default===n.value&&(i.checked=!0),m.appendChild(i),m.appendChild(document.createTextNode(n.label)),t.appendChild(m)});else{let n=document.createElement("label");n.classList.add("voc-form-checkbox-label"),a&&n.classList.add("form-check"),e.width&&(n.style.width=e.width);let s=document.createElement("input");s.type="checkbox",s.classList.add("voc-form-checkbox"),(e.key||e.name)&&(s.name=e.name||e.key,e.key&&(s.id=`voc-form-${e.key}`)),a&&s.classList.add("form-check-input"),e.required&&(s.required=!0),r!==void 0?s.checked=!!r:e.default&&(s.checked=!!e.default),n.appendChild(s),n.appendChild(document.createTextNode(e.label||"")),t.appendChild(n)}b=t;break}case"textarea":{let t=document.createElement("textarea");t.classList.add("voc-form-textarea"),a&&t.classList.add("form-control"),(e.key||e.name)&&(t.name=e.name||e.key,e.key&&(t.id=`voc-form-${e.key}`)),e.placeholder&&(t.placeholder=e.placeholder),r!=null?t.value=String(r):e.default!==void 0&&e.default!==null&&(t.value=String(e.default));let n=t.value||"";if(n&&(e.default||r)){let s=(n.match(/\n/g)||[]).length,m=80,i=n.split(`
|
|
2
|
+
`).reduce((A,H)=>Math.max(A,H.length),0),S=Math.ceil(i/m)||1,_=Math.max(2,s+S),C=20;t.rows=Math.min(_,C),t.style.height=`${C*1.2}em`,t.style.resize="vertical"}e.width&&(t.style.width=e.width),e.required&&(t.required=!0),E(t,e.validation),b=t;break}case"select":{let t=document.createElement("select");if(t.classList.add("voc-form-select"),a&&t.classList.add("form-select"),(e.key||e.name)&&(t.name=e.name||e.key,e.key&&(t.id=`voc-form-${e.key}`)),e.placeholder){let n=document.createElement("option");n.value="",n.textContent=e.placeholder,n.disabled=!0,n.selected=!0,t.appendChild(n)}e.required&&(t.required=!0),e.options&&e.options.forEach(n=>{let s=document.createElement("option");s.value=n.value,s.textContent=n.label,Array.isArray(r)?r.includes(n.value)&&(s.selected=!0):r!==void 0?r===n.value&&(s.selected=!0):e.default===n.value&&(s.selected=!0),t.appendChild(s)}),e.width&&(t.style.width=e.width),b=t;break}case"radio":{let t=document.createElement("div");t.className="voc-form-radio-group "+(e.direction||"vertical"),e.width&&(t.style.width=e.width),e.options&&e.options.forEach((n,s)=>{let m=document.createElement("label");m.classList.add("voc-form-radio-label"),a&&m.classList.add("form-check"),m.style.display=e.direction==="horizontal"?"inline-block":"block",e.width&&(m.style.width=e.width);let i=document.createElement("input");i.type="radio",i.classList.add("voc-form-radio"),a&&i.classList.add("form-check-input"),i.name=e.name||e.key||"",i.value=n.value,e.key&&(i.id=`voc-form-${e.key}-${s}`),Array.isArray(r)?r.includes(n.value)&&(i.checked=!0):r!==void 0?r===n.value&&(i.checked=!0):e.default===n.value&&(i.checked=!0),m.appendChild(i),m.appendChild(document.createTextNode(n.label)),t.appendChild(m)}),b=t;break}case"file":{let t=document.createElement("div");t.className="voc-form-file-wrapper",e.width&&(t.style.width=e.width);let n=document.createElement("input");n.type="file",n.classList.add("voc-form-file"),a&&n.classList.add("form-control"),(e.key||e.name)&&(n.name=e.name||e.key,e.key&&(n.id=`voc-form-${e.key}`)),e.width&&(n.style.width=e.width),e.required&&(n.required=!0),e.accept&&(n.accept=e.accept),e.multiple&&(n.multiple=!0),t.appendChild(n),b=t;break}default:{let t=document.createElement("input");t.type=e.type||"text",t.classList.add("voc-form-input"),a&&t.classList.add("form-control"),(e.key||e.name)&&(t.name=e.name||e.key,e.key&&(t.id=`voc-form-${e.key}`)),e.placeholder&&(t.placeholder=e.placeholder),r!=null?t.value=String(r):e.default!==void 0&&e.default!==null&&(t.value=String(e.default)),e.width&&(t.style.width=e.width),e.required&&(t.required=!0),E(t,e.validation),b=t;break}}if(b&&f.appendChild(b),e.hint_text){let t=document.createElement("small");t.className="voc-form-hint",t.textContent=e.hint_text,f.appendChild(t)}return f}d.fields.forEach(e=>{if(e.type==="row"&&"items"in e){let c=document.createElement("div");if(c.className="voc-form-group voc-form-row",a&&c.classList.add("mb-3"),e.label){let r=document.createElement("h3");r.className="voc-form-row-label",r.textContent=e.label,c.appendChild(r)}if(e.description){let r=document.createElement("p");r.className="voc-form-row-description",r.textContent=e.description,c.appendChild(r)}let k=document.createElement("div");k.className="voc-form-row-items "+(e.direction||"horizontal"),c.appendChild(k),e.items.forEach(r=>{let f=F(r);f&&k.appendChild(f)}),o.appendChild(c)}else{let c=F(e);c&&o.appendChild(c)}});let x=document.createElement("button");return x.type="submit",x.className="voc-form-submit",x.textContent="Submit",a&&x.classList.add("btn","btn-primary"),o.appendChild(x),o}let l=v();p[0].appendChild(l);let y=d?.submit_config??u?.submitConfig??null;return y&&l.addEventListener("submit",a=>{a.preventDefault(),T(l,y,(o,h)=>{u?.onSubmitResult&&u.onSubmitResult(o,h)})}),{element:l,validate:()=>{let a=[];return l.querySelectorAll(":invalid").forEach(h=>{let E=h.validationMessage;a.push({element:h,message:E})}),a},getValues:()=>L(l),onSubmit:a=>{l.addEventListener("submit",o=>{o.preventDefault();let h=L(l);a(h,o)})}}}var w={renderForm:M};var O=w,j={FormsLib:w};export{O as FormsLib,j as default};
|