0

I am trying to prepare a dynamic form that generates a form based on the columns present in the database table. Each form field is based on the columns present in the database table.

import { mapGetters } from 'vuex'
export default {
  name: 'NewRecord',
  data () {
    return {
      columnName: {

      }
    }
  },
  computed: {
    ...mapGetters(['columns'])
  },
}

I am using mapGetters to pull columns from state. Structure of columns is :

[ 
{ "name": "id", "type": "varchar(255)", "label": "Id", "align": "left", "field": "id", "sortable": true, "__iconClass": "q-table__sort-icon q-table__sort-icon--left", "__thClass": "text-left sortable", "__tdClass": "text-left" }, 
{ "name": "username", "type": "varchar(80)", "label": "Username", "align": "left", "field": "username", "sortable": true, "__iconClass": "q-table__sort-icon q-table__sort-icon--left", "__thClass": "text-left sortable", "__tdClass": "text-left" } 
{.......
.......}
]

I am generating form via following code:

<div class='columns row'>
<div class='col-3'
       v-for='col in columns'
       :key='col.name'>
<input standard type='text' :label='capital_letter(col.label)'
v-model="col.name"></input>
</div>
</div>

How can I use that v-model="col.name" in data property for two way binding. Any help will be very much appreciated.

Sujan Shrestha
  • 1,020
  • 1
  • 18
  • 32
  • Could you include an example of the data you want to bind to the form fields? – skirtle Sep 01 '19 at 20:00
  • As you can see above I am making form fields from v-for loop. Form fields are created from columns array of objects as show in above structure. i have used v-mode="col.name" , this data i want to bind in data property. @skirtle – Sujan Shrestha Sep 01 '19 at 20:53
  • So you want users to be able to edit the names of the database columns? – skirtle Sep 01 '19 at 20:59

1 Answers1

1

To manage two way binding to the state in a loop, I think you'll need to avoid v-model. Instead, you probably want to call a mutation on the change event. So your input will look like this:

<div class='col-3' v-for='(col, index) in columns' :key='col.id'>
<input
  standard
  type='text'
  :label='capital_letter(col.label)'
  :value="col.name"
  @input="changeColumn($event, index)"
>
</div>

Notice that we're passing in the index from the loop, so you can target the appropriate column in the method below. Then, in methods:

changeColumn(event, index) {
    this.$store.commit('updateColumn', {i: index, value: event.target.value})
}

Then, using the payload object, change the appropriate column in your store (put this in mutations in the store):

updateColumn(state, payload) {
    state.columns[payload.i].name = payload.value
}

Remember that in your view, you'll also need "...mapMutations(['updateColumn'])" etc...

You can read more about v-model with the state in the Vuex docs: https://vuex.vuejs.org/guide/forms.html

  • Could you elaborate? Are you getting any error messages? First, I'd check that the @input event is firing. Then, in your store file, in updateColumn, log the payload to make sure that's coming through. Also, I'd recommend install Vue DevTools if you haven't already, so you can check your Vuex state. – Teddy Michels Sep 02 '19 at 17:20
  • I am getting this in vue devtools in computed section: updateColumn:"(error during evaluation)" – Sujan Shrestha Sep 02 '19 at 17:38
  • 1
    Also when i try to edit the form field i am getting these errors: Property or method "event" is not defined on the instance but referenced during render Error in v-on handler: "TypeError: Cannot read property 'target' of undefined" – Sujan Shrestha Sep 02 '19 at 17:43
  • I this main problem is in this line: this.$store.commit('updateColumn', {i: index, value: event.target.value}) Error in v-on handler: "TypeError: Cannot read property 'target' of undefined" – Sujan Shrestha Sep 02 '19 at 17:56
  • I figured out. Instead of event.target.value we should use event only. – Sujan Shrestha Sep 02 '19 at 18:26
  • event.target.value worked for me because the event returned an object, but it sounds like we may have had some differences in our markup that changed the event behavior. Actually now I see your input has a closing tag, so maybe you're using some kind of custom component? Regardless, glad you got it figured out. – Teddy Michels Sep 02 '19 at 20:56
  • Thank You.. I am trying some other things so i have not quite completed my work. For now i am accepting your question as your method help me binding the form values. Can we communicate in other social media platform. I have few more question. – Sujan Shrestha Sep 03 '19 at 07:29
  • 1
    Great - thanks! Instagram would work: https://www.instagram.com/v0.run/ – Teddy Michels Sep 03 '19 at 20:22