title: ng-model not updating with on-screen keyboard on Chrome OS
body: <p>A ChromeOS device puts up a virtual keyboard when you select in an input.</p>
  
  <p>Inside my angular component I have an <code>input</code> control bound to a property:</p>
  
  <pre><code>&lt;input type="text" ng-model="$ctrl.searchText" /&gt;
  </code></pre>
  
  <p>I want this to work via a touch screen.
  If I click in the control, the touch screen keyboard appears.</p>
  
  <p>I press the touch keys and the letters appear in the input, but the <code>set searchText</code> method doesn't get called until the text box loses focus.</p>
  
  <p>If I plug in a USB keyboard and enter text, the <code>set searchText</code> method gets called with every new character. It just fails with the onscreen touch keyboard.</p>
  
  <p>I tried setting different options using <a href="https://docs.angularjs.org/api/ng/directive/ngModelOptions" rel="nofollow noreferrer">ngModelOptions</a>:</p>
  
  <pre><code>&lt;input type="text" ng-model="$ctrl.searchText" ng-model-options="{updateOn: 'keyup keydown default blur click touch touchup touchdown'}" /&gt; 
  </code></pre>
  
  <p>This does not change the behavior.</p>
  
  <p><hr />
  I've created the simplest example I could using Plunker. Sure enough, if I browse to the site on the chrome device and use the touch keyboard, the value does not update as you add text. But if I use a USB keyboard, it does update.</p>
  
  <p><a href="http://embed.plnkr.co/bIwMp88BB8gNHFenayfz/" rel="nofollow noreferrer">http://embed.plnkr.co/bIwMp88BB8gNHFenayfz/</a></p>
  
  <p><hr />
  I found <a href="https://w3c.github.io/uievents/tools/key-event-viewer.html" rel="nofollow noreferrer">this Keyboard Event Viewer utility</a> which prints out the exact sequence of keyboard-related events.</p>
  
  <p>I notice some things that are different about the chrome onscreen keyboard: </p>
  
  <ul>
  <li>the <code>keyup</code> event fires with the <code>key</code> value sets to unidentified.</li>
  <li>the onscreen keyboard fires extra events: <code>compositionstart</code>, <code>compositionupdate</code>, but seems to be flakey around the <code>compositionend</code> event.</li>
  </ul>
  
  <p>When I enter the 'a' key via the keyboard, the following events are fired:</p>
  
  <pre><code>| Event type        | data | Input Field |
  |-------------------|------|-------------|
  | keydown           |      | ''          |
  | keypress          |      | ''          |
  | beforeinput       | 'a'  | ''          |
  | input             | 'a'  | 'a'         |
  | keyup             |      | 'a'         |
  </code></pre>
  
  <p>When I enter the 'a' key using the touch screen, the following events are fired. These are the same events, but with the added <code>compositionstart</code>, <code>compositionupdate</code> events.</p>
  
  <pre><code>| Event type        | data | Input Field |
  |-------------------|------|-------------|
  | keydown           |      | ''          |
  | compositionstart  |      | ''          |
  | beforeinput       | 'a'  | ''          |
  | compositionupdate | 'a'  | ''          |
  | input             | 'a'  | 'a'         |
  | keyup             |      | 'a'         |
  </code></pre>
  
  <p>It needs to fire the <code>compositionend</code> event. But it doesn't!</p>
  
  <p>The <code>composition</code> events are very significant in the angular code. The <a href="https://github.com/angular/angular.js/blob/c484213180470c2a8044eeb09dfdc5ef11099bc8/src/ng/directive/input.js#L1247" rel="nofollow noreferrer">relevant code</a> is in input.js, where it defers any handling until the <code>compositionend</code> event:</p>
  
  <pre><code>   // In composition mode, users are still inputting intermediate text buffer,
    // hold the listener until composition is done.
    // More about composition events: https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent
    if (!$sniffer.android) {
      var composing = false;
  
      element.on('compositionstart', function() {
        composing = true;
      });
  
      // Support: IE9+
      element.on('compositionupdate', function(ev) {
        // End composition when ev.data is empty string on 'compositionupdate' event.
        // When the input de-focusses (e.g. by clicking away), IE triggers 'compositionupdate'
        // instead of 'compositionend'.
        if (isUndefined(ev.data) || ev.data === '') {
          composing = false;
        }
      });
  
      element.on('compositionend', function() {
        composing = false;
        listener();
      });
    }
  
    //....
  
    var listener = function(ev) {
       // ...
       if (composing) return;
       // ...
    }
  </code></pre>
  
  <hr>
  
  <p>I have submitted this as a defect to google:</p>
  
  <p><a href="https://bugs.chromium.org/p/chromium/issues/detail?id=818881" rel="nofollow noreferrer">Entering character with on-screen keyboard fails to trigger 'compositionend' event</a></p>