Solution 1 :

Firs of all here are the definitions of click and change events as per MDN

Click Event

An element receives a click event when a pointing device button (such
as a mouse’s primary mouse button) is both pressed and released while
the pointer is located inside the element.

Change Event

The change event is fired for <input>, <select>, and <textarea>
elements when an alteration to the element’s value is committed by the
user. Unlike the input event, the change event is not necessarily
fired for each alteration to an element’s value.

Now if you see the click event is available to all elements but change is available to only input , select and textarea. Also is clear from the definition the latter is fired when the value of the element is changed/altered.

So in order to capture both the events Yes you will have to capture both separately like below.

<input type="date" #input [ngModel]="myInput" (change)="onChange($event)" (click)="onClick($event)" (keydown)="onKeydown($event)" >


export class AppComponent {
  isKeyboardChange: boolean;
  isDatepickerChange: boolean;

  onChange(event) {
    // How to check if user used the mouse to select a date
    // or if he typed a date
    console.log(event.type);
    if (this.isKeyboardChange) {
      console.log("Was changes using Keyboard");
    }

    if (this.isDatepickerChange) {
      console.log("Was changes using date picker");
    }
  }

  onClick(event) {
    this.isKeyboardChange = false;
    this.isDatepickerChange = true;
  }

  onKeydown(event) {
    this.isDatepickerChange = false;
    this.isKeyboardChange = true;
  }
}

Also with the above code you will see. When the user click on the input be it the date or the arrow, the logged value on the console will bee click and when he selects a different value from the current one the value logged will be change.

Also if you use tab to move between input elements click event wont trigger in that case focus will be fired.

Javascript Events: this is a list of events available to all the HTML Elements. This does not include the change event as its only applicable to input, select and textarea.

So the short answer to your question will be that every type of event you want to capture you will have to have a corresponding eventListener/eventHandler.

UPDATE: And in this case you might want to use keydown event which fires whenever a keyboard key is pressed down. So in this case when the user changes the value using a keyboard a keydown event will be fired just before change event and whenever a key is pressed down while the focus is on the input else if user uses the datepicker click will be fired just before change. Also when the user selects the date no click will be fired it will only fire when user clicks on the textbox to open the picker. So using these you will be able to figure out how the value was changed.

UPDATE2: edited to use keydown event instead of keypress as keypress does not captures the arrow keys and the input type date can be changed using arrow keys as well.

UPDATE3:

Browser Compatibility:

  1. Chrome: OK
  2. Firefox: OK
  3. Safari: Does not support date picker
  4. IE: Does not support date picker
  5. Edge: Supports only date picker. But arrow keys are allowed to change the date when datepicker is open (this specific case need to be handled separately as user is actually using datepicker but arrow keys may give a false impression)

Below is a small demo for the same (not in angular) but will behave exactly how it will in angular. The principles are exactly same. Have updated the stackblitz demo and it logs the way user used to change the value i.e. keyboard or datepicker.

Stackblitz Demo

function onChange(event) {
  console.log(event.type)
}

function onClick(event) {
  console.log(event.type)
}

function onFocus(event) {
  console.log(event.type)
}


function onKeypress(event) {
  console.log(event.type)
}
<input type="date" onclick="onClick(event)" onchange="onChange(event)" onfocus="onFocus(event)" onkeypress="onKeypress(event)" onkeydown="onKeypress(event)">

Hope this helps 🙂

Solution 2 :

Try using onMouseDown and onKeyDown. mouseLast would be a boolean whether or not the last event was mouseDown.

template

<input type="date" (change)="onChange($event)" (keydown)="onKey()" (mousedown)="onMouse()">

controller

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  onMouse() {
    this.mouseLast = true;
  }
  onKey() {
    this.mouseLast = false;
  }
  onChange(event) {
    if (this.mouseLast == undefined || this.mouseLast == null) {
        return;
    }
    console.log(this.mouseLast);
  }
}

Problem :

I am trying to differentiate between mouse and keyboard inputs in an input of type date:

template

<input type="date" (change)="onChange($event)">

controller

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {

  onChange(event) {
    // How to check if user used the mouse to select a date
    // or if he typed a date
    console.log(event);
  }
}

simplest stackblitz: https://stackblitz.com/edit/angular-zz2nbl

Is it possible? Do I need to subscribe to multiple, diffrent events?

Comments

Comment posted by Riscie

the problem is, that the (click) event is not behaving the way you would expect for the date input. An event gets fired when the user clicks on the down-arrow for example, but not when he selects a date. @Vega

Comment posted by Riscie

The type is always

Comment posted by Vega

If you combine it with the presence of (input) and (click), you can distinguish from where the event came ?

Comment posted by Vega

Let me try in the demo 🙂

Comment posted by stackblitz.com/edit/angular-ovijfe

Something like this, although I feel you are looking for something a bit more complex :

Comment posted by Riscie

Hi @Manish. Thank you for the detailed answer. I am aware of the diffrent event types. The problem I am trying to solve it to know, wether the change to the date value was made by a click or by keyboard input. I don’t think your example can demonstrate that?

Comment posted by Riscie

Hi again! Could you link to the updated stackblitz? I think the one I’ve created is still unchanged?

Comment posted by Riscie

Hey @Manish. I don’t think your updated example solves my problem. In the resulting change event I still can’t decide wether the user used the mouse or keyboard to initiate the change. Have a look at

Comment posted by Manish

@Riscie thats correct the order wont be same as per the other answer. But with the update i have made the order will be always the same i.e keypress first and then change and click first and then change. Let me do one thing update the stackblitz accordingly

Comment posted by Manish

@Riscie update the answer and a working demo on stackblitz. Hope this solves your problem 🙂

Comment posted by Riscie

Thank you for the answer. I was thinking about this solution. Can we actually be sure, that the

Comment posted by stackoverflow.com/questions/282245/dom-event-precedence

I did some research. It seems like the event order is not defined by the js standard. Browsers are free to implement them they want. However I see that it would always make sense to fire

Comment posted by sportzpikachu

Hey, @Riscie, sorry I couldn’t get back to you earlier, but as you said, the

By