Nebulous
Nebulous

Reputation: 92

VueJS Dynamic Model Binding

We are currently looking at using VueJs 2.0 on our latest project, however we've hit a bit of a wall quite early on, and we're hoping there is an easy solution to it!

So we are using Laravel to generate over 150 form fields, we want to bind these params to Vue. Currently, using Angular 1.4, we just have ng-model="form.data.field" and it create a nice big object to send to the backend for processing...

It would appear with Vue that you have to define everything explicitly within the data param, we have tried to define an object such as:

data:{
  form: {}
}

which then works for v-model="form.item" but v-model="form.item.item2" errors.

Is it possible to replicate this in VueJS?

http://jsbin.com/jafetucuna/edit?html,js,console,output

Upvotes: 4

Views: 3935

Answers (2)

Konkret
Konkret

Reputation: 1021

If you wanted dynamic model binding, the simplest approach to this is probably with array array like this:

<input v-model="formFields[index]" />

Then map every form input using a computed property

  computed: {
    aFormInputName: function() {
      return this.formFields[0].value
    },

Then you get something like this evaluate as true:

formFields[0] === aFormInputName

You can extract the proper way of doing this here, but it isn't exactly an example of what I've outlined.

https://forum.vuejs.org/t/how-do-i-have-dynamic-v-model/18833

Upvotes: 0

retrograde
retrograde

Reputation: 2979

I've got a project doing something similar. It has several core fields but users can add in their own fields, all of which are rendered dynamically. We store the fields in as json in a section_schema table with 4 columns: |id | section_name | schema | disable

The schema contains anything that we would need to render the dynamic form. Some of the specific formatting for our core data gets a little clunky but it works pretty well. I skipped the prep we do on the backend because I didn't want this to get too long. Here are the basics:

basic json in section_schema:

{
   "Company Name":{
      "cols":"8",
      "field_name": "company_name",
      "type":"string",
      "order":"0",
      "required":"1"
   },
   "Member Type":{
      "cols":"4",
      "field_name": "member_type",
      "type":"dropdown_fromdata",
      "order":"1",
      "required":"1",
      "dropdown":{"table" : "membershipType", "field": "name"}
   },
   "Website":{
      "cols":"4",
      "field_name": "company_website",
      "type":"string",
      "order":"2",
      "required":"0"
   },
   ... others

in vue component:

<div class="col-sm-6" v-for="v in dataType">
   <div class="white-box">
     <h3 class="box-title">{{v.section_name}}</h3>
        <form class="form-material form-horizontal m-t-30" :id="v.section_id">
            <input type="hidden" :value="v.section_id" id="type" name="type">
                 <div class="form-group" v-for="i in v.field_data">
                     <label class="col-md-12" :for="i.id">{{i.name}}</span></label>
                      <div class="col-md-12">
                        <select v-if="i.id === 'company_info-member_type'" class="form-control" style="width: 100%;" size="1" :value="i.value" :id="i.id" :name="i.id">
                          <option value="" selected disabled>Please select</option>
                          <option v-for="mt in membershipTypes" :value="mt.name">{{mt.name}}</option>
                        </select>
                        <select v-else-if="i.id === 'company_info_status'" class="form-control" style="width: 100%;" size="1" :value="i.value" :id="i.id" :name="i.id">
                            <option value="" selected disabled>Please select</option>
                            <option v-for="status in statuses" :value="status.name">{{status.name}}</option>
                        </select>
                       <datepicker v-else-if="i.id === 'company_info-anniversary'" :format="format" :value="setDate(i.value)" :id="i.id" :name="i.id"></datepicker>
                       <input v-else-if="i.type == 'phone'" :type="i.type" :id="i.id" :name="i.id" class="form-control" :placeholder="i.name" :value="i.value" data-mask="(999) 999-9999">
                       <input v-else :type="i.type" :id="i.id" :name="i.id" class="form-control" :placeholder="i.name" :value="i.value">
                      </div>
                 </div>

         <button  @click.prevent="saveMemberChanges(v.section_id)" class="btn btn-info waves-effect waves-light m-r-10">Submit</button>  
     </form>
   </div>
 </div> 

Edit: more info

Our data:

data () {
        return {
            dataType: [],
        }
},
methods: {
        getDataTypes: function(){
            var id = this.member.id

            this.$http.get('/member/details/json/'+id).then((response) => {
                var data = response.data
                this.dataType = data
            }, (response) => {
               ...
            });
        },
}

Upvotes: 1

Related Questions