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

Commit

Permalink
feat(form): Add support for input[type=color]
Browse files Browse the repository at this point in the history
Closes #611

Closes #1080
  • Loading branch information
vicb authored and chirayuk committed Jul 29, 2014
1 parent 67060b2 commit b35a264
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 5 deletions.
1 change: 1 addition & 0 deletions example/web/hello_world.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:angular/application_factory.dart';
publishAs: 'ctrl')
class HelloWorld {
String name = "world";
String color = "#aaaaaa";
}

main() {
Expand Down
5 changes: 3 additions & 2 deletions example/web/hello_world.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
</head>
<body hello-world-controller>

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

<script type="application/dart" src="hello_world.dart"></script>
<script src="packages/browser/dart.js"></script>
Expand Down
1 change: 1 addition & 0 deletions lib/directive/module.dart
Original file line number Diff line number Diff line change
Expand Up @@ -121,5 +121,6 @@ class DirectiveModule extends Module {
bind(NgModelPatternValidator, toValue: null);
bind(NgModelMinLengthValidator, toValue: null);
bind(NgModelMaxLengthValidator, toValue: null);
bind(NgModelColorValidator, toValue: null);
}
}
5 changes: 3 additions & 2 deletions lib/directive/ng_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ class InputCheckbox {
*
* **Usage**
*
* <input type="text|url|password|email|search|tel" ng-model="myModel">
* <input type="text|url|password|email|search|tel|color" ng-model="myModel">
* <textarea ng-model="myModel"></textarea>
*
* When the `ng-model` attribute is present on the input element,
Expand All @@ -348,6 +348,7 @@ class InputCheckbox {
@Decorator(selector: 'input[type=email][ng-model]')
@Decorator(selector: 'input[type=search][ng-model]')
@Decorator(selector: 'input[type=tel][ng-model]')
@Decorator(selector: 'input[type=color][ng-model]')
class InputTextLike {
final dom.Element inputElement;
final NgModel ngModel;
Expand Down Expand Up @@ -707,7 +708,7 @@ class NgValue {

@NgOneWay('ng-value')
void set value(val) {
this._value = val;
_value = val;
}
dynamic get value => _value == null ? (element as dynamic).value : _value;
}
Expand Down
16 changes: 16 additions & 0 deletions lib/directive/ng_model_validators.dart
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,22 @@ class NgModelUrlValidator implements NgValidator {
modelValue == null || modelValue.isEmpty || URL_REGEXP.hasMatch(modelValue);
}

/**
* Validates the model to see if its contents match a valid color pattern.
*/
@Decorator(selector: 'input[type=color][ng-model]')
class NgModelColorValidator implements NgValidator {
static final COLOR_REGEXP = new RegExp(r'^#[0-9a-f]{6}$', caseSensitive: false);
final String name = 'ng-color';

NgModelColorValidator(NgModel ngModel) {
ngModel.addValidator(this);
}

bool isValid(modelValue) =>
modelValue == null || modelValue.isEmpty || COLOR_REGEXP.hasMatch(modelValue);
}

/**
* Validates the model to see if its contents match a valid email pattern.
*/
Expand Down
1 change: 1 addition & 0 deletions test/angular_spec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ main() {
"angular.directive.NgInclude",
"angular.directive.NgModel",
"angular.directive.NgModelOptions",
"angular.directive.NgModelColorValidator",
"angular.directive.NgModelConverter",
"angular.directive.NgModelEmailValidator",
"angular.directive.NgModelMaxLengthValidator",
Expand Down
54 changes: 54 additions & 0 deletions test/directive/ng_model_spec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1105,6 +1105,60 @@ void main() {
});
});

describe('type="color"', () {
it('should update input value from model', () {
_.compile('<input type="color" ng-model="model">');
_.rootScope.apply();

expect((_.rootElement as dom.InputElement).value).toEqual('#000000');

_.rootScope.apply('model = "#123456"');
expect((_.rootElement as dom.InputElement).value).toEqual('#123456');
});

it('should render as #000000 on default and when a null value is present', () {
_.compile('<input type="color" ng-model="model">');
_.rootScope.apply();

expect((_.rootElement as dom.InputElement).value).toEqual('#000000');

_.rootScope.apply('model = null');
expect((_.rootElement as dom.InputElement).value).toEqual('#000000');
});

it('should update model from the input value', () {
_.compile('<input type="color" ng-model="model" probe="p">');
Probe probe = _.rootScope.context['p'];
var ngModel = probe.directive(NgModel);
InputElement inputElement = probe.element;

inputElement.value = '#000000';
_.triggerEvent(inputElement, 'change');
expect(_.rootScope.context['model']).toEqual('#000000');

inputElement.value = '#ffffff';
var input = probe.directive(InputTextLike);
input.processValue();
expect(_.rootScope.context['model']).toEqual('#ffffff');
});

it('should only render the input value upon the next digest', (Scope scope) {
_.compile('<input type="color" ng-model="model" probe="p">');
Probe probe = _.rootScope.context['p'];
var ngModel = probe.directive(NgModel);
InputElement inputElement = probe.element;

ngModel.render('#aabbcc');
scope.context['model'] = '#aabbcc';

expect(inputElement.value).not.toEqual('#aabbcc');

scope.apply();

expect(inputElement.value).toEqual('#aabbcc');
});
});

describe('contenteditable', () {
it('should update content from model', () {
_.compile('<p contenteditable ng-model="model">');
Expand Down
27 changes: 26 additions & 1 deletion test/directive/ng_model_validators_spec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,31 @@ void main() {
});
});

describe('[type="color"]', () {
it('should validate the input field given a valid or invalid color', (RootScope scope) {
_.compile('<input type="color" ng-model="val" probe="i" />');
Probe probe = _.rootScope.context['i'];
var model = probe.directive(NgModel);

expect(model.valid).toEqual(true);
expect(model.invalid).toEqual(false);

_.rootScope.apply(() {
_.rootScope.context['val'] = 'red';
});

expect(model.valid).toEqual(false);
expect(model.invalid).toEqual(true);

_.rootScope.apply(() {
_.rootScope.context['val'] = '#ff0000';
});

expect(model.valid).toEqual(true);
expect(model.invalid).toEqual(false);
});
});

describe('[type="email"]', () {
it('should validate the input field given a valid or invalid email address', (RootScope scope) {
_.compile('<input type="email" ng-model="val" probe="i" />');
Expand Down Expand Up @@ -627,6 +652,6 @@ void main() {

expect(model.valid).toBe(true);
});
});
});
});
}

0 comments on commit b35a264

Please sign in to comment.