1

My goal is to replicate the functionality typeform (see question #2) provides with their keyboard friendly forms. I want to generate a list of potential answers to my question using v-for (easy) and assign each of them a keycode which binds a letter to each button (possible?).

I have two problems:

  1. Is it possible to assign a keycode to a list using v-for? (I can't predict the amount of possible answers to a question, it could be anywhere from 2+.)

    None of the following attempts work:

@keydown.:button.key :@keydown.button.key @keydown.{{button.key}}

  1. How do you make this keydown functionality work globally? The only way it works right now is if you tab to the button so it's currently in focus and then press the key which is hardcoded.

Fiddle: https://jsfiddle.net/ffgvw3yr/5/

altShiftDev
  • 1,564
  • 1
  • 9
  • 20

1 Answers1

1
  1. You can process your keyboard event, store result and in your list match element index with processed key:

    <button class="query-input" type="button"
        v-for="(button, index) in questions.attrs"
        @click="answer(button.id, button.name)"
        :class="{ 'selected': index === selected}"
      >{{button.key}} {{ button.name }}</button>
    
  2. You can register your keyboard event processing function when component is mounted:

    methods: {
      processKeydown(e) {
        var key = 'a';
        for (let i = 0; key !== 'z'; i++) {
          if (e.key === key) {
            this.$set(this, 'selected', i);
            break;
          }
          key = String.fromCharCode(key.charCodeAt(0) + 1);
        }
      },
    },
    mounted() {
      window.addEventListener('keydown', this.processKeydown);
    },
    beforeDestroy() {
      window.removeEventListener('keydown', this.processKeydown);
    },
    

Example: JSFiddle snippet

Sui Dream
  • 530
  • 5
  • 15
  • That would do it, much obliged! Adding the event listener to Window was the missing piece to issue #2. As for your processKeydown(e) function, it seems like magic but I'll play with it until it makes sense. – altShiftDev Oct 02 '17 at 18:20
  • @Scott, `beforeDestroy` should be called automatically [before component is destroyed](https://vuejs.org/v2/guide/instance.html#Lifecycle-Diagram) (I don't sure if `removeEventListener` is needed, or Vue just removes event anyway). And `String.fromCharCode(key.charCodeAt(0) + 1);` part I found [here](https://stackoverflow.com/questions/12504042/what-is-a-method-that-can-be-used-to-increment-letters). – Sui Dream Oct 02 '17 at 18:30