Skip to content

Commit 4c38add

Browse files
authored
Merge pull request #17 from codermarcos/bugfix/#14
Fixed bugs #14
2 parents 6a9d226 + adb3311 commit 4c38add

File tree

10 files changed

+713
-200
lines changed

10 files changed

+713
-200
lines changed

.editorconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
root = true
22

33
[*]
4-
end_of_line = lf
4+
end_of_line = crlf
55
insert_final_newline = true
66

77
[*.{js}]

.eslintrc.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
],
2626
"linebreak-style": [
2727
"error",
28-
"unix"
28+
"windows"
2929
],
3030
"quotes": [
3131
"error",

examples/javascript/index.html

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@
44
<head>
55
<meta charset="UTF-8">
66
<meta name="viewport" content="width=device-width, initial-scale=1.0">
7-
<meta http-equiv="X-UA-Compatible" content="ie=edge">
87
<title>SimpleMaskMoney</title>
9-
<meta name="description" content="Simple money mask developed with pure JavaScript">
10-
<meta name="keywords" content="SimpleMaskMoney, MaskMoney, MaskJs, Mascara Javascript, Vanilla, Puro, Pure">
118
<style>
129
@import url('https://fonts.googleapis.com/css?family=Slabo+27px');
1310
* {

lib/simple-mask-money.js

Lines changed: 431 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/simple-mask-money.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "simple-mask-money",
3-
"version": "1.3.0",
3+
"version": "2.0.0",
44
"description": "Simple money mask developed with pure JavaScript. To run on Client Side and Server Side",
55
"main": "lib/simple-mask-money.js",
66
"scripts": {

src/core.js

Lines changed: 82 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ module.exports = class Core {
44
this.args = new Args(args);
55
}
66

7+
isFloat(number) {
8+
return number % 1 !== 0;
9+
}
10+
711
completer(size = 1) {
812
return this.args.fixed ? ''.padEnd(size, '0') : ''.padEnd(size, '_');
913
}
@@ -13,113 +17,83 @@ module.exports = class Core {
1317
}
1418

1519
onlyNumber(value) {
20+
const hasDecimalSeparator = value.toString().indexOf(this.args.decimalSeparator);
21+
let putDecimalSeparator = false;
1622
let retorno = '';
1723

18-
for (let i = 0; i < value.length; i++) {
19-
if (isFinite(value[i])) retorno += value[i];
24+
for (let i = value.length - 1; i >= 0; i--) {
25+
if (isFinite(value[i])) {
26+
retorno = value[i] + retorno;
27+
} else if (hasDecimalSeparator !== -1 && !putDecimalSeparator && value[i] === this.args.decimalSeparator) {
28+
retorno = value[i].replace(this.args.decimalSeparator, '.') + retorno;
29+
putDecimalSeparator = true;
30+
}
2031
}
2132

22-
return retorno;
33+
return retorno[0] === '.' ? `0${retorno}` : retorno;
2334
}
2435

2536
addingPrefix(value) {
2637
return `${this.args.prefix}${value}`;
2738
}
2839

2940
removingPrefix(value) {
30-
return value.replace(this.args.prefix, '');
41+
const position = value.indexOf(this.args.prefix, 0);
42+
43+
if (position !== -1) {
44+
value = value.substring(this.args.prefix.length, value.length);
45+
}
46+
47+
return value;
3148
}
3249

3350
addingSuffix(value) {
3451
return `${value}${this.args.suffix}`;
3552
}
3653

3754
removingSuffix(value) {
38-
if (value.includes(this.args.suffix, value.length - this.args.fractionDigits)) {
39-
value = value.replace(this.args.suffix, '');
40-
} else {
41-
value = value.substring(0, value.length - 1);
42-
}
43-
return value;
44-
}
45-
46-
addingCompleterFromStart(value, completer) {
47-
while (value.length < this.args.fractionDigits) {
48-
value = `${completer}${value}`;
49-
}
50-
return value;
51-
}
55+
const position = value.indexOf(this.args.suffix, value.length - this.args.suffix.length);
5256

53-
addingCompleterFromEnd(value, completer) {
54-
while (value.length < this.args.fractionDigits) {
55-
value = `${value}${completer}`;
57+
if (position !== -1) {
58+
const start = value.substring(0, position);
59+
value = start + value.substring(start.length + this.args.suffix.length - 1, value.length - 1);
5660
}
57-
return value;
58-
}
5961

60-
removingCompleterFromStart(value, completer) {
61-
while (value[0] === completer) {
62-
value = value.replace(completer, '');
63-
}
6462
return value;
6563
}
6664

67-
removingCompleterFromEnd(value, completer) {
68-
while (value[value.length - 1] === completer) {
69-
value = value.substring(0, value.length - 1);
65+
addingCompleter(value, completer, length, start = true) {
66+
while (value.length < length) {
67+
value = start ? `${completer}${value}` : `${value}${completer}`;
7068
}
71-
return value;
72-
}
7369

74-
addingAutoComplete(value) {
75-
const n = `${value}${this.addingCompleterFromEnd('', '0')}`;
76-
return n;
77-
}
78-
79-
autoComplete(value) {
80-
const regexp = new RegExp(`\\${this.args.decimalSeparator}`, 'g');
81-
const array = value.match(regexp) || [];
82-
if (array.length > 1) {
83-
value = this.addingAutoComplete(value);
84-
}
8570
return value;
8671
}
8772

88-
addingDecimalSeparator(value, completer, separator) {
89-
let length = value.length - this.args.fractionDigits;
90-
91-
let regexpFraction;
92-
let decimals = '$1';
93-
let dezenas = completer;
94-
let character = isFinite(completer) ? 'd' : 'w';
95-
96-
regexpFraction = `(\\${character}{${this.args.fractionDigits}})`;
73+
removingCompleter(value, completer, start = true) {
74+
const position = start ? 0 : value.length - 1;
9775

98-
if (length > 0) {
99-
regexpFraction = `(\\${character}{${length}})${regexpFraction}`;
100-
dezenas = decimals;
101-
decimals = '$2';
76+
while (value[position] === completer) {
77+
value = value.substring(0, position - 1) + value.substring(position + 1, value.length);
10278
}
10379

104-
return value.replace(
105-
new RegExp(regexpFraction),
106-
`${dezenas}${separator}${decimals}`
107-
);
80+
return value;
10881
}
10982

110-
addingHundredsSeparator(value) {
83+
addingSeparators(value) {
11184
let size = value.length - this.args.fractionDigits;
85+
let character = this.args.fixed ? 'd' : 'w';
86+
let regexp = `\\,?||\\.?(\\${character})`;
11287
let hundreds = Math.ceil(size / 3);
113-
let regexpHundreds = '(\\d)';
11488

11589
let replacement = `${this.args.decimalSeparator}$${hundreds + 1}`;
11690

11791
for (let i = hundreds; i !== 0; i--) {
11892
if (size >= 3) {
119-
regexpHundreds = `(\\d{3})${regexpHundreds}`;
93+
regexp = `(\\${character}{3})${regexp}`;
12094
size -= 3;
12195
} else {
122-
regexpHundreds = `(\\d{${size}})${regexpHundreds}`;
96+
regexp = `(\\${character}{${size}})${regexp}`;
12397
}
12498

12599
if (i > 1) {
@@ -129,21 +103,31 @@ module.exports = class Core {
129103
}
130104
}
131105

132-
return value.replace(new RegExp(regexpHundreds), replacement);
106+
return value.replace(new RegExp(regexp), replacement);
133107
}
134108

135-
removeSeparator(value, separator) {
136-
return value.replace(new RegExp(`\\${separator}`, 'g'), '');
109+
replaceSeparator(value, separator, replacer = '') {
110+
return value.replace(new RegExp(`\\${separator}`, 'g'), replacer);
137111
}
138112

139-
formatDecimal(value, completer, separator) {
140-
value = this.addingCompleterFromStart(value, completer);
141-
value = this.addingDecimalSeparator(value, completer, separator);
142-
return value;
113+
adjustDotPosition(value) {
114+
let fractionDigits;
115+
let retorno = value.toString();
116+
117+
retorno = retorno.replace('.', '');
118+
fractionDigits = retorno.length - this.args.fractionDigits;
119+
retorno = `${retorno.substring(0, fractionDigits)}.${retorno.substring(fractionDigits)}`;
120+
121+
return retorno;
143122
}
144123

145-
textToNumber(input) {
146-
let retorno = input.toString();
124+
checkNumberStart(value) {
125+
const retorno = value.toString();
126+
return retorno[0] === '.' ? `0${retorno}` : retorno;
127+
}
128+
129+
textToNumber(value, input) {
130+
let retorno = value.toString();
147131
let completer = this.completer();
148132

149133
if (this.args.prefix) {
@@ -154,32 +138,41 @@ module.exports = class Core {
154138
retorno = this.removingSuffix(retorno);
155139
}
156140

157-
retorno = this.removeSeparator(retorno, this.args.thousandsSeparator);
158-
retorno = this.removeSeparator(retorno, this.args.decimalSeparator);
159-
160141
retorno = this.onlyNumber(retorno);
161142

162-
retorno = this.removingCompleterFromStart(
163-
retorno,
164-
completer
165-
);
143+
if (retorno) {
144+
if (input) {
145+
retorno = this.adjustDotPosition(retorno);
146+
}
147+
148+
retorno = this.removingCompleter(retorno, completer);
149+
150+
retorno = this.checkNumberStart(retorno);
151+
}
166152

167153
return retorno || (this.args.fixed ? '0' : '');
168154
}
169155

170-
numberToText(input) {
156+
numberToText(value) {
171157
let retorno = this.emptyOrInvalid();
158+
value = this.replaceSeparator(value.toString(), this.args.decimalSeparator, '.');
159+
160+
if (!isNaN(parseFloat(value))) {
161+
if (this.isFloat(value)) {
162+
const number = value.split('.');
163+
let hundreds = number[0];
164+
let decimals = number[1];
172165

173-
if (!isNaN(parseFloat(input))) {
174-
if (input.length <= this.args.fractionDigits) {
175-
retorno = this.formatDecimal(
176-
input,
177-
this.completer(),
178-
this.args.decimalSeparator
179-
);
166+
decimals = this.addingCompleter(decimals || '', this.completer(), this.args.fractionDigits, false);
167+
168+
retorno = `${hundreds}${decimals}`;
180169
} else {
181-
retorno = this.addingHundredsSeparator(input);
170+
retorno = this.replaceSeparator(value, '.');
171+
retorno = this.addingCompleter(retorno || '', this.completer(), this.args.fractionDigits);
172+
retorno = this.args.fractionDigits >= retorno.length ? `${this.completer()}${retorno}` : retorno;
182173
}
174+
175+
retorno = this.addingSeparators(retorno);
183176
}
184177

185178
if (this.args.prefix) {

src/index.js

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -32,35 +32,24 @@ module.exports = class SimpleMaskMoney {
3232
_core = new Core(_args);
3333
}
3434

35-
static format(value) {
35+
static format(value, input = false) {
3636
const negative = _args.allowNegative && value.indexOf('-') !== -1;
37-
const formatation = _core.numberToText(_core.textToNumber(value));
37+
const formatation = _core.numberToText(_core.textToNumber(value, input));
3838

3939
return `${!_args.negativeSignAfter && negative ? '-': ''}${formatation}${_args.negativeSignAfter && negative ? '-': ''}`;
4040
}
4141

4242
static formatToNumber(input) {
43+
let value = input.toString();
4344
let retorno = '0';
44-
let value = _core.textToNumber(input);
45-
const negative = _args.allowNegative && input.indexOf('-') !== -1;
45+
const negative = _args.allowNegative && value.indexOf('-') !== -1;
4646

4747
if (negative) {
48-
value.replace('-', '');
48+
value = value.replace('-', '');
4949
}
5050

51+
value = _core.textToNumber(value);
5152
if (!isNaN(parseFloat(value))) {
52-
if (value.length <= _args.fractionDigits) {
53-
value = _core.formatDecimal(value, '0', '.');
54-
} else {
55-
let lengthWithoutDecimals = value.length - _args.fractionDigits;
56-
value = value.replace(
57-
new RegExp(
58-
`(\\d{${lengthWithoutDecimals}})(\\d{${_args.fractionDigits}})`
59-
),
60-
'$1.$2'
61-
);
62-
}
63-
6453
retorno = value;
6554
}
6655

@@ -78,7 +67,7 @@ module.exports = class SimpleMaskMoney {
7867

7968
input.addEventListener('input', e => {
8069
const oldValue = input.value;
81-
const newValue = SimpleMaskMoney.format(oldValue);
70+
const newValue = SimpleMaskMoney.format(oldValue, true);
8271
const caretPosition = implanter.getCaretPosition(input);
8372
const move = implanter.indexMove(newValue, oldValue);
8473
let newCaretPosition = caretPosition - move;

0 commit comments

Comments
 (0)