Add keyboard event listeners in vue - vue.js

I read the documentation of vue but can't figure out what is the proper way to add keyboard event listener to my app. It just shows how to add one for input elements. I have something like:
<div>
<p>Some content</p>
<button>Go left</button>
<button>Go right</button>
</div>
I want to add an keyboard event listener so that when a user presses ← it goes left and → goes right.
It works for the button event listener, but I don't know how to make it work for keyboard.
Should I do document.addEventListener() or window.addEventListener()? I don't need the event listener for the whole app, just for that div.

It does work as expected. You just have to make sure your button is focused.
new Vue({
el: "#app",
methods: {
squack: function(text){
alert(text)
}
},
directives: {
focus: {
inserted(el) {
el.focus()
}
}
}
})
<div id="app">
<div>
<p>Some content</p>
<button #keyup.left="squack('left button clicked')" v-focus>Go left</button>
<button #keyup.right="squack('right button clicked')">Go right</button>
</div>
</div>
See this JSFiddle for example. Make sure you shift focus between buttons with Tab / Shift+Tab.

See this JS Fiddle.
Keyboard events work only when you have focus on that element. So having focus on whole <div> and having keyboard events can help. This also eliminates any need of those two left-right buttons. Elements like <button> and <a> have the ability to get focused, <div> doesn't. So we manually need to add tab index to it.
Learn more about tab index from here.

Related

Add event on slot

I'm trying to implement generic modal component with Vue 3.
And I want to close modal window on click outside the modal's content.
So I added 'close' event on modalWrapper and 'contentClick' to prevent closing (bubbling) when content is clicked:
contentClick(event:Event){
event.stopPropagation();
}
Modal:
<template>
<teleport to="body">
<div class="modal-window" v-on:click="close" v-show="isOpened">
<slot class="modal-window__content" v-on:click="contentClick($event)"></slot>
</div>
</teleport>
</template>
The problem is that contentClick(event:Event) is not fired for some reason. I can wrap slot into another div and put contentClick event on it, but not sure that it's a good solution

How to turn off drag slide in Vue agile

I am using vue-agile, and I have to show videos and images in it. The images work fine but for videos, whenever I drag the pointer to move to a certain position in the player, the slider drags and moves to the next slider. Is there any way to stop the drag/swipe feature. Thanks.
https://www.npmjs.com/package/vue-agile
As a workaround, I first watch the mouse events on the clicked element (#mousedown, #mouseup)
On mousedown, I set the swipe-distance prop to a very high pixel value in the example below I used 1,000,000,000 (Default is 50).
Doc: https://github.com/lukaszflorczak/vue-agile
This worked for my case.
<template>
<agile :dots="false" :infinite="false" :center-mode="true"
:nav-buttons="false" :swipe-distance="noSweep ? 1000000000 : 50" >
<div v-for="(card, index) in cards" :key="index">
<div
#mousedown="noSweep=true"
#mouseup="noSweep=false"
>
Card content - example
</div>
</agile>
</template>
<script>
export default {
data() {
return {
noSweep: false,
cards:['A','B','C']
}
}
}
</script>

Vue: Why only the last object is only associated to every modal which is in for loop

This is the first time I am using modal component. Inside a for loop of an array of objects, I also added a modal component, "Add Item". The v:onClick="showSectionID" function in the SHOW button within the modal should just consolelog the id of the object who's associated modal was opened and click it's respective SHOW button. But instead it is giving the id of the last object wherever I click the SHOW button from any of associated modals.
Just to test, I removed the whole modal and only kept the SHOW button and in this case it gives me the correct id. I really cannot figure out what s is wrong in the modal and searched several sources in the internet to see a similar solution but couldn't find. See code:
<div v-for="(section) in allDataObject['Section']" :key="section['uuid']">
<h4>Section Name: {{ section["sectionName"] }}</h4>
<h4>Section Description: {{ section["sectionDescription"] }}</h4>
<template>
<div>
<b-button #click="modalShow = !modalShow">Add Item</b-button>
<b-modal v-model="modalShow">Fill form to add an item !
<button v-on:click="showSectionID (section['uuid'])">SHOW</button>
</b-modal>
</div>
</template>
</div>
In your code, you are creating a modal component for each section within the for loop.
I wouldn't be surprised if actually all your modals show up on the screen, but you see the last one because it's on top of all the other ones. But it also depends on how the modal is implemented.
I suggest you to move the modal template outside your for loop and change what you store in your component data so that you know which section to show in the modal.
Let's say your data() will look like this:
data() {
return {
modalVisible: false,
modalSectionUUID: null
}
}
Then you can create two methods to show and hide the modal:
methods: {
showModal(sectionUUID) {
this.modalVisible = true;
this.modalSectionUUID = sectionUUID;
},
hideModal() {
this.modalVisible = false;
this.modalSectionUUID = null;
}
}
Now, your template will finally look something like this:
<b-modal v-model="modalVisible">Fill form to add an item !
<button v-on:click="showSectionID(modalSectionUUID)">SHOW</button>
</b-modal>
<div v-for="(section) in allDataObject['Section']" :key="section['uuid']">
<h4>Section Name: {{ section["sectionName"] }}</h4>
<h4>Section Description: {{ section["sectionDescription"] }}</h4>
<template>
<div>
<b-button #click="showModal(section['uuid'])">Add Item</b-button>
</div>
</template>
</div>

Vuejs. uiv, keep bootstrap popover alive while the popover is being hovered?

I know that there are similar questions with jquery, but this is related to vue.js
I'm using uiv which is a boostrap version for vue.js. Checking the docs I'm trying to trigger manually the popover using trigger="manual" with a hover event:
<popover title="Title" v-model="show">
Toggle Popover
<template slot="popover">
<p>Popover content</p>
</template>
</popover>
<script>
export default {
data () {
return {
show: false
}
}
}
</script>
Well, I understand why the popover is being closed due when I leave the button I set show to false.
So my question is: Where do I have to place that #mouseleave event in order to prevent closing the popover when it is being hovered?
Here I have a plunker link: https://plnkr.co/edit/gTsOJE4k8fQUMcMUpqS6?p=preview
I've solved my problem doing this:
<popover trigger="hover" title="Title">
<a href="#" #click.prevent>Toggle Popover</a>
<template slot="popover">
<p>Popover content</p>
</template>
</popover>
Basically, we can use trigger="hover" to prevent closing the popover when it is being hovered.
Take a look at this example: https://plnkr.co/edit/RSjhazfxqBhaNqcKijXe?p=preview

How to show tooltip on disabled button and hide tooltip on enabled button using dojo

need to show tooltip on disabled button and hide tooltip on enabled button using dojo.
I am having a check box and a button.
On checking the checkbox i need to enable the button, on unchecking I want to disable the button and want a tootip to tell why the button is disabled.
In general scenario for disabled button the tooltip wont come.
I got a code to display the tooltip on a disabed button from the below link
displaying dojo tooltip on a disabled validation text box
but i want the tooltip to be hidden on enabling the button . Please provide a solution
I have modified the example in the link displaying dojo tooltip on a disabled validation text box to suit your need.
html
<span id="abcd">
<input type="button" disabled="true" dojoType="dijit.form.Button" id="button1" label="MyButton" />
</span>
<div dojoType="dijit.Tooltip" connectId="button1" jsId="tt1" label = "Why the button is disabled?" ></div>
Js part
<script>
dojo.require("dijit.form.Button");
dojo.require("dijit.Tooltip");
dojo.require("dijit.TooltipDialog");
dojo.require("dojox.fx");
var dialog;
dojo.addOnLoad(function() {
dojo.connect(dijit.byId('button1').domNode,'mouseenter', function(){
console.log("HI");
// Modified code ***START***
var button = dijit.byId('button1');
var disabled = button.get("disabled");
if (disabled){ // disabled == true
tt1.open(this);
};
// Modified code ***END***
})
dojo.connect(dojo.byId('abcd'),'mouseleave', function(e){
tt1.close();
console.log("HI2")
})
tt1.addTarget(dojo.query('input', dijit.byId('someId11').domNode));
});
</script>