16

I have this input field I am using for a search:

<input id="search_input" type="text" ng-model="filter.search_terms">

There are many other filters I use as well (checkboxes, radio, etc) and I have a $watch on filter so any changes will fire a search. The problem is that I don't want the search to fire for the text field every time I type a letter and only want it to "save" it on the filter.search_terms only once I press enter.

Is there an easy way to do this or do I have to remove the ng-model and do an ng-click with a function that sets it on enter?

Dragonfly
  • 4,261
  • 7
  • 34
  • 60

3 Answers3

34

You can try adding ng-model-options="{updateOn : 'change blur'}" to your input tag. Should work.

MiTa
  • 1,340
  • 11
  • 12
  • 5
    That's it. Am I the only one who expected that the documentation (e.g., https://docs.angularjs.org/api/ng/directive/ngModelOptions) would have a list of what you can put in ng-model-options and what it would do? It is not clear to me why "change blur" has the particular behavior it has. – Marc Stober Jun 20 '17 at 17:22
  • This doesn't work on IE11 because in IE the "change" event is not emitted, when the "enter" key is pressed. The way I worked that around is I replaced the "change" event with a custom "keydown_enter" one and created a directive that emits "keydown_enter", when "keydown" with `keycode === 13` is triggered on the DOM element. Fyi – d-ph Feb 16 '18 at 17:32
13

Neither of the answers here seem to fully answer the question. The question was how to get the model to ONLY update on pressing enter. I'm sure the original poster has moved on, but for others who may find this, I'll add my approach. I think ninjaPixel got the closest. My response is based off of his directive.

The missing piece however is preventing the default ng-model directive from updating in other cases. To do that, I added an option to the input to update on keyup:

ng-model-options="{updateOn: 'keyup'}"

This overrides the default which updates on input events (for text fields) and forces the update to occur on keyup. This allows our directive to prevent the original ng-model directive's default action by stopping event propagation in our custom keyup handler:

if (ev.keyCode !== 13) return ev.stopImmediatePropagation();

A working codepen can be found here: http://codepen.io/jessehouchins/pen/MbmEgM

Jesse Houchins
  • 151
  • 1
  • 4
8

You can achieve this behaviour by creating a directive called updateOnEnter and then adding this attribute to your HTML element.

<input id="search_input" type="text" update-on-enter ng-model="filter.search_terms">

angular.module('app').directive('updateOnEnter', function() {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, element, attrs, ctrl) {
            element.on("keyup", function(ev) {
                if (ev.keyCode == 13) {
                    ctrl.$commitViewValue();
                    scope.$apply(ctrl.$setTouched);
                }
            });
        }
    }
});
Carlos Morales
  • 5,676
  • 4
  • 34
  • 42
ninjaPixel
  • 6,122
  • 3
  • 36
  • 47
  • 3
    what here tells angular **not** to update unless the key goes up? I see the event, but what's preventing the normal updating of the model? – jeremy Aug 03 '16 at 23:51
  • also duplicated on https://stackoverflow.com/questions/32176130/angular-update-input-value-on-enter-keypress-and-work-in-ie – Saad Benbouzid Jul 27 '17 at 09:17
  • @jeremy : your question has been answered on top comment https://stackoverflow.com/a/40756181/704246 – Saad Benbouzid Jul 27 '17 at 09:18