From 5766a6a173dc1d65b9293fd5bd0bcbc21b0791ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matias=20Niemela=CC=88?= <matias@yearofmoo.com> Date: Wed, 19 Feb 2014 14:08:25 -0500 Subject: [PATCH] fix(ngModel): ensure checkboxes and radio buttons are flagged as dirty when changed Closes #569 Closes #585 --- lib/directive/ng_model.dart | 2 ++ test/directive/ng_model_spec.dart | 52 +++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/lib/directive/ng_model.dart b/lib/directive/ng_model.dart index 1ac6f9dce..7621a0c2e 100644 --- a/lib/directive/ng_model.dart +++ b/lib/directive/ng_model.dart @@ -141,6 +141,7 @@ class InputCheckboxDirective { }; inputElement.onChange.listen((value) { scope.$apply(() { + ngModel.dirty = true; ngModel.viewValue = inputElement.checked ? ngTrueValue.readValue(inputElement) : ngFalseValue.readValue(inputElement); @@ -389,6 +390,7 @@ class InputRadioDirective { }; radioButtonElement.onClick.listen((_) { if (radioButtonElement.checked) { + ngModel.dirty = true; scope.$apply(() => ngModel.viewValue = ngValue.readValue(radioButtonElement)); } }); diff --git a/test/directive/ng_model_spec.dart b/test/directive/ng_model_spec.dart index ce1ea6106..25180c097 100644 --- a/test/directive/ng_model_spec.dart +++ b/test/directive/ng_model_spec.dart @@ -458,6 +458,20 @@ describe('ng-model', () { expect(element.checked).toBe(false); })); + it('should render as dirty when checked', inject((Scope scope) { + var element = _.compile('<input type="text" ng-model="my_model" probe="i" />'); + Probe probe = _.rootScope.i; + var model = probe.directive(NgModel); + + expect(model.pristine).toEqual(true); + expect(model.dirty).toEqual(false); + + _.triggerEvent(element, 'change'); + + expect(model.pristine).toEqual(false); + expect(model.dirty).toEqual(true); + })); + it('should update input value from model using ng-true-value/false', inject((Scope scope) { var element = _.compile('<input type="checkbox" ng-model="model" ng-true-value="1" ng-false-value="0">'); @@ -679,6 +693,44 @@ describe('ng-model', () { expect(greenBtn.checked).toBe(true); expect(blueBtn.checked).toBe(false); }); + + it('should render as dirty when checked', inject((Scope scope) { + var element = _.compile( + '<div>' + + ' <input type="radio" id="on" ng-model="my_model" probe="i" value="on" />' + + ' <input type="radio" id="off" ng-model="my_model" probe="j" value="off" />' + + '</div>' + ); + Probe probe = _.rootScope.i; + + var model = probe.directive(NgModel); + + var input1 = element.query("#on"); + var input2 = element.query("#off"); + + expect(model.pristine).toEqual(true); + expect(model.dirty).toEqual(false); + + expect(input1.classes.contains("ng-dirty")).toBe(false); + expect(input2.classes.contains("ng-dirty")).toBe(false); + expect(input1.classes.contains("ng-pristine")).toBe(true); + expect(input1.classes.contains("ng-pristine")).toBe(true); + + input1.checked = true; + _.triggerEvent(input1, 'click'); + + expect(model.pristine).toEqual(false); + expect(model.dirty).toEqual(true); + + input1.checked = false; + input2.checked = true; + _.triggerEvent(input2, 'click'); + + expect(input1.classes.contains("ng-dirty")).toBe(true); + expect(input2.classes.contains("ng-dirty")).toBe(true); + expect(input1.classes.contains("ng-pristine")).toBe(false); + expect(input1.classes.contains("ng-pristine")).toBe(false); + })); }); describe('type="search"', () {