Skip to content
This repository was archived by the owner on Feb 22, 2018. It is now read-only.

Commit 0064ef5

Browse files
vicbchirayuk
authored andcommitted
feat(form): Add support for input[type=color]
Closes #611 Closes #1080
1 parent ddd9e41 commit 0064ef5

8 files changed

+105
-5
lines changed

example/web/hello_world.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'package:angular/application_factory.dart';
66
publishAs: 'ctrl')
77
class HelloWorld {
88
String name = "world";
9+
String color = "#aaaaaa";
910
}
1011

1112
main() {

example/web/hello_world.html

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
</head>
66
<body hello-world-controller>
77

8-
<h3>Hello {{ctrl.name}}!</h3>
9-
name: <input type="text" ng-model="ctrl.name" ng-model-options="{ debounce: {'default': 500, 'blur': 0} }">
8+
<h3 ng-style="{color:ctrl.color}">Hello {{ctrl.name}}!</h3>
9+
Name: <input type="text" ng-model="ctrl.name" ng-model-options="{ debounce: {'default': 500, 'blur': 0} }" />
10+
Color: <input type="color" ng-model="ctrl.color"/>
1011

1112
<script type="application/dart" src="hello_world.dart"></script>
1213
<script src="packages/browser/dart.js"></script>

lib/directive/module.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,5 +120,6 @@ class DirectiveModule extends Module {
120120
bind(NgModelPatternValidator, toValue: null);
121121
bind(NgModelMinLengthValidator, toValue: null);
122122
bind(NgModelMaxLengthValidator, toValue: null);
123+
bind(NgModelColorValidator, toValue: null);
123124
}
124125
}

lib/directive/ng_model.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ class InputCheckbox {
337337
*
338338
* **Usage**
339339
*
340-
* <input type="text|url|password|email|search|tel" ng-model="myModel">
340+
* <input type="text|url|password|email|search|tel|color" ng-model="myModel">
341341
* <textarea ng-model="myModel"></textarea>
342342
*
343343
* When the `ng-model` attribute is present on the input element,
@@ -353,6 +353,7 @@ class InputCheckbox {
353353
@Decorator(selector: 'input[type=email][ng-model]')
354354
@Decorator(selector: 'input[type=search][ng-model]')
355355
@Decorator(selector: 'input[type=tel][ng-model]')
356+
@Decorator(selector: 'input[type=color][ng-model]')
356357
class InputTextLike {
357358
final dom.Element inputElement;
358359
final NgModel ngModel;
@@ -709,7 +710,7 @@ class NgValue {
709710

710711
@NgOneWay('ng-value')
711712
void set value(val) {
712-
this._value = val;
713+
_value = val;
713714
}
714715
dynamic get value => _value == null ? (element as dynamic).value : _value;
715716
}

lib/directive/ng_model_validators.dart

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,22 @@ class NgModelUrlValidator implements NgValidator {
6868
modelValue == null || modelValue.isEmpty || URL_REGEXP.hasMatch(modelValue);
6969
}
7070

71+
/**
72+
* Validates the model to see if its contents match a valid color pattern.
73+
*/
74+
@Decorator(selector: 'input[type=color][ng-model]')
75+
class NgModelColorValidator implements NgValidator {
76+
static final COLOR_REGEXP = new RegExp(r'^#[0-9a-f]{6}$', caseSensitive: false);
77+
final String name = 'ng-color';
78+
79+
NgModelColorValidator(NgModel ngModel) {
80+
ngModel.addValidator(this);
81+
}
82+
83+
bool isValid(modelValue) =>
84+
modelValue == null || modelValue.isEmpty || COLOR_REGEXP.hasMatch(modelValue);
85+
}
86+
7187
/**
7288
* Validates the model to see if its contents match a valid email pattern.
7389
*/

test/angular_spec.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ main() {
188188
"angular.directive.NgInclude",
189189
"angular.directive.NgModel",
190190
"angular.directive.NgModelOptions",
191+
"angular.directive.NgModelColorValidator",
191192
"angular.directive.NgModelConverter",
192193
"angular.directive.NgModelEmailValidator",
193194
"angular.directive.NgModelMaxLengthValidator",

test/directive/ng_model_spec.dart

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,6 +1105,60 @@ void main() {
11051105
});
11061106
});
11071107

1108+
describe('type="color"', () {
1109+
it('should update input value from model', () {
1110+
_.compile('<input type="color" ng-model="model">');
1111+
_.rootScope.apply();
1112+
1113+
expect((_.rootElement as dom.InputElement).value).toEqual('#000000');
1114+
1115+
_.rootScope.apply('model = "#123456"');
1116+
expect((_.rootElement as dom.InputElement).value).toEqual('#123456');
1117+
});
1118+
1119+
it('should render as #000000 on default and when a null value is present', () {
1120+
_.compile('<input type="color" ng-model="model">');
1121+
_.rootScope.apply();
1122+
1123+
expect((_.rootElement as dom.InputElement).value).toEqual('#000000');
1124+
1125+
_.rootScope.apply('model = null');
1126+
expect((_.rootElement as dom.InputElement).value).toEqual('#000000');
1127+
});
1128+
1129+
it('should update model from the input value', () {
1130+
_.compile('<input type="color" ng-model="model" probe="p">');
1131+
Probe probe = _.rootScope.context['p'];
1132+
var ngModel = probe.directive(NgModel);
1133+
InputElement inputElement = probe.element;
1134+
1135+
inputElement.value = '#000000';
1136+
_.triggerEvent(inputElement, 'change');
1137+
expect(_.rootScope.context['model']).toEqual('#000000');
1138+
1139+
inputElement.value = '#ffffff';
1140+
var input = probe.directive(InputTextLike);
1141+
input.processValue();
1142+
expect(_.rootScope.context['model']).toEqual('#ffffff');
1143+
});
1144+
1145+
it('should only render the input value upon the next digest', (Scope scope) {
1146+
_.compile('<input type="color" ng-model="model" probe="p">');
1147+
Probe probe = _.rootScope.context['p'];
1148+
var ngModel = probe.directive(NgModel);
1149+
InputElement inputElement = probe.element;
1150+
1151+
ngModel.render('#aabbcc');
1152+
scope.context['model'] = '#aabbcc';
1153+
1154+
expect(inputElement.value).not.toEqual('#aabbcc');
1155+
1156+
scope.apply();
1157+
1158+
expect(inputElement.value).toEqual('#aabbcc');
1159+
});
1160+
});
1161+
11081162
describe('contenteditable', () {
11091163
it('should update content from model', () {
11101164
_.compile('<p contenteditable ng-model="model">');

test/directive/ng_model_validators_spec.dart

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,31 @@ void main() {
111111
});
112112
});
113113

114+
describe('[type="color"]', () {
115+
it('should validate the input field given a valid or invalid color', (RootScope scope) {
116+
_.compile('<input type="color" ng-model="val" probe="i" />');
117+
Probe probe = _.rootScope.context['i'];
118+
var model = probe.directive(NgModel);
119+
120+
expect(model.valid).toEqual(true);
121+
expect(model.invalid).toEqual(false);
122+
123+
_.rootScope.apply(() {
124+
_.rootScope.context['val'] = 'red';
125+
});
126+
127+
expect(model.valid).toEqual(false);
128+
expect(model.invalid).toEqual(true);
129+
130+
_.rootScope.apply(() {
131+
_.rootScope.context['val'] = '#ff0000';
132+
});
133+
134+
expect(model.valid).toEqual(true);
135+
expect(model.invalid).toEqual(false);
136+
});
137+
});
138+
114139
describe('[type="email"]', () {
115140
it('should validate the input field given a valid or invalid email address', (RootScope scope) {
116141
_.compile('<input type="email" ng-model="val" probe="i" />');
@@ -627,6 +652,6 @@ void main() {
627652

628653
expect(model.valid).toBe(true);
629654
});
630-
});
655+
});
631656
});
632657
}

0 commit comments

Comments
 (0)