1.1.1 β€’ Published 6 months ago

@jubayer11/vue-dynamic-form-builder v1.1.1

Weekly downloads
-
License
MIT
Repository
github
Last release
6 months ago

Vue Dynamic Form Builder

Vue 3 Compatible
License: MIT
PRs Welcome
Live Demo
npm
GitHub
Related Package

Build fully customizable, schema-driven forms β€” with complete developer freedom.

Vue Dynamic Form Builder gives you the tools to create fully dynamic, validated, and beautifully styled forms β€” while keeping total control over structure, behavior, layout, and appearance.
It’s built to empower developers who want flexibility beyond typical rigid form builders.

πŸš€ Why Use Vue Dynamic Form Builder?

  • True Flexibility:
    Full control over structure, fields, validation, styling, and submission logic β€” not tied to rigid presets.

  • Schema-Driven:
    Define your entire form β€” fields, layouts, validations β€” using simple JavaScript objects. No repetitive HTML or template duplication.

  • Lightweight and Clean:
    No bulky UI frameworks. Built purely with Vue 3 Composition API and clean, extensible CSS utilities.

  • Fully Extensible:
    Easily add new field types, create custom validation rules, and inject your own UI components if needed.

  • Manual or Auto Submission:
    Decide whether the form handles submit automatically β€” or give yourself full manual control over when and how it submits.

  • Frontend-Agnostic:
    Designed to adapt easily to any backend API and frontend system β€” with no assumptions about your stack or styling.

πŸ—οΈ Internal Structure Overview

Vue Dynamic Form Builder is built with a lightweight, highly modular internal architecture to maximize flexibility and developer control.

It uses a schema-driven approach:
You define your form structure using JavaScript objects (CustomizableTextField + FieldType), and the form renders itself automatically based on that schema.


πŸ”Ή Core Components

PartPurpose
CustomizableTextFieldMaster class that manages the full form: adds fields, controls submit button, handles global styles, collects backend errors.
FieldTypeBlueprint for each individual field (e.g., text, textarea, select, radio, multi-select, password, date picker). Defines label, placeholder, validations, custom styles, etc.
ValidationSetupUtility to easily attach built-in and custom validations declaratively to fields.
DynamicForm.vueThe main engine: dynamically renders the form from the schema, connects Vuelidate for live validation, manages form state and submission.
textFieldStyleGlobal default styling system for inputs, labels, errors, and wrappers. Can be overridden globally, per-form, or per-field.

πŸ”Ή Internal Utilities and Libraries

UtilityPurpose
VuelidateUsed internally to power all validation logic dynamically. No manual Vuelidate setup needed by the user.
Moment.jsUsed for formatting and parsing dates and times inside datePickerField inputs.
Lodash (isEqual)Used to deeply compare form data structures (e.g., for form reset, backend error matching).
@vuepic/vue-datepickerIntegrated internally for rendering modern and flexible date/time pickers.

πŸ”Ή Supported Field Types

Field TypeDescription
textFieldStandard single-line input (text, email, number, etc.)
textAreaMulti-line textarea input
selectFieldSingle-select dropdown menu
radioFieldRadio button group
multiSelectMulti-select dropdown (with tag view and custom styling)
passwordTextFieldPassword input with hidden characters
datePickerFieldModern date/time picker (date, month, week, year modes)

βœ… Each field is built as an independent Vue component internally β€” following clean modular structure.


πŸ”Ή Internal Flow

The internal flow of the Dynamic Form system is simple yet powerful:

  1. You define a form schema using CustomizableTextField and FieldType.
  2. You bind the schema to the <DynamicForm> component with v-model for form data.
  3. DynamicForm.vue dynamically renders all fields based on your schema β€” applying global and per-field styles.
  4. Vuelidate is wired automatically β€” every field's validation is live with no manual setup.
  5. Submissions can be automatic (built-in button) or manual (external button triggering validation and submit).
  6. Backend validation errors can be injected anytime using setErrors(), and fields display mapped errors immediately.
  7. Styling is fully customizable globally (schema-wide) or per-field β€” supporting your own utility classes (Tailwind, Bootstrap, etc.)

🎯 Key Architectural Principles

  • Schema First β†’ You control everything through configuration, not through heavy templates.
  • Modular Fields β†’ Every field type is a clean, isolated component (TextField, SelectField, DatePickerField, etc.)
  • Validation as Data β†’ All field validations are attached declaratively through ValidationSetup.
  • Zero Lock-In β†’ No opinionated UI framework β€” you are free to style and extend freely.
  • Error Handling Built-In β†’ Live frontend validation + backend error injection supported out of the box.

βœ… Result:
You get a real-world form builder that feels native, flexible, and fully under your control β€” while staying lightweight, fast, and clean.

πŸ› οΈ Field Types Overview

Vue Dynamic Form Builder supports a range of field types, covering most common real-world form needs.
Each field type can be customized individually for label, placeholder, validation, styling, and behavior.

Field TypeDescription
textFieldStandard single-line input (text, email, number, tel, url, etc.)
textAreaMulti-line text input for longer content (comments, descriptions, etc.)
selectFieldSingle-select dropdown list
radioFieldRadio button group for choosing one option from multiple
multiSelectMulti-select dropdown with tag-style selections
passwordTextFieldPassword input field with hidden characters
datePickerFieldModern date/time picker supporting date, time, month, week, and year modes

βœ… All field types are internally modular β€” meaning you can easily extend, customize, or override their behavior as needed.

βœ… Field-specific styling and validation rules are applied cleanly at the schema level.

βœ… The system is designed to be flexible β€” you can mix multiple field types in a single form freely.

✨ Features

  • Schema-Driven:
    Define all fields and layouts with a simple JavaScript schema.

  • Highly Flexible Field Types:
    Supports:

    • Standard Inputs (text, email, number, password, tel, url)
    • Text Area
    • Select Dropdown
    • Multi-Select Dropdown (with tag views and custom dropdown styles)
    • Radio Button Group
    • Date/Time Pickers (date, dateTime, month, time, year, week)
  • Per-Field Design Overrides:

    • Every field part (div, input, label, error message, dropdown item, etc.) can have custom CSS classes through the schema.
    • Global defaults (textFieldStyle) provided but fully overridable.
  • Validation System:

    • Includes built-in validations like:
      • Required
      • Email format
      • Minimum/Maximum Length
      • Minimum/Maximum Value
      • Value Range (Between)
      • URL format
      • Integer validation
      • Decimal (float) validation
      • Same-As (field matching)
      • Fully Custom Function Validators
  • Backend Error Injection:
    Accept and display backend validation errors automatically, mapping them to the correct fields.

  • Manual or Auto Submission:
    Choose between built-in submit button or fully manual form control (submit/reset from outside).

  • Popup Modal Support:
    Render fully functional forms inside modals without relying on external UI libraries.

  • Developer Friendly:
    Designed with real-world control, composability, and full extensibility β€” not a rigid black-box solution.

  • No UI Framework Lock-in:
    Seamlessly integrate with your own CSS, Tailwind, Bootstrap, or any design system of your choice.

πŸ“¦ Installation Guide

1. Install via NPM

npm install @jubayer11/vue-dynamic-form-builder

2. Install Required Peer Dependencies

This package uses Vuelidate internally for validation.
You must manually install the following dependencies:

npm install vue@^3.5.13 @vuelidate/core@^2.0.3 @vuelidate/validators@^2.0.4
PackagePurposeRecommended Version
vueVue.js core framework (Vue 3.x required)^3.5.13 or latest
@vuelidate/coreValidation engine (e.g., required, email)^2.0.3
@vuelidate/validatorsValidator functions for your fields^2.0.4

βœ… Vuelidate setup is already handled internally β€” no need to import or configure it manually.


πŸ“¦ Included Internal Dependencies

The following libraries are bundled inside the Dynamic Form Builder package:
(You do not need to install these separately.)

LibraryPurpose
momentFlexible and reliable date/time formatting
lodash (isEqual)Internal deep object comparison for form data checking
@vuepic/vue-datepickerLightweight and modern Date/Time picker UI for date-related fields

βœ… These dependencies are handled and maintained inside the package.
βœ… No manual installation or imports needed.

3. Import Required CSS

The package includes all styling bundled into a single compiled CSS file.

Add this line in your project (typically in main.js or main.ts):

import '@jubayer11/vue-dynamic-form-builder/dist/style.css';

βœ… This ensures all form fields, inputs, and components are styled as intended. βœ… Alternatively, you can also import it inside any local Vue component where the form is used:

import '@jubayer11/vue-dynamic-form-builder/dist/style.css';

No SCSS setup is needed β€” everything is already compiled into CSS!

Then, to run locally:

npm run dev      # Start local dev server (demo site)
npm run build    # Build for production

βœ… You're Ready!

Now you're ready to use the Vue Dynamic Form Builder.
Import the component and helper classes inside the local component where you plan to use the form:

import DynamicForm  from '@jubayer11/vue-dynamic-form-builder'
import { FieldType } from '@jubayer11/vue-dynamic-form-builder'
import { fieldType } from '@jubayer11/vue-dynamic-form-builder'
import { ValidationSetup } from '@jubayer11/vue-dynamic-form-builder'
import { CustomizableTextField } from '@jubayer11/vue-dynamic-form-builder'

Drop <DynamicForm /> into your Vue 3 component and bind it with a schema.


πŸ”§ Optional: Local Development (Testing Source Code)

If you want to test or contribute to the package locally:

git clone https://github.com/jubayer11/vue-dynamic-form-builder.git
cd vue-dynamic-form-builder
npm install

⚑ Quick Start

Get started immediately with just a few lines of code!

<template>
  <DynamicForm
    :schema="formSchema"
    v-model="formData"
    @submit="handleSubmit"
  />
</template>

<script setup>
import { ref, computed, reactive } from 'vue';
import { FieldType, CustomizableTextField } from '@jubayer/vue-dynamic-form-builder';

const nameField = new FieldType({
  fieldType: 'textField',
  label: 'Name',
  forType: 'name',
  placeholder: 'Enter your name',
});

const data = reactive(new CustomizableTextField());
data.addField(nameField);

const formSchema = computed(() => data);
const formData = ref(data.createInitialDataObject());

function handleSubmit() {
  console.log('Form submitted:', formData.value);
}
</script>

βœ… This shows:

  • Dynamic form generated by schema
  • Form data two-way bound via v-model
  • Manual submit action (@submit event)

πŸ› οΈ Schema Structure

Every form is generated dynamically based on a schema object.

The two core classes are:

  • CustomizableTextField β€” controls the overall form structure
  • FieldType β€” defines individual fields and their behaviors
import { FieldType, CustomizableTextField } from '@jubayer/vue-dynamic-form-builder';

const nameField = new FieldType({
  fieldType: 'textField',
  label: 'Name',
  forType: 'name',
});

const data = new CustomizableTextField();
data.addField(nameField);

βœ… You can add:

  • Validations (required, email, range, same-as, custom)
  • Default values
  • Field-specific custom styling
  • Flexible per-field behaviors

βœ… The system is fully dynamic β€” you control fields, design, validations, and behavior via pure JavaScript.


🎨 Styling & Design Customization

Use updateStyle() to control field design flexibly at different levels.

πŸ§‘β€πŸ’Ό Style Hierarchy (How it works internally)

  • Default Style (baseFieldClass) β€” Global fallback from textFieldStyle.
  • Custom Schema Style (customFieldClass) β€” Layout-wide style changes (example: row layout, background colors, spacing).
  • Per-Field Style (uniqueFieldClass) β€” Specific to a single field (example: making only the "Username" field bold green).

Final applied class order:

<input
  :class="[
    baseFieldClass,
    customFieldClass,
    uniqueFieldClass,
    { 'textField__default__error': hasError },
    baseIconPaddingClass,
    customIconPaddingClass,
    uniqueIconPaddingClass,
  ]"
/>

✨ How to Customize

  • Schema Level (affect all fields together):

    import { CustomizableFieldsStyle } from 'vue-dynamic-form-builder';
    
    const customStyle = new CustomizableFieldsStyle();
    customStyle.update('field.mainDiv', 'dfutils__row');
    customStyle.update('field.wrapper', 'dfutils__half');
    data.updateStyle(customStyle);
  • Field Level (affect a specific field only):

    username.updateStyle('fieldAndError.field', 'dfutils__bg_lightblue dfutils__rounded_lg dfutils__py_lg');
    username.updateStyle('label.label', 'text-bold text-green-600');

βœ… You can override:

  • Input appearance
  • Label styling
  • Dropdown behavior
  • Multi-select tags
  • Error display
  • Submit button styling

βœ… You can fully mix TailwindCSS, Bootstrap, or custom CSS classes easily.


πŸ“œ Validation System

The Dynamic Form Builder includes a powerful schema-based validation system powered by Vuelidate.

Each field can define validations declaratively during schema setup β€” no manual form-wide watchers or rules.


βœ… How to Add Validations

Attach validations using either:

nameField.addValidations(ValidationSetup.required('Name is required.'));
nameField.addValidations(ValidationSetup.minLength(2, 'Min 2 characters.'));

Or attach multiple validations at once:

passwordField.addValidationsArray([
  ValidationSetup.required('Password required.'),
  ValidationSetup.minLength(6, 'Min 6 characters.')
]);

You can also skip message for auto-label fallback:

emailField.addValidations(ValidationSetup.email());

πŸ” Custom Validations

Use ValidationSetup.custom() to define full logic-based validations:

sportsField.addValidations(
  ValidationSetup.custom(
    (value) => Array.isArray(value) && value.length <= 3,
    'You can select up to 3 sports only.'
  )
);

Or field-to-field comparisons:

detailsField.addValidations(
  ValidationSetup.custom(
    (value, formData) => value !== formData.password,
    'Details cannot match the password.'
  )
);

βœ… Custom functions receive both value and the full formData.

βœ… Must return true (valid) or false (invalid).


🧩 Supported Validation Methods

MethodDescription
required()Must not be empty
email()Must be valid email
minLength(n)Minimum string length
maxLength(n)Maximum string length
minValue(n)Minimum number
maxValue(n)Maximum number
between([min, max])Number must be between
sameAs(fieldName)Field must match another field
url()Must be a valid URL
integer()Must be a whole number
decimal()Must be a float
custom(fn)Fully custom validation logic

πŸ“‘ Backend Error Injection (Recommended)

Whether using auto or manual submit β€” you can inject backend validation errors easily:

data.setErrors({
  email: 'This email is already registered.',
  name: 'Username already taken.'
});

βœ… Keys must match forType defined during field creation.

βœ… Display will automatically happen (highlighted error + message).


🧠 Real-world Backend Example:

const handleSubmit = async () => {
  try {
    startAnimation();
    const response = await yourApiCall(formData.value);

    if (response.success) {
      alert('Form submitted successfully!');
    }
  } catch (error) {
    if (error?.response?.data?.errors) {
      data.setErrors(error.response.data.errors);
    } else {
      console.error('Unexpected error:', error);
    }
  } finally {
    stopAnimation();
  }
};

βœ… No need to manually track field-level errors β€” DynamicForm handles it internally.

πŸ‘ Manual vs Automatic Submit

By default, DynamicForm renders a built-in submit button inside the form.

βœ… But you can disable it and manage submission fully manually.


πŸ”Ή Automatic Submit (default)

const data = reactive(new CustomizableTextField());
data.updateSubmitButton(true, 'Submit');

βœ… Clicking submit triggers validation and fires @submit event automatically.


πŸ”Ή Manual Submit

You can disable the built-in submit button:

const data = reactive(new CustomizableTextField());
data.updateSubmitButton(false);

And manage the form from the parent:

<template>
  <DynamicForm
    :schema="formSchema"
    v-model="formData"
    ref="customForm"
    @submit="handleSubmit"
  />
  <button @click="manualSubmit">Submit</button>
  <button @click="resetForm">Reset</button>
</template>

<script setup>
const customForm = ref(null);

function manualSubmit() {
  if (customForm.value && typeof customForm.value.handleSubmit === 'function') {
    customForm.value.handleSubmit();
  }
}

function resetForm() {
  Object.assign(formData.value, data.createInitialDataObject());
}
</script>

βœ… Full control over:

  • Button placement
  • Loading states
  • Conditional disables
  • Popup-confirm submissions

❓ FAQ

1. How do I reset the form to its initial state?

You can reset the form by copying the initial data object back into your formData:

function resetForm() {
  Object.assign(formData.value, data.createInitialDataObject());
}

βœ… formData will be reset to the default values defined in your schema.


2. How do I manually trigger form submission?

If you are using manual submit mode, you can trigger form submission like this:

<button class="action-btn submit-btn" @click="manualSubmit">
  Submit
</button>
function manualSubmit() {
  if (customForm.value && typeof customForm.value.handleSubmit === "function") {
    customForm.value.handleSubmit(); // Validates and emits submit event
  } else {
    console.error("handleSubmit is not a function on CustomForm");
  }
}

βœ… This will trigger validation and call your custom handleSubmit method if validation passes.


3. How do I disable the built-in submit button and control buttons manually?

By default, the built-in submit button is disabled.
But to ensure manual control, call:

data.updateSubmitButton(false); // Disables built-in submit button

βœ… You can then manage Submit/Reset externally.


4. How can I inject backend/server-side validation errors into the form?

Inside your submit method (usually in a try/catch block), you can inject backend errors like this:

data.setErrors({
  email: "This email is already registered.",
  name: "Username already taken.",
});

βœ… Backend error keys must match field forType.

βœ… DynamicForm automatically highlights the field and shows the message.


5. How do I apply custom styles to a specific field only?

Use updateStyle():

username.updateStyle("fieldAndError.field", "dfutils__bg_lightblue dfutils__rounded_lg dfutils__py_lg");
username.updateStyle("label.label", "dfutils__label_right dfutils__label_bold dfutils__label_green");

βœ… Field-specific styling is very flexible.


6. Can I control the default value of a field?

Yes!
You can set defaultValue when creating a field:

const username = new FieldType({
  fieldType: fieldType.textField,
  label: "Username",
  forType: "username",
  defaultValue: "jubayer",
});

βœ… Prefills initial values inside the form automatically.


7. Can I dynamically add or remove fields from the form after creation?

Currently, the package does not officially provide dynamic add/remove after creation.

βœ… You could manipulate the schema manually and rebuild, but the focus is on predefining a clean schema first.


8. Can I create a fully custom field type if needed?

Yes!
Since fields like TextField.vue and DatePickerField.vue are modular components:

βœ… You can create your own field component.
βœ… Extend DynamicForm easily.
βœ… Handle validation, styling, and schema mapping yourself.


9. How do I validate a field using a custom validation function?

Use ValidationSetup.custom():

detailsField.addValidations(
  ValidationSetup.custom(
    (value, formData) => value !== formData.password,
    "Details cannot match the password."
  )
);

βœ… You have full access to the current field value and the entire form.


10. Can I use the form inside a popup modal? How does validation and submission behave inside modals?

Yes!
DynamicForm works perfectly inside a popup/modal.

Example:

<DynamicForm
  :schema="formSchema"
  v-model="formData"
  ref="popupForm"
  @submit="handleSubmit"
/>

<button @click="manualSubmit">Submit</button>

βœ… Manual submission inside modals works exactly like outside forms.

βœ… No third-party libraries needed β€” just your custom modal.

πŸ§ͺ Demo Gallery

Explore real-world examples of how you can use @jubayer/vue-dynamic-form-builder to build powerful and flexible forms.

Each example is available inside the demo/ folder.

DemoHighlights
Basic Prefilled FormPrefilled data, required fields, email validation, backend error simulation
Row/Column Layout FormResponsive row layout, half-width fields, structured grouping
Manual Submit + Custom ButtonsExternal submit/reset buttons, full manual control
Custom Styling per FieldPer-field label, input, and error styling overrides
Popup Form in ModalFull form handling inside a modal
All Date/Time Picker ModesSupports date, time, month, week, and year picking

πŸ”— Live Demo: https://jubayer11.github.io/vue-dynamic-form-builder/

πŸ“‚ Where to Find Demo Files

DemoFile Location
Basic Prefilled Formsrc/demo/components/demo/DemoPrefilledForm.vue
Row/Column Layout Formsrc/demo/components/demo/DemoRowForm.vue
Manual Submit + Custom Buttonssrc/demo/components/demo/DemoManualSubmitForm.vue
Custom Styling per Fieldsrc/demo/components/demo/DemoCustomStyleForm.vue
Popup Form in Modalsrc/demo/components/demo/DemoPopupForm.vue
All Date/Time Picker Modessrc/demo/components/demo/DemoDateForm.vue

βœ… Demos are real-world, production-grade examples.

πŸ“œ License

MIT License Β© 2025 Jubayer Ahmed

πŸ™Œ Credits

Designed and developed with ❀️ by Jubayer Ahmed (Portfolio) β€” Dynamic Systems β€’ Clean Code β€’ Developer Empowerment

🎯 Final Touches

  • Full Vue 3 + Composition API ready
  • 100% lightweight and modular
  • No rigid styles β€” you control everything
  • Inspired by real-world problems, built for serious developers


πŸ”— Related Projects

Looking for a customizable, fully responsive table to pair with your Vue app?

πŸ‘‰ Check out @jubayer11/vue-dynamic-table-builder
A powerful Vue 3 table builder with pagination, action buttons, responsive columns, expandable rows, and deep style/config customization.


✨ End of README ✨

If you enjoy this package, consider starring ⭐ the repository β€” it helps more developers discover it!

🀝 Interested in contributing?
Feel free to open issues, suggest improvements, or submit pull requests β€” collaboration is always welcome!

1.1.1

6 months ago

1.0.10

6 months ago

1.0.9

6 months ago

1.0.8

6 months ago

1.0.7

6 months ago

1.0.6

6 months ago

1.0.5

6 months ago

1.0.4

6 months ago

1.0.3

6 months ago

1.0.2

6 months ago

1.0.1

6 months ago

1.0.0

6 months ago