@dmitryvim/form-builder 0.1.1 → 0.1.5

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 CHANGED
@@ -2,35 +2,43 @@
2
2
 
3
3
  JSON Schema → Dynamic Forms → Structured Output
4
4
 
5
+ A reusable, zero-dependency form generation library that converts JSON schemas into dynamic, interactive forms with real-time validation and file upload support.
6
+
5
7
  ## Live Demo
6
8
 
7
9
  Try it now: **[https://picazru.github.io/form-builder/dist/index.html](https://picazru.github.io/form-builder/dist/index.html)**
8
10
 
9
11
  ## Quick Start
10
12
 
11
- ### Embed in Your Website
13
+ ### CDN Integration
12
14
 
13
15
  ```html
14
- <!-- Full page embed -->
16
+ <!-- Embed via iframe -->
15
17
  <iframe src="https://picazru.github.io/form-builder/dist/index.html"
16
- width="100%" height="600px"
17
- frameborder="0"
18
- style="border-radius: 8px;"></iframe>
18
+ width="100%" height="600px" frameborder="0"></iframe>
19
19
 
20
- <!-- With custom schema via URL parameter -->
21
- <iframe src="https://picazru.github.io/form-builder/dist/index.html?schema=eyJ2ZXJzaW9uIjoiMC4zIi..."
20
+ <!-- With custom schema -->
21
+ <iframe src="https://picazru.github.io/form-builder/dist/index.html?schema=BASE64_SCHEMA"
22
22
  width="100%" height="600px"></iframe>
23
23
  ```
24
24
 
25
- ### Install via npm
25
+ ### NPM Installation
26
26
 
27
27
  ```bash
28
- npm install @picazru/form-builder
28
+ npm install @dmitryvim/form-builder
29
29
  ```
30
30
 
31
- ## Integration
31
+ ## Core Features
32
+
33
+ - **Schema-driven forms**: JSON Schema v0.3 → Interactive forms
34
+ - **File uploads**: Built-in support with configurable handlers
35
+ - **Real-time validation**: Client-side validation with error display
36
+ - **Framework agnostic**: Works with any web stack
37
+ - **Zero dependencies**: Self-contained HTML/CSS/JavaScript
38
+ - **Read-only mode**: Display form data without editing
39
+ - **Draft saving**: Save incomplete forms without validation
32
40
 
33
- ### Basic Schema
41
+ ## Basic Example
34
42
 
35
43
  ```json
36
44
  {
@@ -44,131 +52,32 @@ npm install @picazru/form-builder
44
52
  "required": true
45
53
  },
46
54
  {
47
- "type": "file",
48
- "key": "avatar",
49
- "label": "Profile Picture",
55
+ "type": "files",
56
+ "key": "attachments",
57
+ "label": "Attachments",
58
+ "maxCount": 3,
50
59
  "accept": {
51
- "extensions": ["jpg", "png"]
60
+ "extensions": ["pdf", "jpg", "png"]
52
61
  }
53
62
  }
54
63
  ]
55
64
  }
56
65
  ```
57
66
 
58
- ### Configure File Handlers
59
-
60
- When embedding the form builder, configure file upload handlers on your page:
61
-
62
- ```html
63
- <!DOCTYPE html>
64
- <html>
65
- <head>
66
- <title>My App with Form Builder</title>
67
- </head>
68
- <body>
69
- <!-- Embed the form builder -->
70
- <iframe id="formBuilder"
71
- src="https://picazru.github.io/form-builder/dist/index.html"
72
- width="100%" height="600px"></iframe>
73
-
74
- <script>
75
- // Configure file upload handlers
76
- window.addEventListener('message', (event) => {
77
- if (event.origin !== 'https://picazru.github.io') return;
78
-
79
- if (event.data.type === 'formBuilderReady') {
80
- // Send configuration to the iframe
81
- const iframe = document.getElementById('formBuilder');
82
- iframe.contentWindow.postMessage({
83
- type: 'configure',
84
- config: {
85
- uploadHandler: async (file) => {
86
- // Your S3 upload logic
87
- const formData = new FormData();
88
- formData.append('file', file);
89
-
90
- const response = await fetch('/api/upload', {
91
- method: 'POST',
92
- body: formData
93
- });
94
-
95
- const result = await response.json();
96
- return result.fileUrl;
97
- }
98
- }
99
- }, 'https://picazru.github.io');
100
- }
101
- });
102
- </script>
103
- </body>
104
- </html>
105
- ```
106
-
107
- ### Direct Page Integration
108
-
109
- If you want to integrate directly on your page (not iframe):
67
+ ## Integration Options
110
68
 
111
- ```html
112
- <script>
113
- window.addEventListener('formBuilderReady', (event) => {
114
- const config = event.detail;
115
-
116
- // Upload files to S3
117
- config.setUploadHandler(async (file) => {
118
- const formData = new FormData();
119
- formData.append('file', file);
120
-
121
- const response = await fetch('/api/upload', {
122
- method: 'POST',
123
- body: formData
124
- });
125
-
126
- const result = await response.json();
127
- return result.fileUrl; // Return S3 URL or resource ID
128
- });
129
-
130
- // Download files
131
- config.setDownloadHandler(async (resourceId) => {
132
- window.open(`/api/download/${resourceId}`, '_blank');
133
- });
134
-
135
- // Generate thumbnails
136
- config.setThumbnailHandler(async (resourceId) => {
137
- return `/api/thumbnail/${resourceId}`;
138
- });
139
- });
140
- </script>
141
- ```
69
+ - **CDN**: Direct iframe embedding
70
+ - **NPM**: Import as module
71
+ - **Direct**: Self-hosted deployment
142
72
 
143
- ### Field Types
73
+ See [Integration Guide](docs/integration.md) for complete setup instructions.
144
74
 
145
- - **text** - Single line text with validation
146
- - **textarea** - Multi-line text
147
- - **number** - Numeric input with min/max
148
- - **select** - Dropdown with options
149
- - **file** - Single file upload with preview
150
- - **files** - Multiple file uploads
151
- - **group** - Nested objects with repeat support
75
+ ## Documentation
152
76
 
153
- ### Form Output
154
-
155
- ```json
156
- {
157
- "name": "John Doe",
158
- "avatar": "https://bucket.s3.amazonaws.com/files/avatar.jpg"
159
- }
160
- ```
161
-
162
- ## Development
163
-
164
- ```bash
165
- git clone https://github.com/picazru/form-builder.git
166
- cd form-builder
167
- npm install
168
- npm run dev # Start development server
169
- npm test # Run tests
170
- npm run build # Build for production
171
- ```
77
+ - [Integration Guide](docs/integration.md) - How to use and integrate
78
+ - [Schema Reference](docs/schema.md) - Complete schema documentation
79
+ - [Requirements](docs/requirements.md) - Product and business requirements
80
+ - [Development Guide](development.md) - Development and testing
172
81
 
173
82
  ## License
174
83
 
package/dist/README.md ADDED
@@ -0,0 +1,193 @@
1
+ # Form Builder Library
2
+
3
+ A reusable JavaScript library for generating dynamic forms from JSON schemas.
4
+
5
+ ## Quick Start
6
+
7
+ ### 1. Include the Library
8
+
9
+ ```html
10
+ <script src="https://unpkg.com/@dmitryvim/form-builder@latest/dist/form-builder.js"></script>
11
+ ```
12
+
13
+ Or via npm:
14
+ ```bash
15
+ npm install @dmitryvim/form-builder
16
+ ```
17
+
18
+ ### 2. Basic Usage
19
+
20
+ ```javascript
21
+ // Define your schema
22
+ const schema = {
23
+ "version": "0.3",
24
+ "title": "User Registration",
25
+ "elements": [
26
+ {
27
+ "type": "text",
28
+ "key": "name",
29
+ "label": "Full Name",
30
+ "required": true
31
+ },
32
+ {
33
+ "type": "text",
34
+ "key": "email",
35
+ "label": "Email",
36
+ "required": true
37
+ }
38
+ ]
39
+ };
40
+
41
+ // Get container element
42
+ const container = document.getElementById('form-container');
43
+
44
+ // Render the form
45
+ const form = FormBuilder.renderForm(schema, container, {
46
+ onSubmit: (data) => {
47
+ console.log('Form submitted:', data);
48
+ },
49
+ onDraft: (data) => {
50
+ console.log('Draft saved:', data);
51
+ },
52
+ onError: (errors) => {
53
+ console.log('Validation errors:', errors);
54
+ }
55
+ });
56
+ ```
57
+
58
+ ## API Reference
59
+
60
+ ### FormBuilder.renderForm(schema, container, options)
61
+
62
+ Renders a form in the specified container.
63
+
64
+ **Parameters:**
65
+ - `schema` - JSON schema object (v0.3)
66
+ - `container` - DOM element to render form in
67
+ - `options` - Configuration object
68
+
69
+ **Options:**
70
+ - `prefill` - Object with prefilled values
71
+ - `readonly` - Boolean, renders form in read-only mode
72
+ - `onSubmit` - Callback for form submission
73
+ - `onDraft` - Callback for draft saving
74
+ - `onError` - Callback for validation errors
75
+
76
+ ### FormBuilder.validateSchema(schema)
77
+
78
+ Validates a JSON schema and returns array of errors.
79
+
80
+ ### FormBuilder.setUploadHandler(uploadFn)
81
+
82
+ Sets custom file upload handler:
83
+ ```javascript
84
+ FormBuilder.setUploadHandler(async (file) => {
85
+ // Upload file to your backend
86
+ const response = await fetch('/upload', {
87
+ method: 'POST',
88
+ body: file
89
+ });
90
+ const result = await response.json();
91
+ return result.resourceId; // Return resource ID
92
+ });
93
+ ```
94
+
95
+ ### FormBuilder.setDownloadHandler(downloadFn)
96
+
97
+ Sets custom file download handler:
98
+ ```javascript
99
+ FormBuilder.setDownloadHandler(async (resourceId, fileName) => {
100
+ window.open(`/download/${resourceId}`, '_blank');
101
+ });
102
+ ```
103
+
104
+ ## Supported Field Types
105
+
106
+ - `text` - Single line text input
107
+ - `textarea` - Multi-line text input
108
+ - `number` - Numeric input with constraints
109
+ - `select` - Dropdown selection
110
+ - `file` - Single file upload
111
+ - `files` - Multiple file upload
112
+ - `group` - Nested objects with optional repeat
113
+
114
+ ## Complete Example
115
+
116
+ ```javascript
117
+ const schema = {
118
+ "version": "0.3",
119
+ "title": "Product Form",
120
+ "elements": [
121
+ {
122
+ "type": "file",
123
+ "key": "cover",
124
+ "label": "Cover Image",
125
+ "required": true,
126
+ "accept": {
127
+ "extensions": ["jpg", "png"],
128
+ "mime": ["image/jpeg", "image/png"]
129
+ },
130
+ "maxSizeMB": 5
131
+ },
132
+ {
133
+ "type": "text",
134
+ "key": "title",
135
+ "label": "Product Title",
136
+ "required": true,
137
+ "maxLength": 100
138
+ },
139
+ {
140
+ "type": "group",
141
+ "key": "features",
142
+ "label": "Features",
143
+ "repeat": {
144
+ "min": 1,
145
+ "max": 5
146
+ },
147
+ "elements": [
148
+ {
149
+ "type": "text",
150
+ "key": "name",
151
+ "label": "Feature Name",
152
+ "required": true
153
+ }
154
+ ]
155
+ }
156
+ ]
157
+ };
158
+
159
+ // Configure file upload
160
+ FormBuilder.setUploadHandler(async (file) => {
161
+ const formData = new FormData();
162
+ formData.append('file', file);
163
+
164
+ const response = await fetch('/api/upload', {
165
+ method: 'POST',
166
+ body: formData
167
+ });
168
+
169
+ const result = await response.json();
170
+ return result.resourceId;
171
+ });
172
+
173
+ // Render form
174
+ FormBuilder.renderForm(schema, document.getElementById('form'), {
175
+ onSubmit: async (data) => {
176
+ const response = await fetch('/api/submit', {
177
+ method: 'POST',
178
+ headers: { 'Content-Type': 'application/json' },
179
+ body: JSON.stringify(data)
180
+ });
181
+
182
+ if (response.ok) {
183
+ alert('Form submitted successfully!');
184
+ }
185
+ }
186
+ });
187
+ ```
188
+
189
+ ## Files
190
+
191
+ - `form-builder.js` - Main library file
192
+ - `sample.html` - Interactive demo page
193
+ - Complete documentation at `/docs/`
@@ -0,0 +1,108 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Form Builder - Simple Example</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ </head>
9
+ <body class="bg-gray-50 p-8">
10
+ <div class="max-w-2xl mx-auto">
11
+ <h1 class="text-3xl font-bold mb-8">Form Builder Library Example</h1>
12
+
13
+ <div class="bg-white rounded-lg shadow p-6 mb-8">
14
+ <h2 class="text-xl font-semibold mb-4">Generated Form</h2>
15
+ <div id="form-container"></div>
16
+ </div>
17
+
18
+ <div class="bg-white rounded-lg shadow p-6">
19
+ <h2 class="text-xl font-semibold mb-4">Form Output</h2>
20
+ <pre id="output" class="bg-gray-100 p-4 rounded text-sm overflow-auto">Submit the form to see output...</pre>
21
+ </div>
22
+ </div>
23
+
24
+ <script src="form-builder.js"></script>
25
+ <script>
26
+ // Example schema
27
+ const schema = {
28
+ "version": "0.3",
29
+ "title": "Contact Form",
30
+ "elements": [
31
+ {
32
+ "type": "text",
33
+ "key": "name",
34
+ "label": "Full Name",
35
+ "required": true,
36
+ "minLength": 2,
37
+ "maxLength": 50
38
+ },
39
+ {
40
+ "type": "text",
41
+ "key": "email",
42
+ "label": "Email Address",
43
+ "required": true,
44
+ "pattern": "^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$"
45
+ },
46
+ {
47
+ "type": "select",
48
+ "key": "category",
49
+ "label": "Category",
50
+ "required": true,
51
+ "options": [
52
+ { "value": "general", "label": "General Inquiry" },
53
+ { "value": "support", "label": "Technical Support" },
54
+ { "value": "billing", "label": "Billing Question" }
55
+ ]
56
+ },
57
+ {
58
+ "type": "textarea",
59
+ "key": "message",
60
+ "label": "Message",
61
+ "required": true,
62
+ "maxLength": 1000
63
+ },
64
+ {
65
+ "type": "file",
66
+ "key": "attachment",
67
+ "label": "Attachment (Optional)",
68
+ "required": false,
69
+ "accept": {
70
+ "extensions": ["pdf", "doc", "docx", "txt"],
71
+ "mime": ["application/pdf", "application/msword", "text/plain"]
72
+ },
73
+ "maxSizeMB": 5
74
+ }
75
+ ]
76
+ };
77
+
78
+ // Configure file upload simulation
79
+ FormBuilder.setUploadHandler(async (file) => {
80
+ // Simulate upload delay
81
+ await new Promise(resolve => setTimeout(resolve, 1000));
82
+
83
+ // Generate fake resource ID
84
+ const resourceId = 'res_' + Math.random().toString(36).substr(2, 12);
85
+ console.log(`File "${file.name}" uploaded with ID: ${resourceId}`);
86
+ return resourceId;
87
+ });
88
+
89
+ // Render the form
90
+ const container = document.getElementById('form-container');
91
+ const output = document.getElementById('output');
92
+
93
+ FormBuilder.renderForm(schema, container, {
94
+ onSubmit: (data) => {
95
+ output.textContent = JSON.stringify(data, null, 2);
96
+ alert('Form submitted successfully! Check the output below.');
97
+ },
98
+ onDraft: (data) => {
99
+ output.textContent = 'DRAFT:\n' + JSON.stringify(data, null, 2);
100
+ console.log('Draft saved:', data);
101
+ },
102
+ onError: (errors) => {
103
+ alert('Validation errors: ' + errors.join(', '));
104
+ }
105
+ });
106
+ </script>
107
+ </body>
108
+ </html>