Select rows from a table with arrow keys

Asked

Viewed 609 times

1

I am trying to develop a code to be able to navigate between the lines of an html table using the navigation arrows.

what would be the best way? I need the selected line to stay with a different class.

my code is like this:

           <tr v-for="(item, index) in itens_adicionados">
                    <td class="text-right">{{ item.item }}</td>
                    <td class="text-right">{{ item.codigo }}</td>
                    <td></td>
                    <td class="text-right">{{ item.descricao }}</td>
                    <td class="text-center">{{ item.quantidade }}</td>
                    <td class="text-right">{{ item.valor_unitario }}</td>
                    <td class="text-right">{{ item.valor_total }}</td>
                </tr>
  • Face I may be wrong, but a table is not a static element, in order to navigate the keys would have to be editable no?!

1 answer

0

There are several ways to do this. I leave a suggestion that listens in the window all through events keydown and specifically by the up and down keys.

You can also limit to an element and use the hooks/Hooks to Vue with @keyup.up="changeRow(-1)" if you prefer. The advantage is that you do not need to clean the headphone with removeEventListener the drawback is that for this Vue hook to work the focus of the page has to be within the element that has the keyup.up.

Example:

const dataArray = [{
    number: 0,
    text: 'foo'
  },
  {
    number: 1,
    text: 'bar'
  },
  {
    number: 2,
    text: 'baz'
  }
];

const getRowIncrement = (e) => {
  if (e.keyCode === 38) return -1;
  if (e.keyCode === 40) return 1;
  return 0;
}

new Vue({
  el: "#app",
  data: {
    linha: 0,
    tableData: dataArray,
  },
  methods: {
    changeRow(e) {
      const rowIncrement = getRowIncrement(e);
      if (!rowIncrement) return;
      
      e.stopPropagation();
      e.preventDefault();
      this.linha = (this.linha + rowIncrement + this.tableData.length) % this.tableData.length;
    }
  },
  mounted() {
    window.addEventListener('keydown', this.changeRow);
  },
  beforeDestroy() {
    window.removeEventListener('keydown', this.changeRow);
  }
})
table {
  border-collapse: collapse
}

td {
  padding: 5px;
}

.chosen {
  background-color: #ccf;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>

<div id="app">
  <table>
    <tr v-for="line in tableData" :key="line.number" :class="line.number === linha ? 'chosen' : ''">
      <td v-for="prop in line" :key="prop">{{prop}}</td>
    </tr>
  </table>
</div>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.