forked from Coridyn/angular-money-directive
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathangular-money-directive.js
120 lines (102 loc) · 3.08 KB
/
angular-money-directive.js
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/**
* Heavily adapted from the `type="number"` directive in Angular's
* /src/ng/directive/input.js
*/
angular.module('fiestah.money', [])
.directive('money', function () {
'use strict';
var NUMBER_REGEXP = /^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/;
function link(scope, el, attrs, ngModelCtrl) {
var min = parseFloat(attrs.min || 0);
var precision = parseFloat(attrs.precision || 2);
var lastValidValue;
function round(num) {
var d = Math.pow(10, precision);
return Math.round(num * d) / d;
}
function formatPrecision(value) {
return parseFloat(value).toFixed(precision);
}
function formatViewValue(value) {
return ngModelCtrl.$isEmpty(value) ? '' : '' + value;
}
ngModelCtrl.$parsers.push(function (value) {
if (angular.isUndefined(value)) {
value = '';
}
// Handle leading decimal point, like ".5"
if (value.indexOf('.') === 0) {
value = '0' + value;
}
// Allow "-" inputs only when min < 0
if (value.indexOf('-') === 0) {
if (min >= 0) {
value = null;
ngModelCtrl.$setViewValue('');
ngModelCtrl.$render();
} else if (value === '-') {
value = '';
}
}
var empty = ngModelCtrl.$isEmpty(value);
if (empty || NUMBER_REGEXP.test(value)) {
lastValidValue = (value === '')
? null
: (empty ? value : parseFloat(value));
} else {
// Render the last valid input in the field
ngModelCtrl.$setViewValue(formatViewValue(lastValidValue));
ngModelCtrl.$render();
}
ngModelCtrl.$setValidity('number', true);
return lastValidValue;
});
ngModelCtrl.$formatters.push(formatViewValue);
var minValidator = function(value) {
if (!ngModelCtrl.$isEmpty(value) && value < min) {
ngModelCtrl.$setValidity('min', false);
return undefined;
} else {
ngModelCtrl.$setValidity('min', true);
return value;
}
};
ngModelCtrl.$parsers.push(minValidator);
ngModelCtrl.$formatters.push(minValidator);
if (attrs.max) {
var max = parseFloat(attrs.max);
var maxValidator = function(value) {
if (!ngModelCtrl.$isEmpty(value) && value > max) {
ngModelCtrl.$setValidity('max', false);
return undefined;
} else {
ngModelCtrl.$setValidity('max', true);
return value;
}
};
ngModelCtrl.$parsers.push(maxValidator);
ngModelCtrl.$formatters.push(maxValidator);
}
// Round off
if (precision > -1) {
ngModelCtrl.$parsers.push(function (value) {
return value ? round(value) : value;
});
ngModelCtrl.$formatters.push(function (value) {
return value ? formatPrecision(value) : value;
});
}
el.bind('blur', function () {
var value = ngModelCtrl.$modelValue;
if (value) {
ngModelCtrl.$viewValue = formatPrecision(value);
ngModelCtrl.$render();
}
});
}
return {
restrict: 'A',
require: 'ngModel',
link: link
};
});