vi-form-builder
v2.5.34
Published
The **Form Builder** plugin for Vue 3 is a dynamic tool that allows developers to create customizable forms based on JSON configurations. It supports a variety of field types, custom components, and flexible layouts. The plugin simplifies the process of b
Keywords
Readme
Form Builder Plugin for Vue 3
The Form Builder plugin for Vue 3 is a dynamic tool that allows developers to create customizable forms based on JSON configurations. It supports a variety of field types, custom components, and flexible layouts. The plugin simplifies the process of building and managing forms by offering a configurable, extendable, and intuitive structure for form elements. It provides features like field grouping, custom field registration, form validation, and automatic form submission.
Supported Field Types
1. group
2. input
3. textarea
4. checkbox-group
5. radio-group
6. file-upload
7. select
- A dropdown selection field.
8. select-ajax
- A dynamic select field that fetches options from an API.
9. date
- A date picker field.
10. password
11. button
12. Custom Fields
- Developers can create custom fields by creating Vue components and registering them with the plugin.
Validation
- Validation is handled using Vuelidate, and developers can apply rules like
required,minLength, etc., to form fields.
Additional Features
- Automatic Submission: The form can automatically submit when data changes (via
autoSubmit). - Styling: The plugin supports customizable CSS variables and classes for adjusting form appearance.
Installation
npm install vi-form-builderIntegration
Integrate Plugin into a Vue App
import ViFormBuilder from "vi-form-builder";
import {createApp} from 'vue';
import App from './App.vue';
const app = createApp(App).use(ViFormBuilder);Import the styles
@import "vi-common/style.css";
@import "vi-form-builder/style.css";Usage Examples
To see usage examples, download the project and run:
cd playground
npm run devForm Props
| Prop | Type | Description | Default Value |
|------------------|--------------------------|------------------------------------------------------------------|---------------|
| config | Array | Array of fields to display in the form. | / |
| modelValue | Object | Object to hold the form data. | / |
| layout | vertical, horizontal | Layout for the form, either vertical or horizontal. | vertical |
| submitAction | Function | Function to handle form submission and return a promise. | / |
| hideSubmit | Boolean | Whether to hide the submit button. | false |
| autoSubmit | Boolean | Automatically submit the form when data changes every 2 seconds. | false |
| buttonLabel | String | Label for the submit button. | Save |
| resetOnSuccess | Boolean | Whether to reset form data after successful submission. | false |
| omitNulls | Boolean | Null values will be removed from model when form is submitted. | false |
Field Options
| Option | Type | Description | Default Value |
|---------------|------------------------------------------------|-----------------------------------------------------------------------------------------------------|----------------|
| field | group, input, textarea, checkbox, etc. | Field component to display. | / |
| name | String | Name of the field in the form data model. | / |
| label | String | Label for the field. | / |
| hideLabel | Boolean | Whether to hide the field label. | false |
| placeholder | String | Placeholder text for the field. Defaults to the label if not specified. | / |
| info | String | Additional text displayed above the field. | / |
| hint | String | Additional text displayed below the field. | / |
| isVisible | Function | Function that determines field visibility based on form data. | Always visible |
| rules | Object | Validation rules (e.g., Vuelidate rules or custom validation). | / |
| transform | Function | Function that wil transform the original field value (do not use it in combination with sync model) | / |
Additional Field Props by Type
| Field Type | Prop | Type | Description | Default Value |
|--------------------------|------------------|---------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------|------------------------------|
| group | title | String | Title for a group field. | / |
| group | children | Array | Array of fields in a group. | / |
| group | horizontal | Boolean | Whether fields in a group should be displayed horizontally. | false |
| group | flatModel | Boolean | Whether group field data should appear at the root level of the model. | false |
| input | type | 'text', 'email', 'url', 'number', 'numeric' | Input type | text |
| input ,textarea | debounce | Number | Number of milliseconds for debounce of input value | 300 |
| textarea | rows | Number | Number fo rowsfor textarea | 6 |
| checkbox-group | options | Array | Array of objects tha have label and value | / |
| radio-group | options | Array | Array of objects tha have label and value | / |
| file-upload | multiple | Boolean | Are multiple files upload allowed | false |
| file-upload | bucket | String | Name of bucket used to upload files to S3 | / |
| file-upload | extensions | Array | Array of strings for allowed extensions (optional) | ex: ['.jpg','.png','jpeg'] |
| file-upload | maxFiles | Number | Number of maximum allowed files to be uploaded if multiple is true | / |
| select | otpions | Array | Array of options for select | / |
| select, select-ajax | multiple | Boolean | Can be selected more then one value | false |
| select, select-ajax | optionValue | String | If options is array of objects which field should be considered as value for the otpion | / |
| select , select-ajax | optionLabel | String | If options is array of objects which field should be considered as label for the otpion | / |
| select | emitValue | Boolean | If options is array of objects should only value be emitted or the whole object (does not work with multiple true in select ajax) | true |
| select, select-ajax | clearable | Boolean | If selected value can be remove form the input (only for single select) | false |
| select, select-ajax | objectOptions | Boolean | If options are list of ojects not strings | true |
| select-ajax | fetchOptions | Function | Function that returns proimse with response for the otpions that needs to appeaer in the select | / |
| select-ajax | rowsPerPage | Number | Number of options displayed and returned form server on every request | 50 |
| select-ajax | infiniteScroll | Boolean | Should load more options when end fo srcoll is riched | false |
- For date field we use this library, every prop form here can be used in config for any date field or as global setting for date fields
- For select and select-ajax fields we use this library, every prop form here can be used in config for any select os select-ajax field
Example Field Configuration
[
{
label: 'First Name',
field: 'input',
name: 'firstName',
},
{
label: 'Last Name',
field: 'input',
name: 'lastName',
},
{
label: 'Email',
field: 'input',
type: 'email',
name: 'email',
},
{
field: 'group',
name: 'address',
horizontal: true,
children: [
{
label: 'City',
field: 'input',
name: 'city',
rules: {required},
},
{
label: 'Zip',
field: 'input',
name: 'zip',
rules: {required},
},
{
label: 'State',
field: 'input',
name: 'state',
},
],
},
]Registering Custom Field Types
The Form Builder supports default fields like input, textarea, checkbox, etc. To add custom fields:
- Create a Vue component for the custom field.
- Register the component in the plugin options.
Example: Creating a Rating Component
<template>
<div class="rating">
<rating-star v-for="i in 5" :key="i" :color="color" :filled="i"></rating-star>
</div>
</template>
<script>
export default {
name: 'Rating',
props: {
field: String,
modelValue: {},
name: String,
label: String,
color: String,
},
};
</script>Register the Custom Field
import Rating from "./components/Rating.vue";
import ViFormBuilder from "vi-form-builder";
const app = createApp(App)
.use(ViFormBuilder, {
fieldComponents: {Rating},
});
// Use the new field type in your field configuration:
fields: [
{
label: 'Rate our service',
field: 'rating',
name: 'rating',
color: 'yellow',
},
];Field Validations
Validation is handled using Vuelidate. Example validation rules:
import {required, minLength} from "@vuelidate/validators";
const config = [
{
label: 'First Name',
name: "firstName",
field: "input",
placeholder: "First Name",
rules: {
required,
minLength: minLength(3),
},
},
];Styling
CSS Classes
| Class Name | Description |
|---------------------------------------------------|----------------------------------------------------------------------------|
| .vi-form-builder | Class on the form |
| .vi-form-builder.no-submit | Classes for form without submit button. |
| .vi-form-builder.with-submit | Classes for form with submit button. |
| .vi-form-builder.horizontal | Class for from with horizontal layout |
| .vi-form-builder.vertical | Class for from with vertical layout |
| .vi-form-field | wrapper class around each field |
| .vi-form-field.group | wrapper class around group field |
| .vi-form-field .vi-form-label | class for lable of the field |
| .vi-form-field .field-container | wraaper class around field content (field, hint, info, errors) |
| .field-container .info | class for field info |
| .field-container .hint | class for field hint |
| .field-container .field-error | class for div that holds one field error |
| .field-container .field | class for div that holds one field error |
| .group-title | class for div that holds title for the group |
| .vi-form-field .field-container .group-fields | class for div that is contatiner which holds all the fields in the group |
CSS Variables
| Variable Name | Usage | Default Value |
|------------------------------------|---------------------------------------------------------------------------|--------------------------|
| --vi-form-primary-color | Main general color for brand identity | #5C67F7 |
| --vi-form-primary-light-color | Lighter version of primary color | 30% from primary color |
| --vi-form-neutral-color | Colors used for displaying error messages and border when field has error | #d8d8d8 |
| --vi-form-neutral-color-light | | |
| `--vi-form-neutral-color-light-2` | | |
| --vi-form-contrasting-text-color | | |
| `--vi-form-field-padding` | | |
| --vi-form-error-color | | |
| `--vi-form-background` | | |
| --vi-form-input-height | | |
| `--vi-form-input-padding` | | |
| --vi-form-input-background | | |
| `--vi-form-input-border-radius` | | |
| --vi-form-input-border-width | | |
| `--vi-form-input-border-color` | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
GLOBAL SETTINGS
Field value transform global settings
For every field we can provide transform function to transform the value of the field before submit/input, we can do the same also globally, only when we use this globalay we cna only set it per field type. For example:
const app = createApp(App);
app.use(ViFormBuilderPlugin, {
...,
transforms: {
"select-ajax": (value, field) => {
return field.multiple ? (value??[]).map(val => val[field.optionValue]): value[field.optionValue]
}
});This means that every time when we submit a form which has field of type select-ajax, this function will be called to tranform the value unless we have transform setting locally set for the filed. Example use case would be , you have registered custom filed 'use-select' where every time use ris selected we wnt to get the id not the whole object
Style global settings
You can override all css variables in the options when plugin is installed:
const app = createApp(App);
app.use(ViFormBuilderPlugin, {
...
style: {
'primary-color': '#f18080',
'primary-light-color': '#f18080',
'error-color': 'red',
}
});File upload global settings
Under fileSettings we can define:
- getPreSignedUrl - must be defined, this function should return pre-sgined url from aws s3 for uplading files
- bucket - s3 bucket name must be proivded here or in th global settings or as config in the date field
createApp(App)
.use(ViFormBuilderPlugin, {
fileSettings: {
getPreSignedUrl({file, bucket}) {
return fetchGraphQL(query, {file, bucket})
},
bucket: 'file-upload'
}
})Field date global settings
From vue-datepicker library we can use any prop as global settings for date field:
createApp(App)
.use(ViFormBuilderPlugin, {
dateSettings: {format: 'HH:mm'}
})Toastify global settings
{
toastify: {
autoClose: 2000,
theme
:
'colored',
hideProgressBar
:
true
}
,
successMessage:'Form Saved'
}Steps for adding changes for contributors
- git pull origin main
- add and test your changes in playground
- change the version in package.json
- vite build
- git push origin main
- npm publish
