Vuejs How the select range of button

Viewed 53

I have a question,

I have some buttons in a v-for, and I need to allow the user to select from A to C for example, as I show in the graphic. Also, the user can press a button, for example, D. my v-for looks like this

<menu-item 
   v-for="(item, index) in menu"
   :key="`item_${index}`"
   @click="setMenuItem(index, item.name)"
/>

then I have data property selectedItems where I add all the item when the user clicks on setMenuItem().

The option when the user clicks just in one Item work fine but when the user has selected from A to C, I can't make it work.

Generally, What I need, is when clicking on a range of buttons from A to C for example, I want to push into my selectedItems data property each item.name which I pass a second argument into my setMenuItem()

Graphic graphic

2 Answers

to do this you have to first have a way to check if the index belong to range or not.

you may create a constant like this:

const RangeSelection = [0,1,2] // you may also add names. I am taking index.

now on you setMenuItem function simply add this check.

setMenuItem(index,name) {
    if(RangeSelection.includes(index)) {
        // this is range selection
         

    } else {
         // this is single selection
         this.selectedItems = [];
         this.selectedItems.push(name)
    }

}

in setMenuItem method, you have parameter index which can be used to set the selected value, for the example:

options = [{name: 'a'},{name: 'b'},{name: 'c'}]
selectedValue = [];
setMenuItem(index, name) {
  this.selectedValue = [...options].slice(0, index)
}

for the example I click menu b, the selectedValue will contain [{name: 'a'},{name: 'b'}]

the problem with code above is that it will pick the start from index 0, hence you need to add one more validation to calculate if it's start index, you can use this logic (note, you have to pass the whole item @click="setMenuItem(index, item)" in the component)

setMenuItem(index, item) {
  const start = this.selectedValue.findIndex((selected) => item.name === selected.name)
  this.selectedValue = [...options].slice(start || 0, index + 1)
}
Related