My issue is, the methods used for both the events is getting triggered when I perform "double click"
For example, I need to perform specific functionality when specific event is triggered.
<a (click)="method1()" (dblclick)="method2()">
Both method1()
and method2()
are getting triggered when I perform "double click".
You can use a timeout and a boolean flag to solve this.
Consider the following:
The DOM takes a few milliseconds to recognize the double click.
But it's damn sure that it recognize the double click but the first click is also recognized.
So the logic goes like this.
isSingleClick: Boolean = true;
method1CallForClick(){
this.isSingleClick = true;
settimeout(()=>{
if(this.isSingleClick){
doTheStuffHere();
}
},250)
}
method2CallForDblClick(){
this.isSingleClick = false;
doTheStuffDblClickHere();
}
Call the method one in the click event of the element and method 2 in the click event of the element.
You can the pure JavaScript call back dblclick
, Or as you use in angular 2 : (dblclick)="doubleClickFunction()"
.
If you have both (click) and (dblclick) on the same element you should add a timeout to your click event callback to avoid it been called when user double click.
Try something like:
.html:
<button (click)="singleClick()" (dblclick)="doubleClick()">click</button>
.js:
singleClick(): void{
this.timer = 0;
this.preventSimpleClick = false;
let delay = 200;
this.timer = setTimeout(() => {
if(!this.preventSimpleClick){
...
}
}, delay);
}
doubleClick(): void{
this.preventSimpleClick = true;
clearTimeout(this.timer);
...
}
It needs simple work-round to block single click then do double click. Check this example
@Component({
selector: 'my-app',
template: `
<div>
<h2>{{title}}</h2>
<button (click)="singleClick($event)" (dblclick)="doubleClick( $event)"> Click </button>
</div>
`,
})
export class App {
title:string;
preventSingleClick = false;
timer: any;
delay: Number;
constructor() {
this.title = `Angular (click) and (dblclick)`
}
singleClick(event) {
this.preventSingleClick = false;
const delay = 200;
this.timer = setTimeout(() => {
if (!this.preventSingleClick) {
alert('Single Click Event');
}
}, delay);
}
doubleClick () {
this.preventSingleClick = true;
clearTimeout(this.timer);
alert('Double Click Event')
}
}
[plunker][1]
[1]: http://plnkr.co/edit/pbsB0zYQCEY4xrPKngrF?p=preview
I just created simple solution for this. Here for the template:
<button (click)="myFunction()">Click me!</button>
And here for the script:
justClicked = false;
doubleClicked = false;
myFunction() {
if (this.justClicked === true) {
this.doubleClicked = true;
this.doubleClick();
} else {
this.justClicked = true;
setTimeout(() => {
this.justClicked = false;
if (this.doubleClicked === false) {
this.singleClick();
}
this.doubleClicked = false;
}, 500);
}
}
singleClick() {
console.log('single');
}
doubleClick() {
console.log('double');
}
I haven't found a way to do it natively in Angular (or Javascript), but here's a generic way to get it working for all your click handlers.
Although conceptually similar to the other answers, the other answers don't handle repeated clicking very well and don't maintain (and reset!) their flags on the right time.
The idea here is to maintain a flag for deciding between the click handler and dblclick handler for a shared context (same element):
- The click handler waits for a short time to rule out double clicks
- The double click handler blocks single click handlers within that waiting period
- Because a double click means two single singles, on double click, again wait for a short period of time before switching the flag back, to make sure the second single click is also blocked
Here's how you use it on your example:
<a (click)="method1()" (dblclick)="method2()"></a>
Inside your component:
const clickContext = new ClickContext();
class YourComponent {
method1 = clickContext.clickHandler(() => { /* your method1 */ });
method2 = clickContext.dblClickHandler(() => { /* your method2 */ });
}
For every context (element) where you need both a click and dblClick handler, you need to create a separate context. Luckily it is a rare requirement.
Now, by using the magic util class I'll go into below, the clicks and doubleclicks are handled properly.
Here's the class that does the flag monitoring and handler execution:
export class ClickContext {
private isSingleClick = true;
clickHandler(handler: ClickHandler): ClickHandler {
return function() {
const args = arguments;
this.isSingleClick = true;
setTimeout(() => {
this.isSingleClick && handler.apply(undefined, args);
}, 250);
}
}
dblClickHandler(handler: ClickHandler): ClickHandler {
return function() {
const args = arguments;
this.isSingleClick = false;
setTimeout(() => {
this.isSingleClick = true;
}, 250);
handler.apply(undefined, args);
}
}
}
type ClickHandler = (...any) => void;
Notice that care is taken to make sure the original arguments are passed on to the target event handler method1 and method2.