A flexible and customizable dynamic form builder with theming support
npm install @elrayes/dynamic-form-builderA flexible, themeable dynamic form builder for modern web apps. Build complete forms from a simple config, validate, theme, and submit — with optional Select2, CKEditor, and Dropzone integrations.


- Dynamic form generation from a JavaScript/TypeScript config
- Rich field types: text, textarea, select, select2, checkbox, radio, file, dropzone, ckeditor, submit
- Built-in validation: required, min/max length, pattern, custom
- Theme support: Bootstrap 5 and Tailwind out of the box (custom themes supported)
- Modal rendering when no mount is provided
- TypeScript types included
- Installation
- Quick Start
- Configuration
- Field Types
- Validation
- Theming
- API
- TypeScript
- Integrations (Select2, CKEditor, Dropzone)
- Requirements
- License
Using npm
``bash`
npm install @elrayes/dynamic-form-builder
Using Yarn
`bash`
yarn add @elrayes/dynamic-form-builder
Laravel + Vite (make globals for Blade use)
In resources/js/bootstrap.js:
`javascript
import { DynamicForm, ThemeManager } from '@elrayes/dynamic-form-builder';
window.DynamicForm = DynamicForm;
window.ThemeManager = ThemeManager;
`
Then rebuild your assets with Vite.
`javascript
import { DynamicForm } from '@elrayes/dynamic-form-builder';
const form = new DynamicForm({
config: [
{ type: 'text', name: 'username', label: 'Username', required: true },
{ type: 'email', name: 'email', label: 'Email', required: true },
{ type: 'password', name: 'password', label: 'Password', required: true },
{ type: 'submit', label: 'Register' }
],
mount: 'form-container',
onSubmit: async (formData, form, instance) => {
await fetch('/api/register', { method: 'POST', body: formData });
}
});
`
HTML mount example
`html`
Modal usage: omit mount (or pass null) and a theme modal will be created.
DynamicForm options
``
new DynamicForm({
config: FieldConfig[],
mount?: string | HTMLElement | null, // if omitted or null, renders in a modal
modalOptions?: ModalOptions, // id, title, show, staticBackdrop, type ('modal' | 'offcanvas'), extendContainerClass
onSubmit: (formData, form, instance) => Promise
onInitialized?: (instance, form, inputs) => void,
theme?: 'bootstrap5' | 'tailwind' | Theme,
waitForDOMReady?: boolean
})
Common FieldConfig keys
- name: string
- type: string (see Field Types)
- label?: string
- value?: any
- placeholder?: string
- required?: boolean
- helper?: string
- options?: Array<{ label: string; value: string|number|boolean; selected?: boolean } | string>
- multiple?: boolean
- select2Options?: Record
- dropzoneOptions?: Record
- rows?: number (textarea)
- validation?: { required?: string; minLength?: number; minLengthMsg?: string; maxLength?: number; maxLengthMsg?: string; pattern?: RegExp|string; patternMsg?: string; custom?: (value, input, field) => boolean|string }
- onCreate?: (inputEl, field, index) => void
Basic
- text, email, password, number, tel, url, date, color, hidden, textarea
Selects
- select (native)
- select2 (jQuery Select2). Provide select2Options and include Select2 assets.
Choices
- checkbox (single), radio (group via options)
Files
- file (native input with preview for single image; list for multiple)
- dropzone (drag-and-drop via Dropzone)
Rich text
- ckeditor (requires window.initializeEditor to return a CKEditor instance)
Submit
- submit (button)
- required: boolean (uses message from validation.required if provided)
- minLength / maxLength: number with optional custom messages
- pattern: RegExp or string with patternMsg
- custom: (value, input, field) => boolean | string
Validation runs on blur/submit and shows theme-appropriate feedback. Radio/checkbox/select2 are handled correctly.
Built-in themes: bootstrap5 (default), tailwind.
Pass theme by name or provide a Theme instance. You can register custom themes.
`ts
import { ThemeManager, TailwindTheme } from '@elrayes/dynamic-form-builder';
// use built-in
new DynamicForm({ config, mount: 'el', theme: 'tailwind', onSubmit });
// register custom
ThemeManager.register('myTheme', new TailwindTheme());
new DynamicForm({ config, theme: 'myTheme', onSubmit });
`
Instance methods
- getForm(): HTMLFormElement
- getData(): FieldConfig[]
- getModalInstance(): ModalInstance | null
- collectFormInputs(): Record
- clearForm(): DynamicForm
- destroy(): void
Callbacks
- onInitialized(instance, form, inputs)
- onSubmit(formData, form, instance)
Types are bundled. Import what you need.
`ts`
import { DynamicForm, FieldConfig, DynamicFormOptions } from '@elrayes/dynamic-form-builder';
Select2
- Ensure jQuery and Select2 are loaded. The builder retries initialization briefly to support async loading.
- Provide select2Options; for multiple, name becomes fieldName[]
CKEditor
- Provide a global initializer that returns the editor instance:
`html`
Dropzone
- Include Dropzone assets. If dropzoneOptions.url is provided, uploads are processed by Dropzone.
- If url is omitted/empty, uploads are deferred: files are appended to FormData on submit (respects multiple).
- jQuery (base dependency; needed for Select2)
- Bootstrap (only if rendering in a modal via bootstrap5 theme)
- Select2 (only for select2 fields)
- CKEditor (only for ckeditor fields)
- Dropzone (only for dropzone fields)
This project is licensed under the MIT License - see the LICENSE file for details.
- By default, when you omit mount, the form renders in a modal container.
- You can switch to an offcanvas container by setting modalOptions.type = 'offcanvas'.
Example (Bootstrap 5.2 or Tailwind):
`js``
new DynamicForm({
config: [ / fields / ],
mount: null, // render in container
modalOptions: { title: 'Create Item', type: 'offcanvas', show: true, extendContainerClass: 'offcanvas-size-lg' },
theme: 'bootstrap5', // or 'tailwind'
onSubmit: (fd) => {/ ... /}
});
Notes:
- Bootstrap theme uses native Bootstrap 5.2 Modal/Offcanvas APIs (make sure you loaded Bootstrap JS/CSS).
- Tailwind theme provides a lightweight modal/offcanvas implementation using utility classes.