# vuex-simple-form

> **Vuex Simple Form**\ VueJS form with vuex, inspired by Rails gem simple_form, which simplify the process of making form in Vue with following goals:

Latest version **0.0.11** (published 2017-12-11) · MIT license · 0 weekly downloads

## Install

```sh
npm install vuex-simple-form
pnpm add vuex-simple-form
yarn add vuex-simple-form
bun add vuex-simple-form
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.0.11 |
| Published | 2017-12-11 |
| First published | 2017-11-27 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 9 |
| Known vulnerabilities | 0 (+3 in 2 direct dependencies) |
| Install scripts | no |
| Author | Hoang Nguyen |
| Maintainers | hoangvn2404 |

## Links

- npm: https://www.npmjs.com/package/vuex-simple-form
- npm.io page: https://npm.io/package/vuex-simple-form

## Dependencies (9)

- [pug](https://npm.io/package/pug.md) ^2.0.0-rc.4
- [vuex](https://npm.io/package/vuex.md) ^3.0.1
- [webpack](https://npm.io/package/webpack.md) ^3.8.1
- [babel-core](https://npm.io/package/babel-core.md) ^6.26.0
- [css-loader](https://npm.io/package/css-loader.md) ^0.28.7
- [vue-loader](https://npm.io/package/vue-loader.md) ^13.5.0
- [babel-loader](https://npm.io/package/babel-loader.md) ^7.1.2
- [babel-preset-env](https://npm.io/package/babel-preset-env.md) ^1.6.1
- [vue-template-compiler](https://npm.io/package/vue-template-compiler.md) ^2.5.9

## Recent versions

- 0.0.11 (latest) — 2017-12-11
- 0.0.10 — 2017-12-08
- 0.0.9 — 2017-12-08
- 0.0.8 — 2017-12-07
- 0.0.7 — 2017-12-07
- 0.0.6 — 2017-12-07
- 0.0.5 — 2017-12-07
- 0.0.4 — 2017-12-01
- 0.0.3 — 2017-11-28
- 0.0.2 — 2017-11-28
- 0.0.1 — 2017-11-28
- 1.0.5 — 2017-11-27
- 1.0.4 — 2017-11-27
- 1.0.3 — 2017-11-27
- 1.0.2 — 2017-11-27
- … 1 more at https://npm.io/package/vuex-simple-form/versions

## README

**Vuex Simple Form**\
VueJS form with vuex, inspired by Rails gem simple_form, which simplify the process of making form in Vue with following
goals:

> * Auto generate code for form quickly using bootstrap 4 style(support for all input type with label & error-indicator
>   for each field)
> * Handle client-side validations (on typing)
> * Handle server-side validations (after submit form)
> * Simple to use

**DEMO**

# ![Form For](./assets/vuex-simple-form.gif)

```html
<form @submit.prevent='onSubmit'>
    <field for='title' />
    <field for='description' />
    <field for='completed' type='checkbox' :collection='options.completed' />
    <field for='completed' type='radio' :collection='options.completed_radio' />
    <field for='days' type='checkbox' :collection='options.days' :inline='true' />
    <button class='btn btn-primary' type='submit'>
      Save
    </button>
  </form>
```

Just wanna play with it? [Check out my sandboxes](https://codesandbox.io/s/0160wrwqyv?module=%2FApp.vue)

## Installation

Install the core package:

```bash
npm install vue-simple-form --save
```

## Vuex setup

import VuexForm from the package

```javascript
import VuexForm from 'vuex-simple-form'

Vue.use(Vuex)

const store = new Vuex.Store({
  modules: {
  	form: VuexForm,
    ... // your other modules
  }
})
```

then add store to our Vue App

```javascript
new Vue({
  el: '#app',
  store: store,
  template: '<App/>',
  components: { App }
})
```

Vuex form module provide you with the following getters & actions

**Getters**

* _`form (Object)`_ our current form object
* _`disabled (Boolean)`_ return true if form pass all validation checking (both client & server side)
* _`validateErrors (Object)`_ return the client validated errors as an object with following methods:
  * `all()` return all errors
  * `any()` return `true` if there is any errors
  * `get(field_name)` return error detail for `field_name`
  * `has(field_name)` return true if there is error for `field_name`

**Actions**

* _`set_form({form_object})`_ set the form

### Create new form

```javsacript
import { mapActions } from 'vuex'

export default {
  data: () => ({
    todo: {
      title: 'a',
      description: 'def',
      completed: true,
      days: [1,2]
    }
  }),

  methods: {
    ...mapActions(['set_form'])
  },

  created: function() {
    this.set_form({
      ...this.todo
    })
  }
}
```

the set_form object can take additional 2 parameters

| Params     | Description                                          | Default |
| ---------- | ---------------------------------------------------- | ------- |
| horizontal | set form horizontal (label & input in the same line) | false   |
| validator  | set client-side validation rules (detail below)      | null    |

### Import the Field Component

Currently vuex-simple-form only support Bootstrap 4 input components, more are coming. Don't forget to add Bootstrap 4
CSS to your application, the easiest way is to add CDN to your `index.html` file

```html
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb"
      crossorigin="anonymous">
```

You only need to import only one Component for all type of input

```javascript
import { BS4Field as Field } from 'vuex-simple-form'
export default {
	components: { Field },
    ... // your component data, methods, computed, etc
}
```

Following are all field props you can use

| Property    | Description                                                                                      | Type                                          | Required | Default        |
| ----------- | ------------------------------------------------------------------------------------------------ | --------------------------------------------- | -------- | -------------- |
| for         | the variable that the input present                                                              | String                                        | `Yes`    |                |
| type        | `text` `password` `number` `date` `checkbox` `radio` `textarea` `select`                         | String                                        | `No`     | `text`         |
| label       | label for the input, if you pass a string, it will be the label, pass `false` for turn off label | String/Boolean                                | `No`     | the field name |
| placeholder | placeholder                                                                                      | String                                        | `No`     | `null`         |
| collection  | options for input with type `checkbox/radio/select`                                              | `[{text: xxx, value: xxx}, ...]` or `[a,b,c]` | `No`     | `[]`           |
| inline      | additional option for input type `checkbox/radio/select` to set all the options stay in one line | Boolean                                       | `No`     | `false`        |

When using with pug/jade templating language for writing html, you could make form with very few lines of code like this

```html
<template lang='pug'>
form(@submit.prevent='onSubmit')
  field(name='title')
  field(name='first_name')
  field(name='description')
  field(name='completed', type='checkbox', :collection='options.completed')
  field(name='completed', type='radio', :collection='options.completed_radio')
  field(name='days', type='checkbox', :collection='options.days', :inline='true')
  button.btn.btn-primary(type='submit', :disabled='disabled') Save
</template>
```

and a form like this will be generate for you

# ![Form For](./assets/form.png)

## Client-side validation

Client side validation can be easily done by create a validator function and pass to the set_form action (inspired by
redux-form validation) Below is a function that take form data and return errors in form of object.

```javascript
// creat validator function
const TodoValidator = values => {
  const errors = {}
  const addErrors = (field, text) => { errors[field] = (errors[field] || []).concat(text) }

  if (!values.title) addErrors('title', "Can't be blank")
  if (values.title.length < 2) addErrors('title', 'Must have at least 2 characters')
  if (!values.description) addErrors('description', "Can't be blank")
  if (!values.completed) addErrors('completed', "Must be tick")
  return errors
}

// pass the validation functions to the set_form action
created: function() {
    this.set_form({
      ...this.todo,
      horizontal: true,
      validator: TodoValidator
    })
  },
```

## Submitting the form & Handle server side validation

the form data to be submit can be call by this.form.data() then you can use any network library to call api to submit
the form

```javascript
import { mapGetters } from 'vuex'
....
export default {
  computed: mapGetters(['form']),
  methods: {
    ... // other methods, etc

    onSubmit() {
      const data = this.form.data()
      axios.post(url, data)
        .then(response => {
          console.log(response)
        })
        .catch(error => {

          // transform the error to an object, here is just an example
          const server_errors = {
            title: ["Can't be blank", 'too short'],
            description: "Can't be blank"
          }

          // use the following call to add server errors to vuex form
          this.form.errors.record(server_errors)
        })
      )
    }
  }
}
```

## Motivation

Vuex-simple-form is inspired by\
[Simple Form](https://github.com/plataformatec/simple_form), a gem that greatly facilitates creating forms in Rails.\
[Redux Form](https://github.com/erikras/redux-form) The Server Validation is inspired by this.\
[Laracasts Vue 2 series](https://laracasts.com/series/learn-vue-2-step-by-step/episodes/19) The form object approach and
client side validation.

The idea of vuex-simple-form is not something new, it just I could not find the tool to satisfy all my need, so I decide
to write a new one, also it help me to learn alot, it's my first time try to write one. I have implement it on my
project using Bootstrap 4, hopefully it could help you too.

---
_Source: https://npm.io/package/vuex-simple-form · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
