Vojtěch
Vojtěch

Reputation: 12416

vue.js: Tracking currently selected row

I have a simple table where I would like to handle click elements:

<div class="row"
     v-bind:class="{selected: isSelected}"
     v-for="scanner in scanners"
     v-on:click="scannerFilter">

    {{scanner.id}} ...
</div>

JS:

    new Vue({
        el: "#checkInScannersHolder",
        data: {
            scanners: [],
            loading: true
        },
        methods: {
            scannerFilter: function(event) {
                // isSelected for current row
                this.isSelected = true;
                // unselecting all other rows?
            }
        }
    });

My problem is unselecting all other rows when some row is clicked and selected.

Also, I would be interested to know, it it is possible accessing the scanner via some variable of the callback function instead of using this as I might need to access the current context.

Upvotes: 1

Views: 11953

Answers (2)

Bill Criswell
Bill Criswell

Reputation: 32941

I was under the impression you wanted to be able to selected multiple rows. So here's an answer for that.

this.isSelected isn't tied to just a single scanner here. It is tied to your entire Vue instance.

If you were to make each scanner it's own component your code could pretty much work.

Vue.component('scanner', {
  template: '<div class="{ selected: isSelected }" @click="toggle">...</div>',
  data: function () {
    return {
      isSelected: false,
    }
  },
  methods: {
    toggle () {
      this.isSelected = !this.isSelected
    },
  },
})

// Your Code without the scannerFilter method...

Then, you can do:

<scanner v-for="scanner in scanners"></scanner>

If you wanted to keep it to a single VM you can keep the selected scanners in an array and toggle the class based on if that element is in the array or not you can add something like this to your Vue instance.

<div
  :class="['row', { selected: selectedScanners.indexOf(scanner) !== 1 }]" 
  v-for="scanner in scanners" 
  @click="toggle(scanner)">
  ...
</div>

...
data: {
  return {
    selectedScanners: [],
    ...
  }
},
methods: {
  toggle (scanner) {
    var scannerIndex = selectedScanners.indexOf(scanner);
    if (scannerIndex !== -1) {
      selectedScanners.splice(scannerIndex, 1)
    } else {
      selectedScanners.push(scanner)
    }
  },
},
...

Upvotes: 4

Saurabh
Saurabh

Reputation: 73649

The problem is you have only one variable isSelected using which you want to control all the rows. a better approach will be to have variable: selectedScanner, and set it to selected scanner and use this in v-bind:class like this:

<div class="row"
     v-bind:class="{selected: selectedScanner === scanner}"
     v-for="scanner in scanners"
     v-on:click="scannerFilter(scanner)">

    {{scanner.id}} ...
</div>

JS

new Vue({
    el: "#checkInScannersHolder",
    data: {
        scanners: [],
        selectedScanner: null,
        loading: true
    },
    methods: {
        scannerFilter: function(scanner) {
            this.selectedScanner = scanner;
        }
    }
});

Upvotes: 8

Related Questions