Skip to content

Commit 1a4d237

Browse files
committed
feat(forms): added hasError and getError methods to all controls
1 parent 8923103 commit 1a4d237

File tree

2 files changed

+205
-152
lines changed

2 files changed

+205
-152
lines changed

modules/angular2/src/forms/model.ts

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {StringWrapper, isPresent} from 'angular2/src/facade/lang';
1+
import {StringWrapper, isPresent, isBlank} from 'angular2/src/facade/lang';
22
import {Observable, EventEmitter, ObservableWrapper} from 'angular2/src/facade/async';
33
import {StringMap, StringMapWrapper, ListWrapper, List} from 'angular2/src/facade/collection';
44
import {Validators} from './validators';
@@ -21,6 +21,24 @@ export function isControl(c: Object): boolean {
2121
return c instanceof AbstractControl;
2222
}
2323

24+
function _find(c: AbstractControl, path: List<string | number>| string) {
25+
if (isBlank(path)) return null;
26+
if (!(path instanceof List)) {
27+
path = StringWrapper.split(<string>path, new RegExp("/"));
28+
}
29+
if (ListWrapper.isEmpty(path)) return null;
30+
31+
return ListWrapper.reduce(<List<string | number>>path, (v, name) => {
32+
if (v instanceof ControlGroup) {
33+
return isPresent(v.controls[name]) ? v.controls[name] : null;
34+
} else if (v instanceof ControlArray) {
35+
var index = <number>name;
36+
return isPresent(v.at(index)) ? v.at(index) : null;
37+
} else {
38+
return null;
39+
}
40+
}, c);
41+
}
2442

2543
/**
2644
* Omitting from external API doc as this is really an abstract internal concept.
@@ -31,7 +49,7 @@ export class AbstractControl {
3149
_errors: StringMap<string, any>;
3250
_pristine: boolean;
3351
_touched: boolean;
34-
_parent: any; /* ControlGroup | ControlArray */
52+
_parent: ControlGroup | ControlArray;
3553
validator: Function;
3654

3755
_valueChanges: EventEmitter;
@@ -78,6 +96,7 @@ export class AbstractControl {
7896

7997
this._errors = this.validator(this);
8098
this._status = isPresent(this._errors) ? INVALID : VALID;
99+
81100
if (isPresent(this._parent) && !onlySelf) {
82101
this._parent.updateValidity({onlySelf: onlySelf});
83102
}
@@ -101,6 +120,21 @@ export class AbstractControl {
101120
}
102121
}
103122

123+
find(path: List<string | number>| string): AbstractControl { return _find(this, path); }
124+
125+
getError(errorCode: string, path: List<string> = null) {
126+
var c = this.find(path);
127+
if (isPresent(c) && isPresent(c._errors)) {
128+
return StringMapWrapper.get(c._errors, errorCode);
129+
} else {
130+
return null;
131+
}
132+
}
133+
134+
hasError(errorCode: string, path: List<string> = null) {
135+
return isPresent(this.getError(errorCode, path));
136+
}
137+
104138
_updateValue(): void {}
105139
}
106140

@@ -168,7 +202,10 @@ export class ControlGroup extends AbstractControl {
168202
this.updateValidity({onlySelf: true});
169203
}
170204

171-
addControl(name: string, c: AbstractControl) { this.controls[name] = c; }
205+
addControl(name: string, c: AbstractControl) {
206+
this.controls[name] = c;
207+
c.setParent(this);
208+
}
172209

173210
removeControl(name: string) { StringMapWrapper.delete(this.controls, name); }
174211

@@ -187,18 +224,6 @@ export class ControlGroup extends AbstractControl {
187224
return c && this._included(controlName);
188225
}
189226

190-
find(path: string | List<string>): AbstractControl {
191-
if (!(path instanceof List)) {
192-
path = StringWrapper.split(<string>path, new RegExp("/"));
193-
}
194-
195-
return ListWrapper.reduce(
196-
<List<string>>path, (v, name) => v instanceof ControlGroup && isPresent(v.controls[name]) ?
197-
v.controls[name] :
198-
null,
199-
this);
200-
}
201-
202227
_setParentForControls() {
203228
StringMapWrapper.forEach(this.controls, (control, name) => { control.setParent(this); });
204229
}

0 commit comments

Comments
 (0)