nu everest nu everest - 3 months ago 24
Javascript Question

Why is Vue.js key modifier only working for `<button>` and not `<div>`?

Please refer to this codepen for a working example.

If you click the button and use the up/down arrow keys the button padding will increase/decrease.

The relevant HTML is:

<div class="inline-block {{ highlight_css }}">
<button @click="toggleEditMode"
@keydown.up.prevent="morePadding"
@keydown.down.prevent="lessPadding"
v-bind:style="padding"
class="bgc-hf8f8f8 font-size-1rem line-height-23 bold border-1px-solid-gray border-radius-3">
{{ status_text }}<br>padding: {{ amount }}px;
</button>
</div>


Sample Vue.js method for Up Arrow key:

morePadding: function() {
if(this.editable) {
this.amount++;
this.padding = 'padding: ' + this.amount + 'px;';
}
},


Everything works great until I change the
<button>
tag to a
<div>
tag. The
@click
works, but the Key Modifiers seems broken.

I read the docs, but couldn't find something that says
<div>
tags are special.

Answer

div elements are not focusable by default. To make them focusable, you can add a tabindex attribute. Use a negative value if you don't want the element to be iterated by sequential navigation.

new Vue({
  el: '#highlight',
  data: {
    button_text: 'Disabled',
    amount: 0,
    highlight_css: '',
    padding: '',
    editable: false
  },
  methods: {
    toggleEditMode: function() {
      this.editable = !this.editable;
      this.changeText();
      this.highlight();
    },
    changeText: function() {
      if(this.editable){
        this.button_text = 'Enabled';
      }
      else {
        this.button_text = 'Disabled';
      }
    },
    highlight: function() {
      if(this.editable){
        this.highlight_css = 'border-2px-solid-orange border-radius-3';
      }
      else {
        this.highlight_css = '';
      }
    },
    morePadding: function() {
      if(this.editable) {
        this.amount++;
        this.padding = 'padding: ' + this.amount + 'px;';
      }
    },
    lessPadding: function() {
      if(this.editable && this.amount > 0) {
        this.amount--;
        this.padding = 'padding: ' + this.amount + 'px;';
      }
    }
  }
});
@import 'https://cdn.jsdelivr.net/foundation/6.2.0/foundation.min.css';
.inline-block {
  display: inline-block
}
.bold {
  font-weight: bold
}
.border-5px-solid-orange {
  border: 5px solid orange
}
.talign-center {
  text-align: center
}
.border-1px-solid-gray {
  border: 1px solid gray
}
.bgc-blue {
  background-color: blue
}
.border-radius-3 {
  border-radius: 0.1875em
}
.display-none {
  display: none
}
.white {
  color: white
}
.padding-top-50 {
  padding-top: 3.125em
}
.padding-5 {
  padding: 0.3125em
}
.padding-10 {
  padding: 0.625em
}
.padding-top-20 {
  padding-top: 1.25em
}
.bgc-hf8f8f8 {
  background-color: #f8f8f8
}
.margin-top-30 {
  margin-top: 1.875em
}
.border-1px-solid-orange {
  border: 1px solid orange
}
.text-align-center {
  text-align: center
}
.display-inline {
  display: inline
}
.red {
  color: red
}
.margin-bottom-20 {
  margin-bottom: 1.25em
}
.border-2px-solid-orange {
  border: 2px solid orange
}
.line-height-23 {
  line-height: 1.4375em
}
.font-size-1rem {
  font-size: 1rem
}
.margin-top-50 {
  margin-top: 3.125em
}
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.js"></script>
<div id="highlight" class="row padding-top-20">
  <div class="large-12 columns large-centered text-align-center margin-top-30">
    <!--Editing Container-->
    <div class="margin-bottom-20">Click the button.<br>Then use the up and down arrow keys to change button padding.</div>
    <div class="inline-block {{ highlight_css }}">
      <div tabindex="-1" type="submit" @click="toggleEditMode" @keydown.up.prevent="morePadding" @keydown.down.prevent="lessPadding" style="{{ padding }}" class="bgc-hf8f8f8 font-size-1rem line-height-23 bold border-1px-solid-gray border-radius-3">
        {{ button_text }}<br>padding: {{ amount }}px;
      </div>
    </div>
  </div>
  <div class="large-12 columns margin-top-50">
    <pre>{{ $data | json }}</pre>
  </div>
</div>

Comments