UNPKG

angular-form-validator

Version:

Angular validation directive with validation rules and error messages.

235 lines (179 loc) 10.5 kB
/*global angular*/ // var stringify = require('json-stringify-safe'); /** * On JS event ('keyup', 'change', ...etc) we want to get value from input form field by using ng-model="some.var". * This function resolves multilevel scope object defined in ng-model="some.multilevel.scope.object". * It will resolve up to 5 levels. * @param {Object} scope - angular $scope object * @param {Object} iAttrs - attribute object which contains HTML tag attributes * @return {Mixed} - ng-model value */ var getInputModelValue = function (scope, iAttrs) { 'use strict'; var ngModelArr = iAttrs.ngModel.split('.'); // console.log(JSON.stringify(ngModelArr, null, 2)); var inputModel; switch (ngModelArr.length) { case 1: if (scope[ngModelArr[0]]) inputModel = scope[ngModelArr[0]]; break; case 2: if (scope[ngModelArr[0]] && scope[ngModelArr[0]][ngModelArr[1]]) inputModel = scope[ngModelArr[0]][ngModelArr[1]]; break; case 3: if (scope[ngModelArr[0]] && scope[ngModelArr[0]][ngModelArr[1]] && scope[ngModelArr[0]][ngModelArr[1]][ngModelArr[2]]) inputModel = scope[ngModelArr[0]][ngModelArr[1]][ngModelArr[2]]; break; case 4: if (scope[ngModelArr[0]] && scope[ngModelArr[0]][ngModelArr[1]] && scope[ngModelArr[0]][ngModelArr[1]][ngModelArr[2]] && scope[ngModelArr[0]][ngModelArr[1]][ngModelArr[2]][ngModelArr[3]]) inputModel = scope[ngModelArr[0]][ngModelArr[1]][ngModelArr[2]][ngModelArr[3]]; break; case 5: if (scope[ngModelArr[0]] && scope[ngModelArr[0]][ngModelArr[1]] && scope[ngModelArr[0]][ngModelArr[1]][ngModelArr[2]] && scope[ngModelArr[0]][ngModelArr[1]][ngModelArr[2]][ngModelArr[3]] && scope[ngModelArr[0]][ngModelArr[1]][ngModelArr[2]][ngModelArr[3]][ngModelArr[4]]) inputModel = scope[ngModelArr[0]][ngModelArr[1]][ngModelArr[2]][ngModelArr[3]][ngModelArr[4]]; break; default: inputModel = scope[iAttrs.ngModel]; } return inputModel; }; /** * Takes errMsg and puts it into scope, so we can use it to output error in HTML. * For example {{errMsg.users.first_name}} * @param {Object} scope - angular's $scope object * @param {Object} iAttrs - attribute object which contains HTML tag attributes * @param {String} errMsg - error message defined in ngform-validator="{min: ['Error message ...', 2]}" * @return {undefined} */ var outputErrorMessage = function (scope, iAttrs, errMsg) { 'use strict'; var ngModelArr = iAttrs.ngModel.split('.'); // console.log(JSON.stringify(ngModelArr, null, 2)); if (!scope.errMsg) scope.errMsg = {}; switch (ngModelArr.length) { case 1: scope.errMsg[ngModelArr[0]] = errMsg; break; case 2: if (!scope.errMsg[ngModelArr[0]]) scope.errMsg[ngModelArr[0]] = {}; scope.errMsg[ngModelArr[0]][ngModelArr[1]] = errMsg; break; case 3: if (!scope.errMsg[ngModelArr[0]]) scope.errMsg[ngModelArr[0]] = {}; if (!scope.errMsg[ngModelArr[0]][ngModelArr[1]]) scope.errMsg[ngModelArr[0]][ngModelArr[1]] = {}; scope.errMsg[ngModelArr[0]][ngModelArr[1]][ngModelArr[2]] = errMsg; break; case 4: if (!scope.errMsg[ngModelArr[0]]) scope.errMsg[ngModelArr[0]] = {}; if (!scope.errMsg[ngModelArr[0]][ngModelArr[1]]) scope.errMsg[ngModelArr[0]][ngModelArr[1]] = {}; if (!scope.errMsg[ngModelArr[0]][ngModelArr[1]][ngModelArr[2]]) scope.errMsg[ngModelArr[0]][ngModelArr[1]][ngModelArr[2]] = {}; scope.errMsg[ngModelArr[0]][ngModelArr[1]][ngModelArr[2]][ngModelArr[3]] = errMsg; break; case 5: if (!scope.errMsg[ngModelArr[0]]) scope.errMsg[ngModelArr[0]] = {}; if (!scope.errMsg[ngModelArr[0]][ngModelArr[1]]) scope.errMsg[ngModelArr[0]][ngModelArr[1]] = {}; if (!scope.errMsg[ngModelArr[0]][ngModelArr[1]][ngModelArr[2]]) scope.errMsg[ngModelArr[0]][ngModelArr[1]][ngModelArr[2]] = {}; if (!scope.errMsg[ngModelArr[0]][ngModelArr[1]][ngModelArr[2]][ngModelArr[3]]) scope.errMsg[ngModelArr[0]][ngModelArr[1]][ngModelArr[2]][ngModelArr[3]] = {}; scope.errMsg[ngModelArr[0]][ngModelArr[1]][ngModelArr[2]][ngModelArr[3]][ngModelArr[4]] = errMsg; break; default: scope.errMsg[ngModelArr[0]] = errMsg; } }; module.exports = function ($parse, $timeout, validateFact) { 'use strict'; var directiveObj = { restrict: 'A', replace: false, scope: false, link: function (scope, iElem, iAttrs) { //post-link function // console.log(stringify(iAttrs.ngModel, null, 2)); //GET RULES (from ngform-validator="{...}" which is string) var rulesObj = iAttrs.ngformValidator; rulesObj = $parse(rulesObj)() || {type: 'string'}; //$parse converts string to object // console.log(rulesObj); //GET OPTIONS var options = iAttrs.ngformValidatorOptions || {}; options = $parse(options)() || {validateOn: 'blur'}; //$parse converts string to object //GET CUSTOM VALIDATOR FUNCTION var customFunc; if (iAttrs.ngformValidatorCustom) { customFunc = eval('(' + iAttrs.ngformValidatorCustom + ')'); // console.log(customFunc); } //DEFINE TYPE (string, number, date, boolean, objectId, mixed) //// get type from <input type="number" ... var inputType; if (iAttrs.type) { inputType = iAttrs.type.toLowerCase(); switch (inputType) { case 'text': inputType = 'string'; break; case 'number': inputType = 'number'; break; case 'range': inputType = 'number'; break; case 'date': inputType = 'date'; break; case 'datetime-local': inputType = 'date'; break; default: inputType = 'string'; } } else { inputType = 'string'; } // console.log('INPUT TYPE: ' + inputType); //// final type var type = rulesObj.type || inputType; type = type.toLowerCase(); // console.log('FINAL TYPE: ' + type); /******************************** VALIDATION on secific EVENT *********************************/ var errMsg; //** on any jquery event 'change', 'blur', 'keyup' ... https://api.jquery.com/category/events/) iElem.on(options.validateOn, function () { //GET INPUT MODEL VALUE (if ng-model="age" => iAttrs.model='age') var inputModel = getInputModelValue(scope, iAttrs); $timeout(function () { //validator synch chain (execute one by one) errMsg = validateFact.type[type](inputModel, iElem, scope, iAttrs); //type validator is always first if (!errMsg && rulesObj.hasOwnProperty('email')) errMsg = validateFact.email(inputModel, iElem, rulesObj); if (!errMsg && rulesObj.hasOwnProperty('url')) errMsg = validateFact.url(inputModel, iElem, rulesObj); if (!errMsg && rulesObj.hasOwnProperty('tel')) errMsg = validateFact.tel(inputModel, iElem, rulesObj); if (!errMsg && rulesObj.hasOwnProperty('min')) errMsg = validateFact.min(inputModel, iElem, rulesObj); if (!errMsg && rulesObj.hasOwnProperty('max')) errMsg = validateFact.max(inputModel, iElem, rulesObj); if (!errMsg && rulesObj.hasOwnProperty('between')) errMsg = validateFact.between(inputModel, iElem, rulesObj); if (!errMsg && rulesObj.hasOwnProperty('emptySpaces')) errMsg = validateFact.emptySpaces(inputModel, iElem, scope, iAttrs, rulesObj); if (!errMsg && rulesObj.hasOwnProperty('sameAs')) errMsg = validateFact.sameAs(inputModel, iElem, scope, rulesObj); if (!errMsg && rulesObj.hasOwnProperty('regex')) errMsg = validateFact.regex(inputModel, iElem, rulesObj); if (!errMsg && rulesObj.hasOwnProperty('enum')) errMsg = validateFact.enum(inputModel, iElem, rulesObj); if (!errMsg && rulesObj.hasOwnProperty('price')) errMsg = validateFact.price(inputModel, iElem, scope, iAttrs, rulesObj); if (!errMsg && rulesObj.hasOwnProperty('alpha')) errMsg = validateFact.alpha(inputModel, iElem, rulesObj); if (!errMsg && rulesObj.hasOwnProperty('alphanumeric')) errMsg = validateFact.alphanumeric(inputModel, iElem, rulesObj); if (!errMsg && rulesObj.hasOwnProperty('lowercase')) errMsg = validateFact.lowercase(inputModel, iElem, scope, iAttrs, rulesObj); if (!errMsg && rulesObj.hasOwnProperty('uppercase')) errMsg = validateFact.uppercase(inputModel, iElem, scope, iAttrs, rulesObj); if (!errMsg && rulesObj.hasOwnProperty('ucfirst')) errMsg = validateFact.ucfirst(inputModel, iElem, scope, iAttrs, rulesObj); if (!errMsg && rulesObj.hasOwnProperty('int')) errMsg = validateFact.int(inputModel, iElem, rulesObj); if (!errMsg && rulesObj.hasOwnProperty('float')) errMsg = validateFact.float(inputModel, iElem, rulesObj); if (!errMsg && iAttrs.ngformValidatorCustom) errMsg = validateFact.custom(inputModel, iElem, customFunc); //error message to scope // console.log(errMsg); outputErrorMessage(scope, iAttrs, errMsg); }, 800); }); //** onBlur validators iElem.on('blur', function () { //GET INPUT MODEL VALUE (if ng-model="age" => iAttrs.model='age') var inputModel = getInputModelValue(scope, iAttrs); $timeout(function () { if (!errMsg && rulesObj.hasOwnProperty('required')) errMsg = validateFact.required(inputModel, iElem, rulesObj); //error message to scope outputErrorMessage(scope, iAttrs, errMsg); }, 1300); }); } //link: }; //directiveObj return directiveObj; };