Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
Ben Nadel at BFusion / BFLEX 2009 (Bloomington, Indiana) with: Kevin Schmidt
Ben Nadel at BFusion / BFLEX 2009 (Bloomington, Indiana) with: Kevin Schmidt ( @schmidtkevinall )

Learning About The "Input" Event From Angular 2

By Ben Nadel on

When I started digging into Angular 2, I saw that, internally, the framework was binding to (input) events on Input and Textarea elements in order to power the ngModel directives. At first, I assumed that this was some sort of special Angular 2 event proxy; but, the more I picked it part, the more I realized that no translation was taking place. And, that's when I finally realized that the "input" event was a native JavaScript DOM (Document Object Model) event - it was just one that I had never heard of. So, I figured I would put together a quick demo in case this DOM event slipped under anyone else's radar.


 
 
 

 
 
 
 
 

Run this demo in my JavaScript Demos project on GitHub.

The "input" event, unlike the "change" event, is a synchronous event that is triggered as the user is interacting with the text-based input controls. Meaning, it doesn't wait for a blur event to calculate the value-change - the input event is triggered immediately after any mutation of the value property (whether it be through user key-stroke events or user paste events).

The "input" event has cross-browser support for text-based Input and Textarea elements but only partial support for Select elements. For a Select element, you're better off just listening for the "change" event. Checkboxes, while inputs, don't seem to fire the input event; so, for checkboxes, you should use "change" as well.

Anyway, here's a quick demo - in this case, I'm using good-old jQuery to bind to the events just to clarify that this has absolutely nothing to do with Angular 2.

  • <!doctype html>
  • <html>
  • <head>
  • <meta charset="utf-8" />
  •  
  • <title>
  • Learning About The Input Event From Angular 2
  • </title>
  •  
  • <link rel="stylesheet" type="text/css" href="./demo.css"></lin>
  • </head>
  • <body>
  •  
  • <h1>
  • Learning About The Input Event From Angular 2
  • </h1>
  •  
  • <p>
  • Focus the input and start typing. Stuff be loggin'.
  • </p>
  •  
  • <form>
  • <input type="text" />
  •  
  • <textarea></textarea>
  •  
  • <select>
  • <option value="1">One</option>
  • <option value="2">Two</option>
  • <option value="3">Three</option>
  • </select>
  •  
  • <input type="checkbox" />
  •  
  • <button type="reset">Clear</button>
  • </form>
  •  
  •  
  • <!-- Load demo scripts. -->
  • <script type="text/javascript" src="../../vendor/jquery/jquery-2.1.0.min.js"></script>
  • <script type="text/javascript">
  •  
  • // Let's compare the Input event to the Change event.
  • // --
  • // NOTE: Select elements don't fire "input" consistently on all browsers. For
  • // Select, you are better off listening to the "change" event.
  • $( "input, textarea, select" )
  • .on( "input", handleInputEvent )
  • .on( "change", handleChangeEvent )
  • ;
  •  
  •  
  • // I log the change events.
  • function handleChangeEvent( event ) {
  •  
  • console.log( "Change Event:", event.target.value );
  •  
  • }
  •  
  •  
  • // I log the input events. Input events are fired SYNCHRONOUSLY as the input
  • // element's value is changed by the user interaction.
  • function handleInputEvent( event ) {
  •  
  • console.log( "Input Event:", event.target.value );
  •  
  • // CAUTION: The input event CANNOT be canceled. Putting this statement
  • // in here to demonstrate that behavior.
  • event.preventDefault();
  •  
  • }
  •  
  • </script>
  •  
  • </body>
  • </html>

As you can see, we're simply binding to the "input" event and logging out the input value with each event. And, when we run the above code and interact with the input element, we get the following output:


 
 
 

 
 Input event in JavaScript fires synchronously as the user edits input text. 
 
 
 

As you can see, the "input" event is being fired with every change the user makes to the input. In contrast, the "change" event is only fired at the end once I blur the form field.

This is so cool. I can't believe I had never heard of the "input" event until I started digging into the Angular 2 source code. This is way more elegant than trying to listen for key-events and click-events in an attempt to capture all input mutations.



Looking For A New Job?

Ooops, there are no jobs. Post one now for only $29 and own this real estate!

100% of job board revenue is donated to Kiva. Loans that change livesFind out more »

Reader Comments

Hi,

How to listen if the value has been updated by some Javascript code.
For example:- say the target of the input field is $ele then if i update it like $ele.value = "testing" then how to listen for this change from Angular2 code.

@Nagarjun,

Angular wasn't really designed to listen for changes on inputs that are altered by external libraries. At least, not as far as I know. So, approaching the problem would really depend on how you are trying to use it. For example, you could always get a ref to the element and access the value that way:

<form (submit)="handleSubmit( elem.value )>
<input #elem />
</form>

... where we export the element as "elem" and then explicitly check the value when we submit the form.

I suppose you could always create a directive that watches the value on some sort of timer and emits a different value. Like:

<input (syntheticInput)="handleInputChange( $event.value )" />

... where [syntheticInput] is the selector of a custom directive that monitors the input value with a setInterval() or something and then emits "syntheticInput" events whenever the value changes.

It all depends on what you want to do.