4

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

6
  • 1
    It's hard to say because I don't know what structure of your data is and what form fields you send from API.But let's imagine you are getting data from API and you will of course dynamically store them into data object - model.Then you can iterate over each object from reponse in your array and dynamically assign model for each value - input field - take look here jsbin.com/kugazopuwu/1/edit?html,js,console,output Hope i understood well your issue, if not sorry Commented Feb 21, 2017 at 21:56
  • Hi thanks for your response - your answer is good although it uses VueJS to render all of the form elements. Unfortunately for security and latency reasons all of the field generation has to be done via blade templates in Laravel. Commented Feb 21, 2017 at 22:14
  • hmm.. I cannot see any errors on v-model="form.item.item2" jsbin.com/laduyaqumi/edit?html,js,console,output Commented Feb 21, 2017 at 23:36
  • But that defines all of the data in the Vue instance, which I am trying to avoid due to the levels in nesting required in our dataset. Commented Feb 22, 2017 at 9:05
  • jsbin.com/jafetucuna/edit?html,js,console,output is what I am after Commented Feb 22, 2017 at 9:09

2 Answers 2

1

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) => {
               ...
            });
        },
}
Sign up to request clarification or add additional context in comments.

2 Comments

We ended out generating the schema on the backend similarly to this. Accepted as the answer, even if we don't like it! :)
lol. If you find something better, please keep me in mind, I'd like to see it.
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.