diff --git a/src/ng/directive/input.js b/src/ng/directive/input.js index aaabd1033398..1de618b9a5ed 100644 --- a/src/ng/directive/input.js +++ b/src/ng/directive/input.js @@ -386,7 +386,17 @@ function isEmpty(value) { return isUndefined(value) || value === '' || value === null || value !== value; } - +/** + * @ngdoc directive + * @name ng.directive:ngUpdateOn + * + * @description + * The `ngUpdateOn` directive postpones model updates until the given event has occurred. + * + * @example + * This example keeps validation messages from showing up while a user is still typing. + +*/ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) { var listener = function() { @@ -406,33 +416,36 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) { } }; - // if the browser does support "input" event, we are fine - except on IE9 which doesn't fire the - // input event on backspace, delete or cut - if ($sniffer.hasEvent('input')) { - element.bind('input', listener); + if (attr.ngUpdateOn) { + element.bind(attr.ngUpdateOn, listener); } else { - var timeout; + // if the browser does support "input" event, we are fine - except on IE9 which doesn't fire the + // input event on backspace, delete or cut + if ($sniffer.hasEvent('input')) { + element.bind('input', listener); + } else { + var timeout; - element.bind('keydown', function(event) { - var key = event.keyCode; + element.bind('keydown', function(event) { + var key = event.keyCode; - // ignore - // command modifiers arrows - if (key === 91 || (15 < key && key < 19) || (37 <= key && key <= 40)) return; + // ignore + // command modifiers arrows + if (key === 91 || (15 < key && key < 19) || (37 <= key && key <= 40)) return; - if (!timeout) { - timeout = $browser.defer(function() { - listener(); - timeout = null; - }); - } - }); + if (!timeout) { + timeout = $browser.defer(function() { + listener(); + timeout = null; + }); + } + }); - // if user paste into input using mouse, we need "change" event to catch it - element.bind('change', listener); + // if user paste into input using mouse, we need "change" event to catch it + element.bind('change', listener); + } } - ctrl.$render = function() { element.val(isEmpty(ctrl.$viewValue) ? '' : ctrl.$viewValue); }; diff --git a/test/ng/directive/inputSpec.js b/test/ng/directive/inputSpec.js index 4dcb79a38d12..3509760228ad 100644 --- a/test/ng/directive/inputSpec.js +++ b/test/ng/directive/inputSpec.js @@ -378,7 +378,7 @@ describe('input', function() { }); - it('should update the model on "blur" event', function() { + it('should update the model on input event', function() { compileInput(''); changeInputValueTo('adam'); @@ -386,6 +386,16 @@ describe('input', function() { }); + it('should not update the model until blur event when ng-update-on="blur" set on input element', function() { + compileInput(''); + + changeInputValueTo('pat'); + expect(scope.name).toEqual(undefined); + browserTrigger(inputElm, 'blur'); + expect(scope.name).toEqual('pat'); + }); + + it('should update the model and trim the value', function() { compileInput('');