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.

  1. : 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
  2. : form: An object which will hold the current state of the form. This will be populated by Vue Formly and should be left empty.
  3. : 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 a message 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.