Vue Formly: JavaScript powered forms for Vue.js
vue-formly
Vue Formly is a JS based form builder heavily inspired by Angular Formly. Vue Formly was designed to provide an easy way to keep your forms consistent and to remove bloat from your code. As there's no "one way" to design your forms, Vue Formly allows you to create custom input types which you can use in your form schemas. Vue Formly itself does not come with any inputs pre-loaded but a set of Bootstrap form inputs can be installed over at Vue Formly Bootstrap, which is also used in the example below. vue-formly-bootstrap is a plugin for Vue Formly which adds multiple form fields according to Twitter Bootstrap.
Note: This is version 2 of Vue Formly and is only compatible with Vue 2.x. If you are wanting to use this with Vue 1.x then check out the Vue Formly 1 Branch.
Documentation for v2 of Vue Formly.
Options
- Form Attributes
The form object is used to track the state of the form. Whether it is valid or not, whether there are any errors etc. The following attributes will be set under each field key. e.g. if you had a field with the key of name you could access these under form.name
- Global options
These options are used by all the different field types. Some fields may have special options and these will be specified below. Check the Vue Formly docs for more info.
- Template Options
- Datepickers & Select2 style selects
Available Inputs:
- input
- select
- textarea
- list ( radio/checkbox )
Example
To start working with vue-formly use the following command to install it.
$ yarn add vue-formly
you also have to install vue-formly-bootstrap
$ yarn add vue-formly-bootstrap
Import in your project
import VueFormly from 'vue-formly'
import VueFormlyBootstrap from 'vue-formly-bootstrap'
Vue.use(VueFormly)
Vue.use(VueFormlyBootstrap)
You'll need to add your input templates. You can also create your own fields or use the Vue Formly Bootstrap plugin which requires few steps to setup.
In order to create a form you can refer to the Basic Usage section of the docs.
There are 3 properties which are required in order for vue-formly to work properly.
- :
fields
: An array which holds the schema for the fields. The actual value of each field is stored here also. This does not have to equal 'fields' and can be whatever variable you like - :
form
: An object which will hold the current state of the form. This will be populated by Vue Formly and should be left empty. - :
model
: An object which holds the model for your form. If you want to set default values this is where you would put it.
In a component it can be used like this:
// required properties, field, form, model
data () {
return {
form: {},
model: {
name: '',
sex: '',
adult: '',
comments: ''
},
fields: [
{
key: 'name',
type: 'input',
wrapper: '<div class="col-md-12"></div>',
templateOptions: {
label: 'Your name',
placeholder: 'Your full name'
}
},
{
key: 'sex',
type: 'select',
options: ['Male', 'Female', 'Other'],
templateOptions: {
label: 'Sex',
placeholder: 'Pick one...'
}
},
{
key: 'adult',
type: 'list',
options: ['Yes', 'No'],
templateOptions: {
label: 'Over 18 years old?',
inputType: 'radio'
}
},
{
key: 'comments',
type: 'textarea',
templateOptions: {
label: 'Comments'
}
}
],
}
}
The wrapper field has been added to the field schema and expects an element string. It will then wrap the field within that element.
In the template you can use the following markup:
<form @submit="handleSubmit()">
<formly-form :form="form" :model="model" :fields="fields">
<button>Submit</button>
</formly-form>
</form>
Validation
Validation can be set up against each field and can take a function or a string to evaluate against. The required attribute can also be set to make this a required field.
Validation Types:
- Expression
- Function & Asynchronous Validation
-
Object
return { form: {}, model: { name: '', sex: '', adult: '', comments: '' }, fields: [ { key: 'name', type: 'input', // add required-> true & name length > 3 required: true, validators: { length: { expression: 'model[ field.key ].length > 3', //error message to appear message: 'You must enter more than 3 characters' } }, wrapper: '<div class="col-md-12"></div>', templateOptions: { label: 'Your name', placeholder: 'Your full name' } }, ... ] } }
In the above example, the
name
field is required and it must be longer than 3 characters. To inform the user about this requirement we can use an error message. This can be done by adding amessage
property to the validator. Note that for this to work you will need to set the validation as an object.We will also need a method to handle the form when the user hits submit.
handleSubmit () { this.$refs.credentials.validate() .then(() => { if (!this.form.$valid) return alert('Your credentials are saved') // submit form }) .catch((e) => { }) },
On submit
we are calling the validate()
method on the FormlyForm component, this will run the validation checks before the form is submitted.
<form @submit.prevent="handleSubmit()">
<formly-form :form="form" :model="model" :fields="fields" ref="credentials">
<button>Submit</button>
</formly-form>
</form>
Also, the .prevent
modifier is used to prevent the page from reloading.
Valid state
There is also a $valid
attribute that is added to the form and is toggled between true
and false
if all the errors are clear. In the above example, when the user first loads the form, vm.form.$valid
will be false as there are required fields. Once they've filled in those fields and the criteria are met, vm.form.$valid
will become true.
Note that validate()
will resolve even if the form is invalid. It should only reject if there was some actual error with the validation. With this in mind you should still check the validity of the form before submitting in.
That's it! If you would like to explore more about vue-formly & vue-formly-bootstrap, head to the project's repository on GitHub, where you will also find the source code, and visit the Docs.