Skip to content

Commit

Permalink
allow to add error keys via helper.setOptions
Browse files Browse the repository at this point in the history
  • Loading branch information
pkalkman committed Feb 24, 2015
1 parent bf8e58b commit 3dc2cf9
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 98 deletions.
209 changes: 111 additions & 98 deletions src/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,112 +4,125 @@
(function () {
'use strict';
angular.module('gg.vmsgs')
.factory('ValidationMessagesHelper', function ($compile) {
.factory('ValidationMessagesHelper', function ($compile) {

var defaultOptions = {
hideClassName: 'ng-hide',
messageClassName: 'validation-message',
messageTemplate: '<span><msg></msg></span>',
showTrigger: 'blur',
hideTrigger: 'valid',
dummy: false,
var defaultErrorKeys = ['required', 'email', 'url', 'minlength', 'maxlength', 'pattern', 'min', 'max'];

//for overriding error messages
errorMessages: {},
var defaultOptions = {
hideClassName: 'ng-hide',
messageClassName: 'validation-message',
messageTemplate: '<span><msg></msg></span>',
showTrigger: 'blur',
hideTrigger: 'valid',
dummy: false,

//to support boostrap styling
parentContainerClassName: 'form-group',
parentErrorClassName: 'has-error'
};
//for overriding error messages
errorMessages: {},

return {
setOptions: function (opts) {
defaultOptions = angular.extend({}, defaultOptions, opts || {});
},
getOptions: function (opts, formOpts) {
return angular.extend({}, defaultOptions, formOpts || {}, opts || {});
},
showTriggers: ['blur', 'submit', 'keydown'],
hideTriggers: ['valid', 'keydown'],
//to support boostrap styling
parentContainerClassName: 'form-group',
parentErrorClassName: 'has-error'
};

//these also define the order of rendering
errorKeys: ['required', 'email', 'url', 'minlength', 'maxlength', 'pattern', 'min', 'max'],
errorMessages: {
required: {
default: 'This field is required',
email: 'A valid e-mail address is required',
number: 'A valid number is required',
date: 'A valid date is required',
week: 'A valid week is required',
url: 'A valid url is required',
month: 'A valid month is required'
},
url: 'A valid url is required',
email: 'A valid e-mail address is required',
minlength: 'This field must be at least {minlength} chars',
maxlength: 'This field must be less than {maxlength} chars',
min: {
default: 'This field must be higher than {min}',
number: 'This number must be higher than {min}',
date: 'This date must be after {min}',
week: 'This week must be after {min}',
month: 'This month must be after {min}'
return {
setOptions: function (opts) {
defaultOptions = angular.extend({}, defaultOptions, opts || {});
if (opts) {
angular.forEach(opts, function (value, key) {
if (key.toUpperCase() === 'ERRORMESSAGES') {
angular.forEach(opts[key], function (eValue, eKey) {
if (defaultErrorKeys.indexOf(eKey) === -1) {
defaultErrorKeys.push(eKey);
}
});
}
});
}
},
max: {
default: 'This field must be lower than {max}',
number: 'This number must be lower than {max}',
date: 'This date must be before {max}',
week: 'This week must be before {max}',
month: 'This month must be before {max}'
getOptions: function (opts, formOpts) {
return angular.extend({}, defaultOptions, formOpts || {}, opts || {});
},
pattern: 'This field must match a specific pattern {pattern}'
},
renderError: function (msg) {
var args;
args = arguments;
if (args.length === 2 && args[1] !== null && typeof args[1] === 'object') {
args = args[1];
}
return msg.replace(/{([^}]*)}/g, function (match, key) {
return (typeof args[key] !== 'undefined' ? args[key] : match);
});
},
_getErrorMessage: function (errorKey, inputType, params, opts) {
var errorMessageFromOpts = opts && opts.errorMessages && opts.errorMessages[errorKey];
var errorMessageObject = errorMessageFromOpts || this.errorMessages[errorKey];
showTriggers: ['blur', 'submit', 'keydown'],
hideTriggers: ['valid', 'keydown'],

if (errorMessageObject) {
return this.renderError(errorMessageObject[inputType] || errorMessageObject.default || errorMessageObject, params);
} else {
throw 'Error message not supported for type ' + errorKey + ' and inputType ' + inputType;
}
},
getRenderParameters: function (elem) {
var params = {};
['minlength', 'maxlength', 'min', 'max', 'pattern'].forEach(function (attr) {
var calculatedAttr = elem.attr(attr) || elem.attr('ng-' + attr);
if (calculatedAttr) {
params[attr] = calculatedAttr;
//these also define the order of rendering
errorKeys: defaultErrorKeys,
errorMessages: {
required: {
default: 'This field is required',
email: 'A valid e-mail address is required',
number: 'A valid number is required',
date: 'A valid date is required',
week: 'A valid week is required',
url: 'A valid url is required',
month: 'A valid month is required'
},
url: 'A valid url is required',
email: 'A valid e-mail address is required',
minlength: 'This field must be at least {minlength} chars',
maxlength: 'This field must be less than {maxlength} chars',
min: {
default: 'This field must be higher than {min}',
number: 'This number must be higher than {min}',
date: 'This date must be after {min}',
week: 'This week must be after {min}',
month: 'This month must be after {min}'
},
max: {
default: 'This field must be lower than {max}',
number: 'This number must be lower than {max}',
date: 'This date must be before {max}',
week: 'This week must be before {max}',
month: 'This month must be before {max}'
},
pattern: 'This field must match a specific pattern {pattern}'
},
renderError: function (msg) {
var args;
args = arguments;
if (args.length === 2 && args[1] !== null && typeof args[1] === 'object') {
args = args[1];
}
});
return params;
},
getErrorMessage: function ($error, elem, opts) {
var inputType = elem.attr('type');
var selectedError = '';
var renderParameters = this.getRenderParameters(elem);
this.errorKeys.forEach(function (errorKey) {
if (!selectedError && $error[errorKey]) {
selectedError = errorKey;
return msg.replace(/{([^}]*)}/g, function (match, key) {
return (typeof args[key] !== 'undefined' ? args[key] : match);
});
},
_getErrorMessage: function (errorKey, inputType, params, opts) {
var errorMessageFromOpts = opts && opts.errorMessages && opts.errorMessages[errorKey];
var errorMessageObject = errorMessageFromOpts || this.errorMessages[errorKey];

if (errorMessageObject) {
return this.renderError(errorMessageObject[inputType] || errorMessageObject.default || errorMessageObject, params);
} else {
throw 'Error message not supported for type ' + errorKey + ' and inputType ' + inputType;
}
});
return this._getErrorMessage(selectedError, inputType, renderParameters, opts);
},
createMessageElement: function (scope, opts) {
return $compile(opts.messageTemplate)(scope)
.addClass(opts.messageClassName)
.addClass(opts.hideClassName);
}
};
});
},
getRenderParameters: function (elem) {
var params = {};
['minlength', 'maxlength', 'min', 'max', 'pattern'].forEach(function (attr) {
var calculatedAttr = elem.attr(attr) || elem.attr('ng-' + attr);
if (calculatedAttr) {
params[attr] = calculatedAttr;
}
});
return params;
},
getErrorMessage: function ($error, elem, opts) {
var inputType = elem.attr('type');
var selectedError = '';
var renderParameters = this.getRenderParameters(elem);
this.errorKeys.forEach(function (errorKey) {
if (!selectedError && $error[errorKey]) {
selectedError = errorKey;
}
});
return this._getErrorMessage(selectedError, inputType, renderParameters, opts);
},
createMessageElement: function (scope, opts) {
return $compile(opts.messageTemplate)(scope)
.addClass(opts.messageClassName)
.addClass(opts.hideClassName);
}
};
});
})();
22 changes: 22 additions & 0 deletions test/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,5 +160,27 @@ describe('helper', function () {
expect(messageElement.text()).toBe('');
});

it('should add custom error key if not yet present', function () {
var input1 = angular.element('<input type="text"/>');
var $error1 = {someNewErrorKey: true};

expect(helper.errorKeys.length).toBe(8);

var opts = {
errorMessages: {
required: {
default: 'Custom msg #1',
number: 'Number here!'
},
someNewErrorKey: 'Some new error key message'
}
};

helper.setOptions(opts);
expect(helper.errorKeys.length).toBe(9);

expect(helper.getErrorMessage($error1, input1, opts)).toBe('Some new error key message');
});

});

0 comments on commit 3dc2cf9

Please sign in to comment.