Matteo Mazza
Matteo Mazza

Reputation: 105

how to dynamically load a vue-form-generator schema?

I need to dynamically load (part of) a form schema asynchronously. For example, I want to create the schema after a REST call.

I started using vue-form-generator, I tried to manipulate the schema creating a component that:

Code:

<template>
  <div class="panel-body">
    <vue-form-generator :schema="schema" :model="model" :options="formOptions"></vue-form-generator>
  </div>
</template>

<script>
import Vue from 'vue';
import VueFormGenerator from "vue-form-generator";

Vue.use(VueFormGenerator);

export default {
  created(){

    setTimeout(() => {
      console.log("start!");

      Vue.set(this.$data.schema.fields,
         [{
            type: "input",
            inputType: "text",
            label: "Name-TEST-success",
            model: "name",
            placeholder: "Your name",
            featured: true,
            required: true
          }]
          )

        console.log("end!");
    }, 1000);

  },
  data() {
    return {
      model: {            
        name: "John Doe"
      },

      schema: {
        fields: [{
          type: "input",
          inputType: "text",
          label: "Name-TEST-failed",
          model: "name",
          placeholder: "Your name",
          featured: true,
          required: true
        }]
      },

      formOptions: {
        validateAfterLoad:     true,
        validateAfterChanged:     true
      }
    }
  }
}
</script>

both the messages start! and end! appear in the console, but the label of the input test does not change.

How can I change the schema (and the model) dynamically?

Upvotes: 0

Views: 2891

Answers (1)

reinerBa
reinerBa

Reputation: 1660

Just put the schema in a computed property and make it dependant on a data property. So the schema will change everytime you change a property on which it depends.

export default {
  created(){

    setTimeout(() => {
      console.log("start!");
      this.labelName = "Name-TEST-success"
    }, 1000);

  },
  data() {
    return {
      model: {            
        name: "John Doe"
      },

      // Add a new property that you can change as you wish
      labelName: 'Name-TEST-failed",

      formOptions: {
        validateAfterLoad:     true,
        validateAfterChanged:     true
      }
    }
  },
  computed: {
    schema () {
        var result = {
        fields: [{
          type: "input",
          inputType: "text",
          label: this.labelName,
          model: "name",
          placeholder: "Your name",
          featured: true,
          required: true
        }]
      }
      return result     
    }
  }
}

UPDATE: You don't need computed properties, they can lead to problems with validity check. Just manipulate the properties direclty. PS: The $set method needs an index to work correct on arrays.

export default {
  created(){

    setTimeout(() => {
      console.log("start!");
      this.fieldObject.label = "Name-TEST-success"
    }, 1000);

  },
  data() {
    var fieldObject = {
          type: "input",
          inputType: "text",
          label: this.labelName,
          model: "name",
          placeholder: "Your name",
          featured: true,
          required: true
        }

    return {
      fieldObject,  // now you can change label with "fieldObject.label = ..."
      model: {            
        name: "John Doe"
      },

      schema: {
        fields: [fieldObject]
      },
      formOptions: {
        validateAfterLoad:     true,
        validateAfterChanged:     true
      }
    }
  }
}

Upvotes: 2

Related Questions