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

Commit 574065f

Browse files
matskomhevery
authored andcommitted
feat(forms): append valid/invalid CSS classes for each validator on all controls
1 parent 419e918 commit 574065f

File tree

3 files changed

+122
-1
lines changed

3 files changed

+122
-1
lines changed

lib/directive/ng_control.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,18 +170,23 @@ abstract class NgControl implements NgAttachAware, NgDetachAware {
170170
* error is real).
171171
*/
172172
updateControlValidity(NgControl ngModel, String errorType, bool isValid) {
173+
String validClassName = errorType + '-valid';
174+
String invalidClassName = errorType + '-invalid';
175+
173176
if (isValid) {
174177
if (errors.containsKey(errorType)) {
175178
Set errorsByName = errors[errorType];
176179
errorsByName.remove(ngModel);
177180
if (errorsByName.isEmpty) {
178181
errors.remove(errorType);
182+
element..removeClass(invalidClassName)..addClass(validClassName);
179183
}
180184
}
181185
if (errors.isEmpty) {
182186
valid = true;
183187
}
184188
} else {
189+
element..removeClass(validClassName)..addClass(invalidClassName);
185190
errors.putIfAbsent(errorType, () => new Set()).add(ngModel);
186191
invalid = true;
187192
}

test/directive/ng_form_spec.dart

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,53 @@ void main() {
529529
}));
530530
});
531531

532+
describe('validators', () {
533+
it('should display the valid and invalid CSS classes on the element for each validation',
534+
inject((TestBed _, Scope scope) {
535+
536+
var form = _.compile(
537+
'<form name="myForm">' +
538+
' <input type="text" ng-model="myModel" required />' +
539+
'</form>'
540+
);
541+
542+
scope.apply();
543+
544+
expect(form.classes.contains('ng-required-invalid')).toBe(true);
545+
expect(form.classes.contains('ng-required-valid')).toBe(false);
546+
547+
scope.apply(() {
548+
scope.context['myModel'] = 'value';
549+
});
550+
551+
expect(form.classes.contains('ng-required-valid')).toBe(true);
552+
expect(form.classes.contains('ng-required-invalid')).toBe(false);
553+
}));
554+
555+
it('should display the valid and invalid CSS classes on the element for custom validations', () {
556+
module((Module module) {
557+
module.type(MyCustomFormValidator);
558+
});
559+
inject((TestBed _, Scope scope) {
560+
var form = _.compile('<form name="myForm">' +
561+
' <input type="text" ng-model="myModel" custom-form-validation />' +
562+
'</form>');
563+
564+
scope.apply();
565+
566+
expect(form.classes.contains('custom-invalid')).toBe(true);
567+
expect(form.classes.contains('custom-valid')).toBe(false);
568+
569+
scope.apply(() {
570+
scope.context['myModel'] = 'yes';
571+
});
572+
573+
expect(form.classes.contains('custom-valid')).toBe(true);
574+
expect(form.classes.contains('custom-invalid')).toBe(false);
575+
});
576+
});
577+
});
578+
532579
describe('reset()', () {
533580
it('should reset the model value to its original state', inject((TestBed _) {
534581
_.compile('<form name="superForm">' +
@@ -661,3 +708,17 @@ void main() {
661708
});
662709
});
663710
}
711+
712+
@NgDirective(
713+
selector: '[custom-form-validation]')
714+
class MyCustomFormValidator extends NgValidator {
715+
MyCustomFormValidator(NgModel ngModel) {
716+
ngModel.addValidator(this);
717+
}
718+
719+
final String name = 'custom';
720+
721+
bool isValid(name) {
722+
return name != null && name == 'yes';
723+
}
724+
}

test/directive/ng_model_spec.dart

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ void main() {
88
TestBed _;
99

1010
beforeEach(module((Module module) {
11-
module..type(ControllerWithNoLove);
11+
module.type(ControllerWithNoLove);
12+
module.type(MyCustomInputValidator);
1213
}));
1314

1415
beforeEach(inject((TestBed tb) => _ = tb));
@@ -1307,6 +1308,46 @@ void main() {
13071308
expect(model.untouched).toBe(true);
13081309
});
13091310

1311+
describe('validators', () {
1312+
it('should display the valid and invalid CSS classes on the element for each validation',
1313+
inject((TestBed _, Scope scope) {
1314+
1315+
var input = _.compile('<input type="email" ng-model="myModel" />');
1316+
1317+
scope.apply(() {
1318+
scope.context['myModel'] = 'value';
1319+
});
1320+
1321+
expect(input.classes.contains('ng-email-invalid')).toBe(true);
1322+
expect(input.classes.contains('ng-email-valid')).toBe(false);
1323+
1324+
scope.apply(() {
1325+
scope.context['myModel'] = 'value@email.com';
1326+
});
1327+
1328+
expect(input.classes.contains('ng-email-valid')).toBe(true);
1329+
expect(input.classes.contains('ng-email-invalid')).toBe(false);
1330+
}));
1331+
1332+
it('should display the valid and invalid CSS classes on the element for custom validations',
1333+
inject((TestBed _, Scope scope) {
1334+
1335+
var input = _.compile('<input type="text" ng-model="myModel" custom-input-validation />');
1336+
1337+
scope.apply();
1338+
1339+
expect(input.classes.contains('custom-invalid')).toBe(true);
1340+
expect(input.classes.contains('custom-valid')).toBe(false);
1341+
1342+
scope.apply(() {
1343+
scope.context['myModel'] = 'yes';
1344+
});
1345+
1346+
expect(input.classes.contains('custom-valid')).toBe(true);
1347+
expect(input.classes.contains('custom-invalid')).toBe(false);
1348+
}));
1349+
});
1350+
13101351
describe('converters', () {
13111352
it('should parse the model value according to the given parser', inject((Scope scope) {
13121353
_.compile('<input type="text" ng-model="model" probe="i">');
@@ -1439,3 +1480,17 @@ class VowelValueParser implements NgModelConverter {
14391480
return value;
14401481
}
14411482
}
1483+
1484+
@NgDirective(
1485+
selector: '[custom-input-validation]')
1486+
class MyCustomInputValidator extends NgValidator {
1487+
MyCustomInputValidator(NgModel ngModel) {
1488+
ngModel.addValidator(this);
1489+
}
1490+
1491+
final String name = 'custom';
1492+
1493+
bool isValid(name) {
1494+
return name != null && name == 'yes';
1495+
}
1496+
}

0 commit comments

Comments
 (0)