Home > other >  How to get an object from an array on button click in vue
How to get an object from an array on button click in vue

Time:10-18

I have created a table and in the table I am looping through an array of objects.

    <table class="table table-striped" v-if="bins.length > 0">
        <thead>
        <tr>
            <th scope="col">#</th>
            <th scope="col">Location</th>
            <th scope="col" class="text-end">Action</th>
        </tr>
        </thead>
        <tbody>
        <tr v-for="(bin, index) in bins" :key="index">
            <th scope="row">{{index   1}}</th>
            <td ref="txtLocaton" contenteditable="false" v-text="bin.binlocation"></td>
            <td class="text-end">
            <div class="action-btn">
                <button @click="btnEdit"><fa icon="edit" /> Edit</button>
                <button><fa icon="trash" /> Delete</button>
            </div>
            </td>
        </tr>
        </tbody>
    </table>

What I would like is that on the Edit button click, I want to change the contenteditable attribute from false to true.

This is the code for the data()

<script>
export default {
    data(){
        return{
            bins:[
                {
                    binlocation: '11 Garden Block, New City',
                },
                {
                    binlocation: 'Ali Towers, Lahore'
                },
                {
                    binlocation: 'The Mall Road'
                }
            ]
        }
    },

    methods:{
        btnEdit(){
          console.log(this.$refs.txtLocaton)
        }
    }
}
</script>

I am thinking about changing the attribute using "ref" but when I console it, it is returning the last array on button click

CodePudding user response:

You may store contenteditable keys in bins array (false initially?):

[{
  binlocation: '11 Garden Block, New City',
  contenteditable: false,
}, {
  binlocation: 'Ali Towers, Lahore',
  contenteditable: false,
}, ...]

Then bind contenteditable td attribute to those values (instead of passing false directly):

<td ref="txtLocaton" :contenteditable="bin.contenteditable" v-text="bin.binlocation"></td>

And simply toggle values as you wish when 'edit' button pressed:

<button @click="bin.contenteditable = !bin.contenteditable"><fa icon="edit" /> Edit</button>

or

<button @click="btnEdit(index)"><fa icon="edit" /> Edit</button>
btnEdit(index) {
  this.bins[index] = !this.bins[index]; 
}

CodePudding user response:

Try like following snippet (You can pass index to your method and bind contenteditable attribute to data property):

new Vue({
  el: '#demo',
  data(){
    return{
      bins:[
        {binlocation: '11 Garden Block, New City',},
        {binlocation: 'Ali Towers, Lahore'},
        {binlocation: 'The Mall Road'}
      ],
      editable: null
    }
  },
  methods:{
    btnEdit(index){
      this.editable = index
    }
  }
})

Vue.config.productionTip = false
Vue.config.devtools = false
.editable {
  border: 2px solid violet;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
  <table class="table table-striped" v-if="bins.length > 0">
    <thead>
      <tr>
        <th scope="col">#</th>
        <th scope="col">Location</th>
        <th scope="col" class="text-end">Action</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(bin, index) in bins" :key="index">
        <th scope="row">{{index   1}}</th>
        <td ref="txtLocaton" :contenteditable="index === editable" :class="index === editable && 'editable'" v-text="bin.binlocation"></td>
        <td class="text-end">
        <div class="action-btn">
          <button @click="btnEdit(index)"> Edit</button>
          <button> Delete</button>
        </div>
        </td>
      </tr>
    </tbody>
  </table>
</div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related