Data Model

#'data' Property

The data property of the form gives you an object which has all the values of elements represented in the proper structure. Let's see what we mean by that:

// 'data' property of the form:

        
          
<script>
  export default {
    mixins: [Laraform],
    data: () => ({
      schema: {
        name: {
          type: 'text',
          label: 'Name'
        },
        contact: {
          type: 'object',
          schema: {
            email: {
              type: 'text',
              label: 'Email'
            },
            phone: {
              type: 'text',
              label: 'Phone'
            }
          }
        },
        actors: {
          type: 'list',
          label: 'Favorite actors',
          element: {
            type: 'text',
            placeholder: 'Name'
          }
        }
      }
    })
  }
</script>
        

The data property can be accessed within the form:

export default {
  mixins: [Laraform],
  data: () => ({
    schema: {
      ...
    }
  }),
  created() {
    // renders form data
    console.log(this.data)
  }
}

#Filtered Property

The filtered property is the same as data except for one thing: it excludes elements which has conditions that are not fulfilled or for which the submission has been disabled.

The filtered property can be accessed within the form:

export default {
  mixins: [Laraform],
  data: () => ({
    schema: {
      ...
    }
  }),
  created() {
    // renders form data
    console.log(this.filtered)
  }
}

#Using Vuex

You have two ways how you can use Laraform with Vuex. First is a simplified approach for quick setup, while the second gives you more customizablity.

#Using Store-Path

You can pass a string to you main Laraform component as a store-path property which should represent the Vuex state path. For example:

// app.js

import Vue from 'vue'
import Vuex from 'vuex'
import Laraform from '@laraform/laraform'
import ChangePasswordForm from './path/to/ChangePasswordForm.vue'

Vue.use(Vuex)

const store = Vuex.Store({
  state: {
    forms: {
      changePassword: {}
    }
  }
})

// Make store available for Laraform so state changes
// are done properly with mutations instead of altering
// state directly.
Laraform.store(store)

Vue.use(Laraform)

const app = new Vue({
    el: '#app',
    store,
    components: {
      ChangePasswordForm
    }
})
<!-- index.html -->

<div id="app">
  <change-password-form store-path="forms.changePassword"></change-password-form>
</div>

Now everything that changes in the Vuex store will be represented in the form and vice verse.

#Overriding Store Property

Laraform has a computed property called store which is responsible for setting and getting form data for external Vuex state. By default it retrieves the value based on the store-path property from Vuex state and mutates the same value when the form's data is changed.

You can override this computed property, using it's set and get function:


<script>
  export module {
    mixins: [Laraform],
    name: 'ChangePasswordForm',
    data: () => ({
      // ...
    }),
    computed: {
      store: {
        get() {
          // get value from Vuex store
        },
        set(value) {
          // set value to Vuex store
        }
      }
    }
  }
</script>

#Manipulating Data

The form's and its element's data can be changed via their API as we will see in this section.

#Load

To load a complete set of data for a form, you can call the form's .load(data) method. This method accepts an object which contains data for the whole form. For example:

Form's `data`:

      
          
<script>
  export default {
    mixins: [Laraform],
    data: () => ({
      schema: {
        name: {
          type: 'text',
          label: 'Name'
        },
        contact: {
          type: 'object',
          label: 'Contact',
          schema: {
            email: {
              type: 'text',
              placeholder: 'Email'
            },
            phone: {
              type: 'text',
              placeholder: 'Phone'
            }
          }
        }
      }
    }),
    mounted() {
      this.load({
        name: 'John Doe',
        contact: {
          email: 'john@doe.com'
        }
      })
    }
  }
</script>
        

As you can see the name and contact.email elements received values according to the data object given to the .load() method.

Now let's see what happens if an element has a default value and the loaded data does not contain any value for that:

          
<script>
  export default {
    mixins: [Laraform],
    data: () => ({
      schema: {
        name: {
          type: 'text',
          label: 'Name'
        },
        email: {
          type: 'text',
          label: 'Email',
          default: 'john@doe.com'
        },
      }
    }),
    mounted() {
      this.load({
        name: 'John Doe'
      })
    }
  }
</script>
        

In this case the name element has its value set to John Doe, while email is emptied. That's because the purpose of .load() is to load a complete set of form data and therefore clears any element which is not represented in the loaded data.

To leave the form as it is and only update certain elements without clearing others, you can use .update() which is described next.

#Update

Contrary to .load(data), .update(data) method does not empty elements which don't have data represented in the data provided for the method.

So in our previous example if we used .update() instead of .load() the email field would've kept it default value.

Let's see that in action to make sure:

          
<script>
  export default {
    mixins: [Laraform],
    data: () => ({
      schema: {
        name: {
          type: 'text',
          label: 'Name'
        },
        email: {
          type: 'text',
          label: 'Email',
          default: 'john@doe.com'
        },
      }
    }),
    mounted() {
      this.update({
        name: 'John Doe'
      })
    }
  }
</script>
        

#Reset

By calling .reset() method the elements of the form will get into their initial state, meaning being set to their default values or if none given, being emptied.

#Clear

By calling .clear() method the values of the element will be emptied.

#Reaching Elements

Not only the form's data can be manipulated as a whole but you can also load, update, reset and clear elements individually. To do so you can reach the elements using the form's .el$(path) method:


export default {
  mixins: [Laraform],
  data: () => ({
    schema: {
      name: {
        type: 'text',
        default: 'John Doe'
      }
    }
  }),
  mounted() {
    // Outputs: 'John Doe'
    console.log(this.el$('name').value)
  }
  created() {
    this.$nextTick(() => {
      // Outputs: 'John Doe'
      console.log(this.el$('name').value)
    })
  }
}
Be aware that elements are not available right at the created() hook, only after they are mounted. If you need to reach them there, make sure you use $nextTick().

Element Path

The path is a string representation of an element's location in the form using dot . syntax.

Let's see an example which includes a regular and nested elements:

export default {
  mixins: [Laraform],
  data: () => ({
    schema: {
      // Regular element
      name: {
        type: 'text',
        label: 'Name'
      },

      // Nested object element
      contact: {
        type: 'object',
        label: 'Contact',
        schema: {
          email: {
            type: 'text',
            label: 'Email'
          }
        }
      },

      // Nested single element list
      actors: {
        type: 'list',
        label: 'Favorite actors',
        element: {
          type: 'text',
          placeholder: 'Name'
        }
      },

      // Nested object list
      cars: {
        type: 'list',
        label: 'What cars you have?',
        object: {
          schema: {
            make: {
              type: 'text',
              placeholder: 'Make'
            },
            model: {
              type: 'text',
              placeholder: 'Model'
            }
          }
        }
      }
    }
  })
}

The path of the elements above looks like this:

Name element: 'name'

Contact element: 'contact'
Email element of contact: 'contact.email'

Actors element: 'actors'
Item of actor list: 'actors.0, actors.1, ...'

Cars element: 'cars'
Items of car list: 'cars.0, cars.1'
Elements of car list items: 'cars.0.make, cars.0.model, ...'
Note that if you are trying to reach nested elements from lifecycle hooks you might need to use $nextTick() to do so. This is because the form reaches it's elements by their `ref` which only updates in a new cycle.