JSFiddle - React, Tailwind, and code Playground
by webvitaly
HTML
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.css">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.js"></script>
<section ng-app="app">
<article ng-controller="appCtrl" class="container">
<form class="form-horizontal well" name="form" novalidate>
<div class="form-group">
<label class="col-sm-6 control-label">Number - should be greater than MinNumber; positive integer; min="200"; max="500";</label>
<div class="col-sm-6">
<input type="number" min="200" max="500" ng-model="number" name="number" class="form-control" min-model="minnumber" min-model-name="Min Number" positive-integer validate required />
<div class="form-errors"></div>
</div>{{ form.number.$error }}</div>
<div class="form-group">
<label class="col-sm-6 control-label">MinNumber; positive float;</label>
<div class="col-sm-6">
<input type="number" ng-model="minnumber" name="minnumber" class="form-control" positive-float validate required />
<div class="form-errors"></div>
</div>{{ form.minnumber.$error }}</div>
<div class="form-group">
<label class="col-sm-6 control-label">Email - minlength="5"; maxlength="15";</label>
<div class="col-sm-6">
<input type="email" ng-minlength="5" ng-maxlength="15" ng-model="email" name="email" class="form-control" validate required />
<form-errors></form-errors>
</div>{{ form.email.$error }}</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-6">
<button ng-click="submit()" ng-disabled="form.$invalid" class="btn btn-primary">submit</button>
</div>
</div>
</form>
</article>
</section>
CSS
input.ng-invalid.ng-dirty {
border-color: red;
color: red;
}
input.ng-valid.ng-dirty {
border-color: green;
color: green;
}
JavaScript
var app = angular.module('app', []);
app.controller('appCtrl', function ($scope) {
});
app.directive('validate', function () {
return {
restrict: 'A',
require: 'ngModel', // require: '^form',
link: function (scope, element, attrs, ctrl) {
console.log('======================');
console.log(scope);
console.log(element);
console.log(attrs);
console.log(ctrl);
console.log(scope.form.$error);
angular.forEach(scope.form.$error, function (value, key) {
console.log('scope.form.$error = ' + key + ': ' + value);
console.log(value);
});
}
};
});
app.directive('positiveInteger', function () {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, ctrl) {
ctrl.$parsers.unshift(function (viewValue) {
var INTEGER_REGEXP = /^\d+$/;
if (INTEGER_REGEXP.test(viewValue)) { // it is valid
ctrl.$setValidity('positiveInteger', true);
return viewValue;
} else { // it is invalid, return undefined (no model update)
ctrl.$setValidity('positiveInteger', false);
return undefined;
}
});
}
};
});
app.directive('positiveFloat', function () {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, ctrl) {
ctrl.$parsers.unshift(function (viewValue) {
var FLOAT_REGEXP = /^(?:[1-9]\d*|0)?(?:\.\d+)?$/;
if (FLOAT_REGEXP.test(viewValue)) { // it is valid
ctrl.$setValidity('positiveInteger', true);
return viewValue;
} else { // it is invalid, return undefined (no model update)
ctrl.$setValidity('positiveInteger', false);
...