diff --git a/src/ui-codemirror.js b/src/ui-codemirror.js index 480f4f2..7be9547 100644 --- a/src/ui-codemirror.js +++ b/src/ui-codemirror.js @@ -10,7 +10,7 @@ angular.module('ui.codemirror', []) /** * @ngInject */ -function uiCodemirrorDirective($timeout, uiCodemirrorConfig) { +function uiCodemirrorDirective($timeout, $rootScope, uiCodemirrorConfig) { return { restrict: 'EA', @@ -132,6 +132,28 @@ function uiCodemirrorDirective($timeout, uiCodemirrorConfig) { }); } }); + + // Commit as with NgModelController + codemirror.on('blur', function() { + if (ngModel.$touched) { + return; + } + + if ($rootScope.$$phase) { + scope.$evalAsync(ngModel.$setTouched); + } else { + scope.$apply(ngModel.$setTouched); + } + }); + + // Debounce as with NgModelController + if (ngModel.$options && ngModel.$options.updateOn) { + ngModel.$options.updateOn.split(/\s+/).forEach(function(trigger) { + codemirror.on(trigger, function() { + ngModel.$$debounceViewValueCommit(trigger); + }); + }); + } } function configUiRefreshAttribute(codeMirror, uiRefreshAttr, scope) { diff --git a/test/codemirror.spec.js b/test/codemirror.spec.js index 6b315d4..dfc3a5e 100644 --- a/test/codemirror.spec.js +++ b/test/codemirror.spec.js @@ -111,6 +111,7 @@ describe('uiCodemirror', function() { return codemirror; }); + window.CodeMirror.signal = _constructor.signal; window.CodeMirror.defaults = codemirrorDefaults; }); @@ -274,6 +275,34 @@ describe('uiCodemirror', function() { }); + it('when the IDE changes should update the model on blur', function() { + // Define values + var oldValue = 'bar'; + var newValue = 'baz'; + + // Create codemirror editor and bind with updateOn blur + var element = $compile('
')(scope); + var ctrl = element.controller('ngModel'); + + // Check initial states + expect(ctrl.$pristine).toBe(true); + expect(ctrl.$valid).toBe(true); + scope.$apply('foo = "' + oldValue + '"'); + expect(scope.foo).toBe(oldValue); + expect(codemirror.getValue()).toBe(oldValue); + + // Change text but DO NOT blur + codemirror.setValue(newValue); + expect(scope.foo).toBe(oldValue); + expect(codemirror.getValue()).toBe(newValue); + + // Blur and observe change to model + window.CodeMirror.signal(codemirror, 'blur', codemirror); + expect(scope.foo).toBe(newValue); + expect(ctrl.$valid).toBe(true); + expect(ctrl.$dirty).toBe(true); + }); + it('when the model changes should update the IDE', function() { var element = $compile('
')(scope); var ctrl = element.controller('ngModel');