Angular: Attach directive
http://angularjs.org/
HTML
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.3/angular.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
<div ng-controller="MyCtrl">
<div class="col-md-12">
<table class="table table-condensed">
<thead>
<tr>
<th>Name</th>
<th>$valid</th>
<th>$invalid</th>
<th>$dirty</th>
<th>$pristine</th>
<th>$touched</th>
<th>$untouched</th>
<th>Error</th>
</tr>
</thead>d
<tr ng-repeat="field in testForm">
<td>{{field.$name}}</td>
<td ng-class="{'success':field.$valid, 'danger': !field.$valid}">{{field.$valid}}</td>
<td ng-class="{'success':field.$invalid, 'danger': !field.$invalid}">{{field.$invalid}}</td>
<td ng-class="{'success':field.$dirty, 'danger': !field.$dirty}">{{field.$dirty}}</td>
<td ng-class="{'success':field.$pristine, 'danger': !field.$pristine}">{{field.$pristine}}</td>
<td ng-class="{'success':field.$touched, 'danger': !field.$touched}">{{field.$touched}}</td>
<td ng-class="{'success':field.$untouched,'danger': !field.$untouched}">{{field.$untouched}}</td>
<td style="width: 40%;">{{field.$error}}</td>
</tr>
</table>
<button class="btn btn-primary" ng-click="toggleValidate()">Toggle validation</button>
Do Validate: {{doValidate}}
<br /><br />
<form name="testForm" id="testForm">
<input
name="testInput"
type="text"
ng-class="{'error': testForm.testInput.$invalid && testForm.testInput.$dirty }"
ng-model="testInput"
attach-directive="{'validate-test': validateLogic() }"
/>
</form>
</div>
</div>
CSS
.error {
background: red;
}
JavaScript
var myApp = angular.module('myApp',[]);
myApp.directive('attachDirective', function($compile, $timeout) {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, ctrl) {
scope.$watch(attrs.attachDirective, attachWatchAction, true);
function attachWatchAction(newValue) {
angular.forEach(newValue, function (value, key) {
if (value) {
alert(key);
if (!element.attr(key)) {
element.attr(key, true);
$compile(element)(scope);
}
} else {
alert(key);
if (element.attr(key)) {
element.removeAttr(key);
$compile(element)(scope);
}
}
});
}
}
};
});
myApp.directive('validateTest', function() {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, ctrl) {
ctrl.$parsers.unshift(function (value) {
var valid = value === 'test';
ctrl.$setValidity('validateTest', valid);
if(!valid) {
ctrl.$dirty = true;
ctrl.$touched = true;
}
return valid ? value : undefined;
});
ctrl.$formatters.unshift(function (value) {
var valid = value === 'test';
ctrl.$setValidity('validateTest', valid);
if(!valid && value !== '') {
ctrl.$dirty = true;
ctrl.$pristine = false;
ctrl.$touched = true;
...