Skip to content

Commit bf1a1f2

Browse files
feat(chapter-10) - add field validation messages
1 parent 2e6c912 commit bf1a1f2

File tree

6 files changed

+25
-23
lines changed

6 files changed

+25
-23
lines changed

1820EN_10_Code/04_field_directive/field-directive.js

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
angular.module('field-directive', ['1820EN_10_Code/04_field_directive/template/text.html', '1820EN_10_Code/04_field_directive/template/number.html'])
22

3-
.directive('field', function($compile, $http, $templateCache) {
3+
.directive('field', function($compile, $http, $templateCache, $interpolate) {
44

55
return {
66
restrict:'E',
@@ -14,7 +14,7 @@ angular.module('field-directive', ['1820EN_10_Code/04_field_directive/template/t
1414
// (we need to replace dots with something to work with browsers and also form scope)
1515
modelId = attrs.ngModel.replace('.', '_').toLowerCase();
1616

17-
// Load up the relevant template
17+
// Load up the template for this kind of field
1818
getFieldElement = $http.get('1820EN_10_Code/04_field_directive/template/' + attrs.type + '.html', {cache:$templateCache}).then(function(response) {
1919
var newElement = angular.element(response.data);
2020
var inputElement = newElement.find('input') || newElement.find('textarea') || newElement.find('select');
@@ -40,34 +40,33 @@ angular.module('field-directive', ['1820EN_10_Code/04_field_directive/template/t
4040
inputElement.attr('id', childScope.id);
4141
newElement.find('label').attr('for', childScope.id);
4242

43-
childScope.$messages = {};
43+
childScope.$validationMessages = {};
4444
var originalElement = transclude(scope);
4545
angular.forEach(originalElement.find('validator'), function(validatorElement) {
4646
validatorElement = angular.element(validatorElement);
47-
childScope.$messages[validatorElement.attr('key')] = validatorElement.text();
48-
var validationAttributes = scope.$eval(validatorElement.attr('attributes'));
49-
angular.forEach(validationAttributes, function(key, value) {
50-
inputElement.attr(key, value);
47+
48+
// We need to watch the message incase it has interpolated values that need processing
49+
scope.$watch($interpolate(validatorElement.text()), function (message) {
50+
childScope.$validationMessages[validatorElement.attr('key')] = message;
5151
});
52-
});
5352

54-
childScope.$watch('$field.$error', function(errors) {
55-
childScope.$messages = [];
56-
angular.forEach(errors, function(key, value) {
57-
if ( value ) {
58-
childScope.$messages.push(childScope.$messages[key]);
59-
}
53+
// Extract the options and bind them to the input element
54+
var validationAttributes = scope.$eval(validatorElement.attr('options'));
55+
angular.forEach(validationAttributes, function(value, key) {
56+
inputElement.attr(key, value);
6057
});
61-
}, true);
58+
});
6259

63-
// We must compile here otherwise the new input won't pick up the FormController
60+
// We must compile in the postLink function rather than the compile function
61+
// otherwise the new input won't pick up the FormController
6462
$compile(newElement)(childScope, function(clone) {
6563
// We can only add the new element after the directive element because
6664
// transclusion caused the directive element to be converted to a template.
6765
// Comments are ignored by ng-repeat, otherwise this would not work
6866
element.after(clone);
6967
});
7068

69+
// Only after the new element has been compiled will we have access to the $field
7170
if ( formController ) {
7271
childScope.$form = formController;
7372
childScope.$field = formController[childScope.name];

1820EN_10_Code/04_field_directive/index.html

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,13 @@
1010
<script src="template/number.html.js"></script>
1111
</head>
1212
<body ng-init="myModel = {}">
13-
<form name="form">
14-
<field ng-model="myModel.myNumber" type="number" label="My Number"></field> {{ myModel.myNumber }}
13+
<form name="form" class="form-inline" ng-init="x = 3" novalidate>
14+
<button ng-click="x=5">X</button>
15+
<field ng-model="myModel.myNumber" type="number" label="My Number">
16+
<validator key="number">Please enter a valid number</validator>
17+
</field> {{ myModel.myNumber }}
1518
<field ng-model="myModel.myText" type="text" label="My Text">
16-
<validator key="required" message="My Text is required" attributes="{required: true}"></validator>
19+
<validator key="required" options="{required: true}">My Text is {{ x }} required</validator>
1720
</field> {{ myModel.myText }}
1821
</form>
1922
</body>

1820EN_10_Code/04_field_directive/template/number.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
<label class="control-label">{{label}}</label>
33
<div class="controls">
44
<input type="number">
5-
<span ng-repeat="message in $messages" class="help-inline">{{message}}</span>
5+
<span ng-repeat="error in $errors" class="help-inline">{{$validationMessages[error]}}</span>
66
</div>
77
</div>

1820EN_10_Code/04_field_directive/template/number.html.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ angular.module("1820EN_10_Code/04_field_directive/template/number.html", []).run
44
" <label class=\"control-label\">{{label}}</label>" +
55
" <div class=\"controls\">" +
66
" <input type=\"number\">" +
7-
" <span ng-repeat=\"message in $messages\" class=\"help-inline\">{{message.text}}</span>" +
7+
" <span ng-repeat=\"error in $errors\" class=\"help-inline\">{{$validationMessages[error]}}</span>" +
88
" </div>" +
99
"</div>");
1010
}]);

1820EN_10_Code/04_field_directive/template/text.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
<label class="control-label">{{label}}</label>
33
<div class="controls">
44
<input type="text">
5-
<span ng-repeat="message in $messages" class="help-inline">{{message}}</span>
5+
<span ng-repeat="(key, error) in $field.$error" ng-show="error && $field.$dirty" class="help-inline">{{$validationMessages[key]}}</span>
66
</div>
77
</div>

1820EN_10_Code/04_field_directive/template/text.html.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ angular.module("1820EN_10_Code/04_field_directive/template/text.html", []).run([
44
" <label class=\"control-label\">{{label}}</label>" +
55
" <div class=\"controls\">" +
66
" <input type=\"text\">" +
7-
" <span ng-repeat=\"message in $messages\" class=\"help-inline\">{{message.text}}</span>" +
7+
" <span ng-repeat=\"(key, error) in $field.$error\" ng-show=\"error && $field.$dirty\" class=\"help-inline\">{{$validationMessages[key]}}</span>" +
88
" </div>" +
99
"</div>");
1010
}]);

0 commit comments

Comments
 (0)