Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
AngularJS EMBG Custom Validator
<!-- EMBG field which is optional -->
<md-input-container>
<label>ЕМБГ</label>
<input ng-model="vm.embg"
mk-valid-embg
maxlength="13"
name="embg"
autocomplete="off">
<div ng-messages="form.embg.$error">
<div ng-message="embg">Внесете валиден ЕМБГ</div>
</div>
</md-input-container>
<!-- EMBG field which is required -->
<md-input-container>
<label>ЕМБГ</label>
<input ng-model="vm.embg"
mk-valid-embg
required
maxlength="13"
name="embg"
autocomplete="off">
<div ng-messages="form.embg.$error">
<div ng-message="required">Внесете ЕМБГ<div>
<div ng-message="embg">Внесете валиден ЕМБГ</div>
</div>
</md-input-container>
(function () {
'use strict';
angular
.module('mk.directives') // replace this with your specific module
.directive('mkValidEmbg', validEmbg); // replace this with your preferred directive name
validEmbg.$inject = [];
function validEmbg() {
var directive = {
link: link,
require: 'ngModel',
restrict: 'A'
};
return directive;
function link(scope, element, attrs, ctrl) {
function embgValidator(embg) {
// I prefer to have this as there is already a specific directive for required fields
// you can combine this directive with ng-required if you are making the field required
if (!embg) {
return true;
}
// check if it is of correct length
// check if it contains only numbers
if (!/^[0-9]{13}$/.test(embg)) {
return false;
}
// check the checksum
if (!isValidCheckSum(embg)) {
return false;
}
// check if it is a valid date
if (!isValidDate(embg)) {
return false;
}
return true;
}
ctrl.$validators.embg = function (ngModelValue) {
return embgValidator(ngModelValue);
};
}
function isValidCheckSum(embg) {
var mask = '765432765432',
sum = 0,
K = parseInt(embg[embg.length - 1]);
for (var i = 0; i <= 12; ++i) {
sum += parseInt(embg[i]) * parseInt(mask[i]);
}
var m = 11 - sum % 11;
if (m >= 10) {
m = 0;
}
return m == K;
}
function isValidDate(embg) {
// it works for dates within the years 1800-2700
// hopefully your software works until that date and this becomes a problem
var d = parseInt(embg.substr(0, 2)),
m = parseInt(embg.substr(2, 2)) - 1, // m is 0 indexed for the calculations (0-11)
y = parseInt(embg.substr(4, 3)) + 1000;
if (parseInt(embg.substr(4, 1)) < 8) {
y += 1000;
}
return m >= 0 && m < 12 && d > 0 && d <= daysInMonth(m, y) && y > 1800 && y <= moment().year();
}
function daysInMonth(m, y) {
switch (m) {
case 1:
return (y % 4 === 0 && y % 100) || y % 400 === 0 ? 29 : 28;
case 8: case 3: case 5: case 10:
return 30;
default:
return 31;
}
}
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment