├── .gitignore ├── bower.json ├── angular-validation-schema.min.js ├── examples └── index.html ├── readme.md └── angular-validation-schema.js /.gitignore: -------------------------------------------------------------------------------- 1 | bower_components -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-validation-schema", 3 | "main": "angular-validation-schema.js", 4 | "version": "0.0.1", 5 | "homepage": "https://github.com/thetutlage/angular-validation-schema", 6 | "authors": [ 7 | "Harminder Virk " 8 | ], 9 | "description": "Schema based validation provider for https://github.com/huei90/angular-validation", 10 | "keywords": [ 11 | "angular", 12 | "angularjs", 13 | "validations", 14 | "validator", 15 | "angular-validation" 16 | ], 17 | "license": "MIT", 18 | "ignore": [ 19 | "**/.*", 20 | "node_modules", 21 | "bower_components", 22 | "test", 23 | "tests" 24 | ] 25 | } -------------------------------------------------------------------------------- /angular-validation-schema.min.js: -------------------------------------------------------------------------------- 1 | (function(){var e=angular.module("validation.schema",[]).provider("validationSchema",function(){var e={};this.set=function(t,n){e[t]=n};this.get=function(t){return e[t]};this.$get=function(){return{set:this.set,get:this.get}}}).directive("validationSchema",["validationSchema",function(e){return{restrict:"AE",compile:function(t,n){function s(e){var t=e+" Schema not found";console.warn("VALIDATION SCHEMA :",t)}function o(e){function n(e){angular.forEach(arguments,function(t){if(t!==e){angular.forEach(t,function(t,r){if(e[r]&&e[r].constructor&&e[r].constructor===Object){n(e[r],t)}else{e[r]=e[r]||t}})}});return e}var i=t[0].querySelectorAll("input,select,textarea");angular.forEach(i,function(t){var i=angular.element(t);var s=i.attr("name");if(e[s]){var o=n(e[s],r);i.attr("validator",o.validations);i.attr("valid-method",o["validate-on"]);angular.forEach(o.messages,function(e,t){i.attr(t+"-error-message",e.error||"");i.attr(t+"-success-message",e.success||"")})}})}var r={validations:"required",messages:{required:{error:"Required",success:"Good Required"}},"validate-on":"watch"};var i=e.get(n.schema);if(i){o(i)}else{s(n.schema)}}}}])}).call(this); -------------------------------------------------------------------------------- /examples/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 |
10 |
11 | 12 |
13 |
14 | 15 |
16 |
17 | 18 |
19 |
20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 | 57 | 58 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | 2 | ## Schema based Angular JS Validation 3 | 4 | [angular-validation](https://github.com/huei90/angular-validation) is damn neat in terms 5 | of validating your forms. I personally hate making my html too much declarative especially 6 | for long forms. 7 | 8 | Schema validator is a provider on top of [angular-validation](https://github.com/huei90/angular-validation) letting you control from forms using schema. 9 | 10 | ## Example 11 | 12 | ```javascript 13 | // Angular validation 14 | var app = angular.module('yourApp', ['validation', 'validation.rule']); 15 | 16 | // Now injecting valiation.schema 17 | var app = angular.module('yourApp', ['validation', 'validation.rule','validation.schema']); 18 | ``` 19 | 20 | ### Your Schema 21 | 22 | ```javascript 23 | 24 | // Defining schema 25 | var Author = { 26 | firstname: { 27 | 'validations': 'required', 28 | 'validate-on': 'submit', 29 | 'messages':{ 30 | 'required': { 31 | 'error':'We need it', 32 | 'success': 'All good' 33 | } 34 | } 35 | }, 36 | url:{ 37 | 'validations': 'required,url', 38 | 'validate-on': 'submit', 39 | 'messages':{ 40 | 'required': { 41 | 'error':'We need it', 42 | 'success': 'All good' 43 | }, 44 | 'url':{ 45 | 'error':'It must be a url' 46 | } 47 | } 48 | } 49 | }; 50 | 51 | app.config(function(validationSchemaProvider){ 52 | validationSchemaProvider.set("Author",Author); 53 | }); 54 | 55 | ``` 56 | 57 | ### Your html 58 | 59 | ```html 60 |
61 |
62 |
63 | 64 | 65 |
66 |
67 | 68 | 69 |
70 | 71 | 72 |
73 |
74 | 75 | ``` 76 | 77 | ## Global Validations 78 | 79 | At times we have similar validations on most of the fields and it is very frustating to add same validations on all the fields. 80 | 81 | Using globals inside your schema you can add global rules on all mentioned fields. 82 | 83 | ``` 84 | 85 | var Author = { 86 | globals: { 87 | 'validations': 'required', 88 | 'validate-on': 'submit', 89 | 'messages':{ 90 | 'required': { 91 | 'error':'We need it', 92 | 'success': 'All good' 93 | } 94 | } 95 | }, 96 | firstname: { 97 | }, 98 | url:{ 99 | 'validations': 'required,url' 100 | } 101 | }; 102 | 103 | ``` 104 | 105 | You see how much we have cut down by using globals, as they apply rules globally on all fields. 106 | 107 | ## Tiny Templating 108 | 109 | We all like personalized error messages, and using globals it will be difficult to show personalized 110 | messages. So by using this tiny helper `%field%` you can print field name. 111 | 112 | So `%field% is required on firstname` with turn out to be `firstname is required`. 113 | 114 | 115 | ## Plunker 116 | 117 | [Live Demo](http://plnkr.co/edit/X56HEsDYgYoY8gbSj7cu?p=preview) 118 | 119 | ## That's All 120 | 121 | That is all you need , rest of the stuff will work as specified in angular-valiation docs , it is just a provider to remove validations from html to schema. 122 | -------------------------------------------------------------------------------- /angular-validation-schema.js: -------------------------------------------------------------------------------- 1 | /* 2 | *************************************** 3 | SCHEMA VALIDATOR 4 | *************************************** 5 | Schema validator for angular-valiation, good 6 | if you want to keep your backend validation rules 7 | in sync or your hate making your html too declarative. 8 | 9 | @author - Harminder Virk 10 | @github - https://github.com/thetutlage/angular-validation-schema 11 | */ 12 | 13 | (function() { 14 | var app = angular.module('validation.schema',[]) 15 | 16 | // Tiny provider to save and fetch schemas 17 | .provider('validationSchema',function(){ 18 | 19 | // List of schemas are stored here 20 | var schemas = {}; 21 | 22 | // Adding schema to object 23 | this.set = function(name,hash){ 24 | schemas[name] = hash; 25 | }; 26 | 27 | // fetching from object 28 | this.get = function(name){ 29 | return schemas[name]; 30 | } 31 | 32 | // Exposing them here 33 | this.$get = function(){ 34 | return{ 35 | set: this.set, 36 | get: this.get 37 | } 38 | } 39 | }) 40 | 41 | // Required directive 42 | .directive('validationSchema',['validationSchema',function(validationSchema){ 43 | return{ 44 | restrict: 'AE', 45 | compile: function(tElem, tAttrs){ 46 | // Default schema to extend upon 47 | var defaultSchema = { 48 | // default validation is set to required 49 | 'validations':'required', 50 | 'validate-on':'watch' 51 | }; 52 | 53 | var globalMessages = {}; 54 | 55 | // Grabbing schema the user wants 56 | var schema = validationSchema.get(tAttrs.schema); 57 | 58 | if(schema){ 59 | 60 | // If it is an valid schema , then setFixtures 61 | setFixtures(schema); 62 | 63 | }else{ 64 | 65 | // Otherwise show warning of non-existing schema 66 | warnDeveloper(tAttrs.schema); 67 | } 68 | 69 | // Warn developer method 70 | function warnDeveloper(schema){ 71 | 72 | // Error message 73 | var error_message = schema + ' Schema not found'; 74 | 75 | // Outputting to console 76 | console.warn('VALIDATION SCHEMA :',error_message); 77 | } 78 | 79 | function setFixtures(schema){ 80 | 81 | // If schema has globals 82 | if(schema.globals){ 83 | 84 | // Remove defaultSchema validations with globals 85 | defaultSchema.validations = schema.globals.validations || defaultSchema.validations; 86 | 87 | // Remove validate-on validations with globals 88 | defaultSchema["validate-on"] = schema.globals["validate-on"] || defaultSchema["validate-on"]; 89 | 90 | // Set globalMessages if globals have one or empty object 91 | globalMessages = schema.globals.messages || {}; 92 | 93 | // Delete schema globals as not required anymore 94 | delete schema.globals; 95 | } 96 | 97 | // Deep extending objects 98 | function extendDeep(dst) { 99 | 100 | // Looping through all the values 101 | angular.forEach(arguments, function(obj) { 102 | if (obj !== dst) { 103 | angular.forEach(obj, function(value, key) { 104 | if (dst[key] && dst[key].constructor && dst[key].constructor === Object) { 105 | 106 | // Rerun if above key is an Object 107 | 108 | extendDeep(dst[key], value); 109 | 110 | } else { 111 | 112 | // Extend here 113 | 114 | dst[key] = dst[key] || value; 115 | } 116 | }); 117 | } 118 | }); 119 | return dst; 120 | } 121 | 122 | // schema.firstname = extendDeep(schema.firstname,defaultSchema); 123 | 124 | // Grabbing all form elements inside the tElem 125 | var formElements = tElem[0].querySelectorAll('input,select,textarea'); 126 | 127 | // Looping through all form Elements 128 | angular.forEach(formElements,function(input){ 129 | 130 | // Getting instance of angular element 131 | var i = angular.element(input); 132 | 133 | // Grabbing name 134 | // @description - Name is required to match keys on schema 135 | // @example - firstname key on schema will be matched with firstname as form 136 | // element name 137 | 138 | var input_name = i.attr('name'); 139 | 140 | // If schema defination exists 141 | if(schema[input_name]){ 142 | 143 | // Deep extend rules to save undefined stuff 144 | var i_schema = extendDeep(schema[input_name],defaultSchema); 145 | 146 | // Setting validator on field 147 | i.attr('validator',i_schema.validations); 148 | 149 | // Setting valid-method on field 150 | i.attr('valid-method',i_schema['validate-on']); 151 | 152 | // Extends messages using global and field values 153 | i_schema.messages = i_schema.messages || {}; 154 | i_schema.messages = extendDeep(i_schema.messages,globalMessages); 155 | 156 | // Looping through messages object 157 | angular.forEach(i_schema.messages,function(vals,key){ 158 | 159 | // Grabbing error message and replace %field% with input name 160 | var error_message = vals.error ? vals.error.replace('%field%',input_name) : ''; 161 | 162 | // Grabbing success message and replace %field% with input name 163 | var success_message = vals.success ? vals.success.replace('%field%',input_name) : ''; 164 | 165 | // Setting error message for validation type 166 | i.attr(key+'-error-message',error_message); 167 | 168 | // Setting success message for validation type 169 | i.attr(key+'-success-message',success_message); 170 | 171 | }); 172 | } 173 | 174 | }); 175 | } 176 | } 177 | } 178 | }]); 179 | }).call(this); --------------------------------------------------------------------------------