fix bug comma

This commit is contained in:
2020-07-12 15:04:12 +07:00
parent e132f3b5c9
commit c27b800795
66 changed files with 15559 additions and 16 deletions

View File

@@ -0,0 +1,12 @@
# This file is for unifying the coding style for different editors and IDEs
# editorconfig.org
root = true
[*]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

View File

@@ -0,0 +1,41 @@
{
"bitwise": true,
"boss": true,
"browser": true,
"camelcase": true,
"curly": true,
"eqeqeq": true,
"eqnull": true,
"expr": true,
"immed": true,
"noarg": true,
"node": true,
"onevar": true,
"quotmark": "double",
"smarttabs": true,
"trailing": true,
"unused": true,
"globals": {
"jQuery": true,
"$": true,
"devel": true,
// QUnit
"QUnit": true,
"test": true,
"module": true,
"expect": true,
"stop": true,
"start": true,
"ok": true,
"equal": true,
"notEqual": true,
"deepEqual": true,
"notDeepEqual": true,
"strictEqual": true,
"notStrictEqual": true,
"raises": true,
// util functions
"keypress": true,
"keydown": true
}
}

View File

@@ -0,0 +1,8 @@
language: node_js
node_js:
- 4
install:
- npm install grunt-cli -g
- npm install -g bower
- npm install
- bower install

View File

@@ -0,0 +1,75 @@
module.exports = function(grunt) {
"use strict";
grunt.initConfig({
pkg: grunt.file.readJSON("package.json"),
meta: {
banner: "/*\n" +
" * <%= pkg.title || pkg.name %> - v<%= pkg.version %>\n" +
" * <%= pkg.description %>\n" +
" * <%= pkg.homepage %>\n" +
" *\n" +
" * Made by <%= pkg.author.name %>\n" +
" * Under <%= pkg.license %> License\n" +
" */\n"
},
jshint: {
all: ["Gruntfile.js", "src/**/*.js", "test/**/*.js", "!test/util.js"],
options: {
jshintrc: true
}
},
concat: {
dist: {
src: ["src/jquery.maskMoney.js"],
dest: "dist/jquery.maskMoney.js"
},
options: {
banner: "<%= meta.banner %>"
}
},
uglify: {
options: {
banner: "<%= meta.banner %>",
mangle: {
reserved: ["jQuery", "$"]
}
},
build: {
files: [
{ src: "src/jquery.maskMoney.js", dest: "dist/jquery.maskMoney.min.js" },
]
}
},
qunit: {
all: ["test/*.html"]
},
jquerymanifest: {
options: {
source: grunt.file.readJSON("package.json"),
overrides: {
"name": "maskMoney",
"title": "jQuery maskMoney",
"download": "https://raw.github.com/plentz/jquery-maskmoney/master/dist/jquery.maskMoney.min.js",
"docs": "http://github.com/plentz/jquery-maskmoney",
"demo": "http://plentz.github.com/jquery-maskmoney",
"keywords": ["form", "input", "mask", "money"]
}
}
},
watch: {
files: ["test/*.html", "test/*.js", "src/*.js"],
tasks: ["jshint", "qunit"]
}
});
grunt.loadNpmTasks("grunt-contrib-concat");
grunt.loadNpmTasks("grunt-contrib-jshint");
grunt.loadNpmTasks("grunt-contrib-uglify");
grunt.loadNpmTasks("grunt-jquerymanifest");
grunt.loadNpmTasks("grunt-contrib-qunit");
grunt.loadNpmTasks("grunt-contrib-watch");
grunt.registerTask("test", ["jshint", "qunit"]);
grunt.registerTask("default", ["jshint", "qunit", "concat", "uglify", "jquerymanifest"]);
};

View File

@@ -0,0 +1,22 @@
Copyright (c) 2007-2013 Diego Plentz (plentz.org)
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,103 @@
# jQuery maskMoney [![Build Status](https://travis-ci.org/plentz/jquery-maskmoney.png)](https://travis-ci.org/plentz/jquery-maskmoney)
Just a simple way to create masks to your currency form fields with [jQuery](http://jquery.com/).
***
### Download
To get the latest(minified) version, [click here](https://cdn.rawgit.com/plentz/jquery-maskmoney/master/dist/jquery.maskMoney.min.js).
You can also use [CloudFlare's cdnjs](http://cdnjs.com/). Just choose the version you want to use [here](http://cdnjs.com/libraries/jquery-maskmoney/).
***
### Show Time!
To view a complete demonstration of it's features and usage, access our [examples page](http://plentz.github.com/jquery-maskmoney)!
***
### Usage:
```html
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" type="text/javascript"></script>
<script src="dist/jquery.maskMoney.min.js" type="text/javascript"></script>
</head>
<body>
<input type="text" id="currency" />
</body>
<script>
$(function() {
$('#currency').maskMoney();
})
</script>
```
***
### Options:
The options that you can set are:
* `prefix`: the prefix to be displayed before(aha!) the value entered by the user(example: "US$ 1234.23"). default: ''
* `suffix`: the suffix to be displayed after the value entered by the user(example: "1234.23 €"). default: ''
* `affixesStay`: set if the prefix and suffix will stay in the field's value after the user exits the field. default: true
* `thousands`: the thousands separator. default: ','
* `decimal`: the decimal separator. default: '.'
* `precision`: how many decimal places are allowed. default: 2
* `allowZero`: use this setting to prevent users from inputing zero. default: false
* `allowNegative`: use this setting to prevent users from inputing negative values. default: false
* `formatOnBlur`: delay formatting of text field until focus leaves the field. default: false
* `reverse`: by default, `maskMoney` applies keystrokes from right to left. use this setting to apply keystrokes from left to right.
* `selectAllOnFocus`: select all text in the input when the element fires the focus event. default :false
* `allowEmpty`: allow empty input values, so that when you delete the number it doesn't reset to 0.00. default: false
__IMPORTANT__: if you try to bind maskMoney to a read only field, nothing will happen, since we ignore completely read only fields. So, if you have a read only field, try to bind maskMoney to it, it will not work. Even if you change the field removing the readonly property, you will need to re-bind maskMoney to make it work.
***
### Bonus!
We have 3 bonus methods that can be useful to you:
* `.maskMoney('destroy')` removes maskMoney from an element.
* `.maskMoney('mask')` apply the mask to your input. This method can work as a setter as well, if you pass a value to it, like this `.maskMoney('mask', 1999.99)`
* `.maskMoney('unmasked')` return a float value (ex.: 'R$ 1.234,56' => 1234.56). PS: If you have only one input field, you should use this way `.maskMoney('unmasked')[0]`, since it will always return an array.
You can also configure maskMoney options using the data-* API instead of passing it as a hash in the `.maskMoney` method call. To use it, simply set the options using `data-<option>`, like this:
```html
<input type="text" data-affixes-stay="true" data-prefix="R$ " data-thousands="." data-decimal="," />
```
And when you bind maskMoney to that field, we will read those options. **ATTENTION**: for settings that isn't entirely lowercase, you will need to use dashes instead of capital letters. For example, to set `allowZero`, you will need to add a attribute called `data-allow-zero`.
***
### Tests:
To run our test suite, just clone the repo and open `test/index.html`. If you want to run it using nodejs, clone the repo and run:
```
npm install
bower install
grunt test
```
***
### Contributors:
* [Aurélio Saraiva](http://github.com/aureliosaraiva)
* [Raul Pereira da Silva](http://raulpereira.com)
* [Diego Plentz](http://plentz.org)
* [Otávio Ribeiro Medeiros](http://github.com/otaviomedeiros)
* [Víctor Cruz](http://github.com/xtream)
* [Synapse Studios](http://github.com/synapsestudios)
* [Guilherme Garnier](http://blog.guilhermegarnier.com/)
* [Plínio Balduino](http://github.com/pbalduino)
* [Luis Fernando Gomes](https://github.com/luiscoms)
* [Gary Moore](http://www.gmoore.net/)
* [Daniel Loureiro](https://github.com/loureirorg)
* [Thiago Silva](http://twitter.com/tafs7/)
* [Guilherme Nagatomo](https://github.com/guilhermehn)
* [Andrew Duncan](https://github.com/abduncan)
***
### License:
__jQuery-maskMoney__ is released under the MIT license.

View File

@@ -0,0 +1,25 @@
{
"name": "jquery-maskmoney",
"version": "3.1.1",
"homepage": "https://github.com/plentz/jquery-maskmoney",
"authors": [
"Diego Plentz <diego@plentz.org>"
],
"description": "jQuery plugin to mask data entry in the input text in the form of money (currency).",
"main": "dist/jquery.maskMoney.js",
"keywords": [
"form",
"money",
"jquery"
],
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test"
],
"dependencies": {
"jquery": "^3.2.1"
}
}

View File

@@ -0,0 +1,110 @@
<html>
<head>
<meta charset="utf-8">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" type="text/javascript"></script>
<script src="../src/jquery.maskMoney.js" type="text/javascript"></script>
<!-- just necessary for syntax highlight -->
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shCore.css' rel='stylesheet' type='text/css' />
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css' rel='stylesheet' type='text/css' />
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJScript.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js' type='text/javascript'></script>
<style type="text/css">
body { font-family: helvetica, sans-serif; }
h1 { font-size: 2em;}
h4 {font-weight: 100; }
h4 code { background-color: whitesmoke; }
</style>
</head>
<body>
<h1>jQuery-maskMoney examples</h1>
<p>jQuery plugin to mask data entry in the input text in the form of money (currency). <a href="https://github.com/plentz/jquery-maskmoney">Project home @ github</a></p>
<input type="text" id="demo1" value="0.01" />
<script type="text/javascript">$("#demo1").maskMoney();</script>
<pre class="brush: js">$("#demo1").maskMoney();</pre>
<input type="text" id="demo2" />
<script type="text/javascript">$("#demo2").maskMoney({thousands:',', decimal:'.', allowZero: true, suffix: ' €'});</script>
<pre class="brush: js">$("#demo2").maskMoney({thousands:'', decimal:'.', allowZero:true, suffix: ' €'});</pre>
<input type="text" id="demo3" />
<script type="text/javascript">$("#demo3").maskMoney({prefix:'R$ ', allowNegative: true, thousands:'.', decimal:',', affixesStay: false});</script>
<pre class="brush: js">$("#demo3").maskMoney({prefix:'R$ ', allowNegative: true, thousands:'.', decimal:',', affixesStay: false});</pre>
<input type="text" id="demo4" data-thousands="." data-decimal="," data-prefix="R$ " />
<script type="text/javascript">$("#demo4").maskMoney();</script>
<pre class="brush: js">$("#demo4").maskMoney();</pre>
<pre class="brush: html"><input type="text" id="demo4" data-thousands="." data-decimal="," data-prefix="R$ " /></pre>
<input type="text" id="demo5" value="1234567.89"/>
<script type="text/javascript">$("#demo5").maskMoney({prefix:'R$ ', thousands:'.', decimal:',', affixesStay: true});</script>
<input type="button" onclick="$('#demo5').maskMoney('mask')" value="trigger mask event at demo5"/>
<pre class="brush: js">$("#demo5").maskMoney('mask');</pre>
<input type="text" id="demo6"/>
<script type="text/javascript">$("#demo6").maskMoney({prefix:'R$ ', thousands:'.', decimal:',', affixesStay: true});</script>
<input type="button" onclick="$('#demo6').maskMoney('mask', 1999.99)" value="trigger mask event at demo6, passing a float value as parameter"/>
<pre class="brush: js">$("#demo6").maskMoney('mask', 1999.99);</pre>
<input type="text" id="demo7"/>
<script type="text/javascript">$("#demo7").maskMoney();</script>
<input type="button" onclick="$('#demo7').maskMoney('destroy')" value="remove maskmoney from demo7"/>
<pre class="brush: js">$("#demo6").maskMoney('destroy');</pre>
<input type="text" id="demo8" value="R$ 1.231.231,23"/>
<script type="text/javascript">$("#demo8").maskMoney();</script>
<input type="button" onclick="var num = $('#demo8').maskMoney('unmasked')[0];alert('type: '+typeof(num) + ', value: ' + num)" value="alert unmasked value and type from demo7"/>
<pre class="brush: js">
var num = $('#demo8').maskMoney('unmasked')[0];
alert('type: '+ typeof(num) + ', value: ' + num)
</pre>
<input type="text" id="demo9" value="$15.45" />
<script type="text/javascript">
$("#demo9").maskMoney({ formatOnBlur: true, prefix: '$' });
</script>
<pre class="brush: js">$("#demo9").maskMoney({ formatOnBlur: true, prefix: '$' });</pre>
<input type="text" id="demo10" value="$15.45" />
<script type="text/javascript">
$("#demo10").maskMoney({ formatOnBlur: true, reverse: true, prefix: '$' });
</script>
<h4>Note: The <code>reverse</code> option is meant to be used with the <code>formatOnBlur</code> option.</h4>
<pre class="brush: js">
$("#demo10").maskMoney({ formatOnBlur: true, reverse: true, prefix: '$' });
</pre>
<input type="text" id="demo11" value="45.55" />
<script type="text/javascript">
$("#demo11").maskMoney({ selectAllOnFocus: true });
</script>
<pre class="brush: js">$("#demo11").maskMoney({ selectAllOnFocus: true });</pre>
<input type="text" id="demo12" value=""/>
<script type="text/javascript">$("#demo12").maskMoney({ formatOnBlur: true, reverse: true, prefix: '$', selectAllOnFocus: true });</script>
<input type="button" onclick="var num = $('#demo12').maskMoney('applyMask', $('#demo12').val());alert('Mask applied '+ num)" value="alert masked value from demo12"/>
<pre class="brush: js">
$("#demo12").maskMoney({ formatOnBlur: true, reverse: true, prefix: '$', selectAllOnFocus: true });
var num = $('#demo12').maskMoney('applyMask', $('#demo12').val());
alert('Mask applied '+ num);
</pre>
<input type="text" id="demo13" value="45" />
<script type="text/javascript">
$("#demo13").maskMoney({ formatOnBlur: true, reverse: true, prefix: '$', selectAllOnFocus: true, precision: 0 });
</script>
<pre class="brush: js">$("#demo13").maskMoney({ formatOnBlur: true, reverse: true, prefix: '$', selectAllOnFocus: true, precision: 0 });</pre>
<input type="text" id="demo14" value="" />
<script type="text/javascript">
$("#demo14").maskMoney({ formatOnBlur: true, reverse: true, prefix: '$', selectAllOnFocus: true, precision: 4, allowEmpty: true });
</script>
<pre class="brush: js">$("#demo14").maskMoney({ formatOnBlur: true, reverse: true, prefix: '$', selectAllOnFocus: true, precision: 4, allowEmpty: true });</pre>
</body>
<script type="text/javascript">
SyntaxHighlighter.all()
</script>
</html>

View File

@@ -0,0 +1,591 @@
/*
* jquery-maskmoney - v3.1.1
* jQuery plugin to mask data entry in the input text in the form of money (currency)
* https://github.com/plentz/jquery-maskmoney
*
* Made by Diego Plentz
* Under MIT License
*/
(function ($) {
"use strict";
if (!$.browser) {
$.browser = {};
$.browser.mozilla = /mozilla/.test(navigator.userAgent.toLowerCase()) && !/webkit/.test(navigator.userAgent.toLowerCase());
$.browser.webkit = /webkit/.test(navigator.userAgent.toLowerCase());
$.browser.opera = /opera/.test(navigator.userAgent.toLowerCase());
$.browser.msie = /msie/.test(navigator.userAgent.toLowerCase());
$.browser.device = /android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase());
}
var defaultOptions = {
prefix: "",
suffix: "",
affixesStay: true,
thousands: ",",
decimal: ".",
precision: 2,
allowZero: false,
allowNegative: false,
doubleClickSelection: true,
allowEmpty: false,
bringCaretAtEndOnFocus: true
},
methods = {
destroy: function () {
$(this).unbind(".maskMoney");
if ($.browser.msie) {
this.onpaste = null;
}
return this;
},
applyMask: function (value) {
var $input = $(this);
// data-* api
var settings = $input.data("settings");
return maskValue(value, settings);
},
mask: function (value) {
return this.each(function () {
var $this = $(this);
if (typeof value === "number") {
$this.val(value);
}
return $this.trigger("mask");
});
},
unmasked: function () {
return this.map(function () {
var value = ($(this).val() || "0"),
isNegative = value.indexOf("-") !== -1,
decimalPart;
// get the last position of the array that is a number(coercion makes "" to be evaluated as false)
$(value.split(/\D/).reverse()).each(function (index, element) {
if (element) {
decimalPart = element;
return false;
}
});
value = value.replace(/\D/g, "");
value = value.replace(new RegExp(decimalPart + "$"), "." + decimalPart);
if (isNegative) {
value = "-" + value;
}
return parseFloat(value);
});
},
unmaskedWithOptions: function () {
return this.map(function () {
var value = ($(this).val() || "0"),
settings = $(this).data("settings") || defaultOptions,
regExp = new RegExp((settings.thousandsForUnmasked || settings.thousands), "g");
value = value.replace(regExp, "");
return parseFloat(value);
});
},
init: function (parameters) {
// the default options should not be shared with others
parameters = $.extend($.extend({}, defaultOptions), parameters);
return this.each(function () {
var $input = $(this), settings,
onFocusValue;
// data-* api
settings = $.extend({}, parameters);
settings = $.extend(settings, $input.data());
// Store settings for use with the applyMask method.
$input.data("settings", settings);
function getInputSelection() {
var el = $input.get(0),
start = 0,
end = 0,
normalizedValue,
range,
textInputRange,
len,
endRange;
if (typeof el.selectionStart === "number" && typeof el.selectionEnd === "number") {
start = el.selectionStart;
end = el.selectionEnd;
} else {
range = document.selection.createRange();
if (range && range.parentElement() === el) {
len = el.value.length;
normalizedValue = el.value.replace(/\r\n/g, "\n");
// Create a working TextRange that lives only in the input
textInputRange = el.createTextRange();
textInputRange.moveToBookmark(range.getBookmark());
// Check if the start and end of the selection are at the very end
// of the input, since moveStart/moveEnd doesn't return what we want
// in those cases
endRange = el.createTextRange();
endRange.collapse(false);
if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
start = end = len;
} else {
start = -textInputRange.moveStart("character", -len);
start += normalizedValue.slice(0, start).split("\n").length - 1;
if (textInputRange.compareEndPoints("EndToEnd", endRange) > -1) {
end = len;
} else {
end = -textInputRange.moveEnd("character", -len);
end += normalizedValue.slice(0, end).split("\n").length - 1;
}
}
}
}
return {
start: start,
end: end
};
} // getInputSelection
function canInputMoreNumbers() {
var haventReachedMaxLength = !($input.val().length >= $input.attr("maxlength") && $input.attr("maxlength") >= 0),
selection = getInputSelection(),
start = selection.start,
end = selection.end,
haveNumberSelected = (selection.start !== selection.end && $input.val().substring(start, end).match(/\d/)) ? true : false,
startWithZero = ($input.val().substring(0, 1) === "0");
return haventReachedMaxLength || haveNumberSelected || startWithZero;
}
function setCursorPosition(pos) {
// Do not set the position if
// the we're formatting on blur.
// This is because we do not want
// to refocus on the control after
// the blur.
if (!!settings.formatOnBlur) {
return;
}
$input.each(function (index, elem) {
if (elem.setSelectionRange) {
elem.focus();
elem.setSelectionRange(pos, pos);
} else if (elem.createTextRange) {
var range = elem.createTextRange();
range.collapse(true);
range.moveEnd("character", pos);
range.moveStart("character", pos);
range.select();
}
});
}
function maskAndPosition(startPos) {
var originalLen = $input.val().length,
newLen;
$input.val(maskValue($input.val(), settings));
newLen = $input.val().length;
// If the we're using the reverse option,
// do not put the cursor at the end of
// the input. The reverse option allows
// the user to input text from left to right.
if (!settings.reverse) {
startPos = startPos - (originalLen - newLen);
}
setCursorPosition(startPos);
}
function mask() {
var value = $input.val();
if (settings.allowEmpty && value === "") {
return;
}
var decimalPointIndex = value.indexOf(settings.decimal);
if (settings.precision > 0) {
if(decimalPointIndex < 0){
value += settings.decimal + new Array(settings.precision + 1).join(0);
}
else {
// If the following decimal part dosen't have enough length against the precision, it needs to be filled with zeros.
var integerPart = value.slice(0, decimalPointIndex),
decimalPart = value.slice(decimalPointIndex + 1);
value = integerPart + settings.decimal + decimalPart +
new Array((settings.precision + 1) - decimalPart.length).join(0);
}
} else if (decimalPointIndex > 0) {
// if the precision is 0, discard the decimal part
value = value.slice(0, decimalPointIndex);
}
$input.val(maskValue(value, settings));
}
function changeSign() {
var inputValue = $input.val();
if (settings.allowNegative) {
if (inputValue !== "" && inputValue.charAt(0) === "-") {
return inputValue.replace("-", "");
} else {
return "-" + inputValue;
}
} else {
return inputValue;
}
}
function preventDefault(e) {
if (e.preventDefault) { //standard browsers
e.preventDefault();
} else { // old internet explorer
e.returnValue = false;
}
}
function fixMobile() {
if ($.browser.device) {
$input.attr("type", "tel");
}
}
function keypressEvent(e) {
e = e || window.event;
var key = e.which || e.charCode || e.keyCode,
decimalKeyCode = settings.decimal.charCodeAt(0);
//added to handle an IE "special" event
if (key === undefined) {
return false;
}
// any key except the numbers 0-9. if we're using settings.reverse,
// allow the user to input the decimal key
if ((key < 48 || key > 57) && (key !== decimalKeyCode || !settings.reverse)) {
return handleAllKeysExceptNumericalDigits(key, e);
} else if (!canInputMoreNumbers()) {
return false;
} else {
if (key === decimalKeyCode && shouldPreventDecimalKey()) {
return false;
}
if (settings.formatOnBlur) {
return true;
}
preventDefault(e);
applyMask(e);
return false;
}
}
function shouldPreventDecimalKey() {
// If all text is selected, we can accept the decimal
// key because it will replace everything.
if (isAllTextSelected()) {
return false;
}
return alreadyContainsDecimal();
}
function isAllTextSelected() {
var length = $input.val().length;
var selection = getInputSelection();
// This should if all text is selected or if the
// input is empty.
return selection.start === 0 && selection.end === length;
}
function alreadyContainsDecimal() {
return $input.val().indexOf(settings.decimal) > -1;
}
function applyMask(e) {
e = e || window.event;
var key = e.which || e.charCode || e.keyCode,
keyPressedChar = "",
selection,
startPos,
endPos,
value;
if (key >= 48 && key <= 57) {
keyPressedChar = String.fromCharCode(key);
}
selection = getInputSelection();
startPos = selection.start;
endPos = selection.end;
value = $input.val();
$input.val(value.substring(0, startPos) + keyPressedChar + value.substring(endPos, value.length));
maskAndPosition(startPos + 1);
}
function handleAllKeysExceptNumericalDigits(key, e) {
// -(minus) key
if (key === 45) {
$input.val(changeSign());
return false;
// +(plus) key
} else if (key === 43) {
$input.val($input.val().replace("-", ""));
return false;
// enter key or tab key
} else if (key === 13 || key === 9) {
return true;
} else if ($.browser.mozilla && (key === 37 || key === 39) && e.charCode === 0) {
// needed for left arrow key or right arrow key with firefox
// the charCode part is to avoid allowing "%"(e.charCode 0, e.keyCode 37)
return true;
} else { // any other key with keycode less than 48 and greater than 57
preventDefault(e);
return true;
}
}
function keydownEvent(e) {
e = e || window.event;
var key = e.which || e.charCode || e.keyCode,
selection,
startPos,
endPos,
value,
lastNumber;
//needed to handle an IE "special" event
if (key === undefined) {
return false;
}
selection = getInputSelection();
startPos = selection.start;
endPos = selection.end;
if (key === 8 || key === 46 || key === 63272) { // backspace or delete key (with special case for safari)
preventDefault(e);
value = $input.val();
// not a selection
if (startPos === endPos) {
// backspace
if (key === 8) {
if (settings.suffix === "") {
startPos -= 1;
} else {
// needed to find the position of the last number to be erased
lastNumber = value.split("").reverse().join("").search(/\d/);
startPos = value.length - lastNumber - 1;
endPos = startPos + 1;
}
//delete
} else {
endPos += 1;
}
}
$input.val(value.substring(0, startPos) + value.substring(endPos, value.length));
maskAndPosition(startPos);
return false;
} else if (key === 9) { // tab key
return true;
} else { // any other key
return true;
}
}
function focusEvent() {
onFocusValue = $input.val();
mask();
var input = $input.get(0),
textRange;
if (!!settings.selectAllOnFocus) {
input.select();
} else if (input.createTextRange && settings.bringCaretAtEndOnFocus) {
textRange = input.createTextRange();
textRange.collapse(false); // set the cursor at the end of the input
textRange.select();
}
}
function cutPasteEvent() {
setTimeout(function () {
mask();
}, 0);
}
function getDefaultMask() {
var n = parseFloat("0") / Math.pow(10, settings.precision);
return (n.toFixed(settings.precision)).replace(new RegExp("\\.", "g"), settings.decimal);
}
function blurEvent(e) {
if ($.browser.msie) {
keypressEvent(e);
}
if (!!settings.formatOnBlur && $input.val() !== onFocusValue) {
applyMask(e);
}
if ($input.val() === "" && settings.allowEmpty) {
$input.val("");
} else if ($input.val() === "" || $input.val() === setSymbol(getDefaultMask(), settings)) {
if (!settings.allowZero) {
$input.val("");
} else if (!settings.affixesStay) {
$input.val(getDefaultMask());
} else {
$input.val(setSymbol(getDefaultMask(), settings));
}
} else {
if (!settings.affixesStay) {
var newValue = $input.val().replace(settings.prefix, "").replace(settings.suffix, "");
$input.val(newValue);
}
}
if ($input.val() !== onFocusValue) {
$input.change();
}
}
function clickEvent() {
var input = $input.get(0),
length;
if (!!settings.selectAllOnFocus) {
// selectAllOnFocus will be handled by
// the focus event. The focus event is
// also fired when the input is clicked.
return;
} else if (input.setSelectionRange && settings.bringCaretAtEndOnFocus) {
length = $input.val().length;
input.setSelectionRange(length, length);
} else {
$input.val($input.val());
}
}
function doubleClickEvent() {
var input = $input.get(0),
start,
length;
if (input.setSelectionRange && settings.bringCaretAtEndOnFocus) {
length = $input.val().length;
start = settings.doubleClickSelection ? 0 : length;
input.setSelectionRange(start, length);
} else {
$input.val($input.val());
}
}
fixMobile();
$input.unbind(".maskMoney");
$input.bind("keypress.maskMoney", keypressEvent);
$input.bind("keydown.maskMoney", keydownEvent);
$input.bind("blur.maskMoney", blurEvent);
$input.bind("focus.maskMoney", focusEvent);
$input.bind("click.maskMoney", clickEvent);
$input.bind("dblclick.maskMoney", doubleClickEvent);
$input.bind("cut.maskMoney", cutPasteEvent);
$input.bind("paste.maskMoney", cutPasteEvent);
$input.bind("mask.maskMoney", mask);
});
}
};
function setSymbol(value, settings) {
var operator = "";
if (value.indexOf("-") > -1) {
value = value.replace("-", "");
operator = "-";
}
if (value.indexOf(settings.prefix) > -1) {
value = value.replace(settings.prefix, "");
}
if (value.indexOf(settings.suffix) > -1) {
value = value.replace(settings.suffix, "");
}
return operator + settings.prefix + value + settings.suffix;
}
function maskValue(value, settings) {
if (settings.allowEmpty && value === "") {
return "";
}
if (!!settings.reverse) {
return maskValueReverse(value, settings);
}
return maskValueStandard(value, settings);
}
function maskValueStandard(value, settings) {
var negative = (value.indexOf("-") > -1 && settings.allowNegative) ? "-" : "",
onlyNumbers = value.replace(/[^0-9]/g, ""),
integerPart = onlyNumbers.slice(0, onlyNumbers.length - settings.precision),
newValue,
decimalPart,
leadingZeros;
newValue = buildIntegerPart(integerPart, negative, settings);
if (settings.precision > 0) {
decimalPart = onlyNumbers.slice(onlyNumbers.length - settings.precision);
leadingZeros = new Array((settings.precision + 1) - decimalPart.length).join(0);
newValue += settings.decimal + leadingZeros + decimalPart;
}
return setSymbol(newValue, settings);
}
function maskValueReverse(value, settings) {
var negative = (value.indexOf("-") > -1 && settings.allowNegative) ? "-" : "",
valueWithoutSymbol = value.replace(settings.prefix, "").replace(settings.suffix, ""),
integerPart = valueWithoutSymbol.split(settings.decimal)[0],
newValue,
decimalPart = "";
if (integerPart === "") {
integerPart = "0";
}
newValue = buildIntegerPart(integerPart, negative, settings);
if (settings.precision > 0) {
var arr = valueWithoutSymbol.split(settings.decimal);
if (arr.length > 1) {
decimalPart = arr[1];
}
newValue += settings.decimal + decimalPart;
var rounded = Number.parseFloat((integerPart + "." + decimalPart)).toFixed(settings.precision);
var roundedDecimalPart = rounded.toString().split(settings.decimal)[1];
newValue = newValue.split(settings.decimal)[0] + "." + roundedDecimalPart;
}
return setSymbol(newValue, settings);
}
function buildIntegerPart(integerPart, negative, settings) {
// remove initial zeros
integerPart = integerPart.replace(/^0*/g, "");
// put settings.thousands every 3 chars
integerPart = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, settings.thousands);
if (integerPart === "") {
integerPart = "0";
}
return negative + integerPart;
}
$.fn.maskMoney = function (method) {
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof method === "object" || !method) {
return methods.init.apply(this, arguments);
} else {
$.error("Method " + method + " does not exist on jQuery.maskMoney");
}
};
})(window.jQuery || window.Zepto);

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,31 @@
{
"name": "maskMoney",
"version": "3.1.1",
"title": "jQuery maskMoney",
"author": {
"name": "Diego Plentz",
"email": "diego@plentz.org",
"url": "http://plentz.org"
},
"licenses": [
{
"type": "MIT",
"url": "http://opensource.org/licenses/MIT"
}
],
"dependencies": {
"jquery": "latest"
},
"description": "jQuery plugin to mask data entry in the input text in the form of money (currency)",
"keywords": [
"form",
"input",
"mask",
"money"
],
"docs": "http://github.com/plentz/jquery-maskmoney",
"demo": "http://plentz.github.com/jquery-maskmoney",
"download": "https://raw.github.com/plentz/jquery-maskmoney/master/dist/jquery.maskMoney.min.js",
"bugs": "https://github.com/plentz/jquery-maskmoney/issues",
"homepage": "https://github.com/plentz/jquery-maskmoney"
}

View File

@@ -0,0 +1,49 @@
{
"name": "jquery-maskmoney",
"filename": "jquery.maskMoney.min.js",
"description": "jQuery plugin to mask data entry in the input text in the form of money (currency)",
"version": "3.1.1",
"homepage": "https://github.com/plentz/jquery-maskmoney",
"repository": {
"type": "git",
"url": "https://github.com/plentz/jquery-maskmoney.git"
},
"bugs": "https://github.com/plentz/jquery-maskmoney/issues",
"author": {
"name": "Diego Plentz",
"email": "diego@plentz.org",
"url": "http://plentz.org"
},
"dependencies": {
"jquery": "latest"
},
"engines": {
"node": ">=4"
},
"main": "dist/jquery.maskMoney.js",
"npmName": "jquery-maskmoney",
"npmFileMap": [
{
"basePath": "/dist/",
"files": [
"jquery.maskMoney.min.js"
]
}
],
"devDependencies": {
"amdefine": "latest",
"grunt": "latest",
"grunt-cli": "latest",
"grunt-contrib-concat": "latest",
"grunt-contrib-jshint": "latest",
"grunt-contrib-qunit": "latest",
"grunt-contrib-uglify": "latest",
"grunt-contrib-watch": "latest",
"grunt-jquerymanifest": "latest"
},
"license": "MIT",
"scripts": {
"test": "grunt test --verbose",
"build": "grunt"
}
}

View File

@@ -0,0 +1,591 @@
(function ($) {
"use strict";
if (!$.browser) {
$.browser = {};
$.browser.mozilla = /mozilla/.test(navigator.userAgent.toLowerCase()) && !/webkit/.test(navigator.userAgent.toLowerCase());
$.browser.webkit = /webkit/.test(navigator.userAgent.toLowerCase());
$.browser.opera = /opera/.test(navigator.userAgent.toLowerCase());
$.browser.msie = /msie/.test(navigator.userAgent.toLowerCase());
$.browser.device = /android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase());
}
var defaultOptions = {
prefix: "",
suffix: "",
affixesStay: true,
thousands: ",",
decimal: ".",
precision: 2,
allowZero: false,
allowNegative: false,
doubleClickSelection: true,
allowEmpty: false,
bringCaretAtEndOnFocus: true
},
methods = {
destroy: function () {
$(this).unbind(".maskMoney");
if ($.browser.msie) {
this.onpaste = null;
}
return this;
},
applyMask: function (value) {
var $input = $(this);
// data-* api
var settings = $input.data("settings");
return maskValue(value, settings);
},
mask: function (value) {
return this.each(function () {
var $this = $(this);
if (typeof value === "number") {
$this.val(value);
}
return $this.trigger("mask");
});
},
unmasked: function () {
return this.map(function () {
var value = ($(this).val() || "0"),
isNegative = value.indexOf("-") !== -1,
decimalPart;
// get the last position of the array that is a number(coercion makes "" to be evaluated as false)
$(value.split(/\D/).reverse()).each(function (index, element) {
if (element) {
decimalPart = element;
return false;
}
});
value = value.replace(/\D/g, "");
value = value.replace(new RegExp(decimalPart + "$"), "." + decimalPart);
if (isNegative) {
value = "-" + value;
}
return parseFloat(value);
});
},
unmaskedWithOptions: function () {
return this.map(function () {
var value = ($(this).val() || "0"),
settings = $(this).data("settings") || defaultOptions,
regExp = new RegExp((settings.thousandsForUnmasked || settings.thousands), "g");
value = value.replace(regExp, "");
return parseFloat(value);
});
},
init: function (parameters) {
// the default options should not be shared with others
parameters = $.extend($.extend({}, defaultOptions), parameters);
return this.each(function () {
var $input = $(this), settings,
onFocusValue;
// data-* api
settings = $.extend({}, parameters);
settings = $.extend(settings, $input.data());
// Store settings for use with the applyMask method.
$input.data("settings", settings);
function getInputSelection() {
var el = $input.get(0),
start = 0,
end = 0,
normalizedValue,
range,
textInputRange,
len,
endRange;
if (typeof el.selectionStart === "number" && typeof el.selectionEnd === "number") {
start = el.selectionStart;
end = el.selectionEnd;
} else {
range = document.selection.createRange();
if (range && range.parentElement() === el) {
len = el.value.length;
normalizedValue = el.value.replace(/\r\n/g, "\n");
// Create a working TextRange that lives only in the input
textInputRange = el.createTextRange();
textInputRange.moveToBookmark(range.getBookmark());
// Check if the start and end of the selection are at the very end
// of the input, since moveStart/moveEnd doesn't return what we want
// in those cases
endRange = el.createTextRange();
endRange.collapse(false);
if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
start = end = len;
} else {
start = -textInputRange.moveStart("character", -len);
start += normalizedValue.slice(0, start).split("\n").length - 1;
if (textInputRange.compareEndPoints("EndToEnd", endRange) > -1) {
end = len;
} else {
end = -textInputRange.moveEnd("character", -len);
end += normalizedValue.slice(0, end).split("\n").length - 1;
}
}
}
}
return {
start: start,
end: end
};
} // getInputSelection
function canInputMoreNumbers() {
var haventReachedMaxLength = !($input.val().length >= $input.attr("maxlength") && $input.attr("maxlength") >= 0),
selection = getInputSelection(),
start = selection.start,
end = selection.end,
haveNumberSelected = (selection.start !== selection.end && $input.val().substring(start, end).match(/\d/)) ? true : false,
startWithZero = ($input.val().substring(0, 1) === "0");
return haventReachedMaxLength || haveNumberSelected || startWithZero;
}
function setCursorPosition(pos) {
// Do not set the position if
// the we're formatting on blur.
// This is because we do not want
// to refocus on the control after
// the blur.
if (!!settings.formatOnBlur) {
return;
}
$input.each(function (index, elem) {
if (elem.setSelectionRange) {
elem.focus();
elem.setSelectionRange(pos, pos);
} else if (elem.createTextRange) {
var range = elem.createTextRange();
range.collapse(true);
range.moveEnd("character", pos);
range.moveStart("character", pos);
range.select();
}
});
}
function maskAndPosition(startPos) {
var originalLen = $input.val().length,
newLen;
$input.val(maskValue($input.val(), settings));
newLen = $input.val().length;
// If the we're using the reverse option,
// do not put the cursor at the end of
// the input. The reverse option allows
// the user to input text from left to right.
if (!settings.reverse) {
startPos = startPos - (originalLen - newLen);
}
setCursorPosition(startPos);
}
function mask() {
var value = $input.val();
if (settings.allowEmpty && value === "") {
return;
}
var isNumber = !isNaN(value);
var decimalPointIndex = isNumber? value.indexOf("."): value.indexOf(settings.decimal);
if (settings.precision > 0) {
if(decimalPointIndex < 0){
value += settings.decimal + new Array(settings.precision + 1).join(0);
}
else {
// If the following decimal part dosen't have enough length against the precision, it needs to be filled with zeros.
var integerPart = value.slice(0, decimalPointIndex),
decimalPart = value.slice(decimalPointIndex + 1);
value = integerPart + settings.decimal + decimalPart +
new Array((settings.precision + 1) - decimalPart.length).join(0);
}
} else if (decimalPointIndex > 0) {
// if the precision is 0, discard the decimal part
value = value.slice(0, decimalPointIndex);
}
$input.val(maskValue(value, settings));
}
function changeSign() {
var inputValue = $input.val();
if (settings.allowNegative) {
if (inputValue !== "" && inputValue.charAt(0) === "-") {
return inputValue.replace("-", "");
} else {
return "-" + inputValue;
}
} else {
return inputValue;
}
}
function preventDefault(e) {
if (e.preventDefault) { //standard browsers
e.preventDefault();
} else { // old internet explorer
e.returnValue = false;
}
}
function fixMobile() {
if ($.browser.device) {
$input.attr("type", "tel");
}
}
function keypressEvent(e) {
e = e || window.event;
var key = e.which || e.charCode || e.keyCode,
decimalKeyCode = settings.decimal.charCodeAt(0);
//added to handle an IE "special" event
if (key === undefined) {
return false;
}
// any key except the numbers 0-9. if we're using settings.reverse,
// allow the user to input the decimal key
if ((key < 48 || key > 57) && (key !== decimalKeyCode || !settings.reverse)) {
return handleAllKeysExceptNumericalDigits(key, e);
} else if (!canInputMoreNumbers()) {
return false;
} else {
if (key === decimalKeyCode && shouldPreventDecimalKey()) {
return false;
}
if (settings.formatOnBlur) {
return true;
}
preventDefault(e);
applyMask(e);
return false;
}
}
function shouldPreventDecimalKey() {
// If all text is selected, we can accept the decimal
// key because it will replace everything.
if (isAllTextSelected()) {
return false;
}
return alreadyContainsDecimal();
}
function isAllTextSelected() {
var length = $input.val().length;
var selection = getInputSelection();
// This should if all text is selected or if the
// input is empty.
return selection.start === 0 && selection.end === length;
}
function alreadyContainsDecimal() {
return $input.val().indexOf(settings.decimal) > -1;
}
function applyMask(e) {
e = e || window.event;
var key = e.which || e.charCode || e.keyCode,
keyPressedChar = "",
selection,
startPos,
endPos,
value;
if (key >= 48 && key <= 57) {
keyPressedChar = String.fromCharCode(key);
}
selection = getInputSelection();
startPos = selection.start;
endPos = selection.end;
value = $input.val();
$input.val(value.substring(0, startPos) + keyPressedChar + value.substring(endPos, value.length));
maskAndPosition(startPos + 1);
}
function handleAllKeysExceptNumericalDigits(key, e) {
// -(minus) key
if (key === 45) {
$input.val(changeSign());
return false;
// +(plus) key
} else if (key === 43) {
$input.val($input.val().replace("-", ""));
return false;
// enter key or tab key
} else if (key === 13 || key === 9) {
return true;
} else if ($.browser.mozilla && (key === 37 || key === 39) && e.charCode === 0) {
// needed for left arrow key or right arrow key with firefox
// the charCode part is to avoid allowing "%"(e.charCode 0, e.keyCode 37)
return true;
} else { // any other key with keycode less than 48 and greater than 57
preventDefault(e);
return true;
}
}
function keydownEvent(e) {
e = e || window.event;
var key = e.which || e.charCode || e.keyCode,
selection,
startPos,
endPos,
value,
lastNumber;
//needed to handle an IE "special" event
if (key === undefined) {
return false;
}
selection = getInputSelection();
startPos = selection.start;
endPos = selection.end;
if (key === 8 || key === 46 || key === 63272) { // backspace or delete key (with special case for safari)
preventDefault(e);
value = $input.val();
// not a selection
if (startPos === endPos) {
// backspace
if (key === 8) {
if (settings.suffix === "") {
startPos -= 1;
} else {
// needed to find the position of the last number to be erased
lastNumber = value.split("").reverse().join("").search(/\d/);
startPos = value.length - lastNumber - 1;
endPos = startPos + 1;
}
//delete
} else {
endPos += 1;
}
}
$input.val(value.substring(0, startPos) + value.substring(endPos, value.length));
maskAndPosition(startPos);
return false;
} else if (key === 9) { // tab key
return true;
} else { // any other key
return true;
}
}
function focusEvent() {
onFocusValue = $input.val();
mask();
var input = $input.get(0),
textRange;
if (!!settings.selectAllOnFocus) {
input.select();
} else if (input.createTextRange && settings.bringCaretAtEndOnFocus) {
textRange = input.createTextRange();
textRange.collapse(false); // set the cursor at the end of the input
textRange.select();
}
}
function cutPasteEvent() {
setTimeout(function () {
mask();
}, 0);
}
function getDefaultMask() {
var n = parseFloat("0") / Math.pow(10, settings.precision);
return (n.toFixed(settings.precision)).replace(new RegExp("\\.", "g"), settings.decimal);
}
function blurEvent(e) {
if ($.browser.msie) {
keypressEvent(e);
}
if (!!settings.formatOnBlur && $input.val() !== onFocusValue) {
applyMask(e);
}
if ($input.val() === "" && settings.allowEmpty) {
$input.val("");
} else if ($input.val() === "" || $input.val() === setSymbol(getDefaultMask(), settings)) {
if (!settings.allowZero) {
$input.val("");
} else if (!settings.affixesStay) {
$input.val(getDefaultMask());
} else {
$input.val(setSymbol(getDefaultMask(), settings));
}
} else {
if (!settings.affixesStay) {
var newValue = $input.val().replace(settings.prefix, "").replace(settings.suffix, "");
$input.val(newValue);
}
}
if ($input.val() !== onFocusValue) {
$input.change();
}
}
function clickEvent() {
var input = $input.get(0),
length;
if (!!settings.selectAllOnFocus) {
// selectAllOnFocus will be handled by
// the focus event. The focus event is
// also fired when the input is clicked.
return;
} else if (input.setSelectionRange && settings.bringCaretAtEndOnFocus) {
length = $input.val().length;
input.setSelectionRange(length, length);
} else {
$input.val($input.val());
}
}
function doubleClickEvent() {
var input = $input.get(0),
start,
length;
if (input.setSelectionRange && settings.bringCaretAtEndOnFocus) {
length = $input.val().length;
start = settings.doubleClickSelection ? 0 : length;
input.setSelectionRange(start, length);
} else {
$input.val($input.val());
}
}
fixMobile();
$input.unbind(".maskMoney");
$input.bind("keypress.maskMoney", keypressEvent);
$input.bind("keydown.maskMoney", keydownEvent);
$input.bind("blur.maskMoney", blurEvent);
$input.bind("focus.maskMoney", focusEvent);
$input.bind("click.maskMoney", clickEvent);
$input.bind("dblclick.maskMoney", doubleClickEvent);
$input.bind("cut.maskMoney", cutPasteEvent);
$input.bind("paste.maskMoney", cutPasteEvent);
$input.bind("mask.maskMoney", mask);
});
}
};
function setSymbol(value, settings) {
var operator = "";
if (value.indexOf("-") > -1) {
value = value.replace("-", "");
operator = "-";
}
if (value.indexOf(settings.prefix) > -1) {
value = value.replace(settings.prefix, "");
}
if (value.indexOf(settings.suffix) > -1) {
value = value.replace(settings.suffix, "");
}
return operator + settings.prefix + value + settings.suffix;
}
function maskValue(value, settings) {
if (settings.allowEmpty && value === "") {
return "";
}
if (!!settings.reverse) {
return maskValueReverse(value, settings);
}
return maskValueStandard(value, settings);
}
function maskValueStandard(value, settings) {
var negative = (value.indexOf("-") > -1 && settings.allowNegative) ? "-" : "",
onlyNumbers = value.replace(/[^0-9]/g, ""),
integerPart = onlyNumbers.slice(0, onlyNumbers.length - settings.precision),
newValue,
decimalPart,
leadingZeros;
newValue = buildIntegerPart(integerPart, negative, settings);
if (settings.precision > 0) {
if(!isNaN(value) && value.indexOf(".")){
var precision = value.substr(value.indexOf(".") + 1);
onlyNumbers += new Array((settings.precision + 1) - precision.length).join(0);
integerPart = onlyNumbers.slice(0, onlyNumbers.length - settings.precision);
newValue = buildIntegerPart(integerPart, negative, settings);
}
decimalPart = onlyNumbers.slice(onlyNumbers.length - settings.precision);
leadingZeros = new Array((settings.precision + 1) - decimalPart.length).join(0);
newValue += settings.decimal + leadingZeros + decimalPart;
}
return setSymbol(newValue, settings);
}
function maskValueReverse(value, settings) {
var negative = (value.indexOf("-") > -1 && settings.allowNegative) ? "-" : "",
valueWithoutSymbol = value.replace(settings.prefix, "").replace(settings.suffix, ""),
integerPart = valueWithoutSymbol.split(settings.decimal)[0],
newValue,
decimalPart = "";
if (integerPart === "") {
integerPart = "0";
}
newValue = buildIntegerPart(integerPart, negative, settings);
if (settings.precision > 0) {
var arr = valueWithoutSymbol.split(settings.decimal);
if (arr.length > 1) {
decimalPart = arr[1];
}
newValue += settings.decimal + decimalPart;
var rounded = Number.parseFloat((integerPart + "." + decimalPart)).toFixed(settings.precision);
var roundedDecimalPart = rounded.toString().split(settings.decimal)[1];
newValue = newValue.split(settings.decimal)[0] + "." + roundedDecimalPart;
}
return setSymbol(newValue, settings);
}
function buildIntegerPart(integerPart, negative, settings) {
// remove initial zeros
integerPart = integerPart.replace(/^0*/g, "");
// put settings.thousands every 3 chars
integerPart = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, settings.thousands);
if (integerPart === "") {
integerPart = "0";
}
return negative + integerPart;
}
$.fn.maskMoney = function (method) {
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof method === "object" || !method) {
return methods.init.apply(this, arguments);
} else {
$.error("Method " + method + " does not exist on jQuery.maskMoney");
}
};
})(window.jQuery || window.Zepto);

View File

@@ -0,0 +1,31 @@
"use strict";
module("change");
test("it calls the change event when the field's value is changed", function() {
var input = $("#input1").maskMoney(),
changeWasCalled = false;
input.change(function() {
changeWasCalled = true;
});
input.val("0.01");
input.trigger("focus");
keypress(input, 1);
input.trigger("blur");
ok(changeWasCalled, "change was called");
equal(input.val(), "0.11", "changed value");
});
test("it doesn't call the change event when the field's value is unchanged", function() {
var input = $("#input1").maskMoney(),
changeWasCalled = false;
input.change(function() {
changeWasCalled = true;
});
input.val("0.01");
input.trigger("focus");
input.trigger("blur");
ok(!changeWasCalled, "change was not called");
equal(input.val(), "0.01", "changed value");
});

View File

@@ -0,0 +1,27 @@
"use strict";
// stop()/start() is used when you have async tests. since we use setTimeout({}, 0)
// to call mask() inside cutPasteEvent function, we need to use them
module("cut & paste");
test("when cuting", function() {
stop();
var input = $("#input1").maskMoney();
input.val("12345678");
input.trigger("cut");
setTimeout( function() {
start();
equal(input.val(), "12,345,678.00", "format the value of the field");
}, 1);
});
test("when pasting", function() {
stop();
var input = $("#input1").maskMoney();
input.val("12345678");
input.trigger("paste");
setTimeout( function() {
start();
equal(input.val(), "12,345,678.00", "format the value of the field");
}, 1);
});

View File

@@ -0,0 +1,27 @@
"use strict";
module("data-dash api");
test("with field configured using data-* attributes", function() {
var input = $("#input3").maskMoney();
input.val("12345678");
input.trigger("focus");
equal(input.val(), "R$12.345.678,00", "configure maskMoney using data-* attributes");
});
test("configuring a setting that isn't a single word", function() {
var input = $("#input3");
input.attr("data-allow-zero", "true");
input.maskMoney();
input.val("0");
input.trigger("mask");
equal(input.val(), "R$0,00", "it works by using dashes-pattern instead of camelCase");
});
test("allow to configure multiple fields using data-* attributes", function() {
var input = $(".multiple-dash").maskMoney();
input.val("12345678");
input.trigger("focus");
equal($("#input3").val(), "R$12.345.678,00", "configure maskMoney using data-* attributes");
equal($("#input4").val(), "U$12,345,678.00", "configure maskMoney using data-* attributes");
});

View File

@@ -0,0 +1,17 @@
"use strict";
module("empty");
test("allow empty inputs", function() {
var input = $("#input1").maskMoney({ precision: 2, allowEmpty: true });
input.val("");
input.trigger("focus");
equal(input.val(), "", "allow empty inputs");
});
test("don't allow empty inputs", function() {
var input = $("#input1").maskMoney({ precision: 2, allowEmpty: false });
input.val("");
input.trigger("focus");
equal(input.val(), "0.00", "don't allow empty inputs");
});

View File

@@ -0,0 +1,9 @@
"use strict";
module("focus");
test("with default mask", function() {
var input = $("#input1").maskMoney();
input.val("12345678");
input.trigger("focus");
equal(input.val(), "12,345,678.00", "format the value of the field on focus");
});

View File

@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>jQuery maskMoney Test Suite</title>
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.23.1.css">
<script src="../bower_components/jquery/dist/jquery.min.js"></script>
<script src="http://code.jquery.com/qunit/qunit-1.23.1.js"></script>
<script src="../src/jquery.maskMoney.js"></script>
<script src="util.js"></script>
<script src="init_and_destroy_test.js"></script>
<script src="mask_test.js"></script>
<script src="data_dash_test.js"></script>
<script src="unmasked_test.js"></script>
<script src="focus_test.js"></script>
<script src="change_test.js"></script>
<script src="typing_test.js"></script>
<script src="cut_paste_test.js"></script>
<script src="selection_test.js"></script>
<script src="empty_test.js"></script>
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture">
<input type="text" id="input1" class="all"/>
<input type="text" id="input2" class="all"/>
<input type="text" class="multiple-dash" id="input3" data-prefix="R$" data-thousands="." data-decimal=","/>
<input type="text" class="multiple-dash" id="input4" data-prefix="U$" data-thousands="," data-decimal="."/>
</div>
</body>
</html>

View File

@@ -0,0 +1,26 @@
"use strict";
test("chainable", function() {
ok($("#input1").maskMoney().val("123"), "can be chained");
equal($("#input1").val(), "123", "class was added correctly from chaining");
});
test("init", function() {
var input = $("#input1").maskMoney(),
events;
events = jQuery._data(input.get(0), "events");
ok(events.blur, "attached the blur event");
ok(events.keypress, "attached the keypress event");
ok(events.keydown, "attached the keydown event");
ok(events.focus, "attached the focus event");
ok(events.click, "attached the click event");
});
test("destroy", function() {
var input = $("#input1").maskMoney(),
events;
input.maskMoney("destroy");
events = jQuery._data(input.get(0), "events");
equal(events, undefined, "destroy method removed all attached events");
});

View File

@@ -0,0 +1,82 @@
"use strict";
module("mask");
test("when triggered in a empty field", function() {
var input = $("#input1").maskMoney();
input.val("");
input.maskMoney("mask");
equal(input.val(), "0.00", "set zero as the value");
});
test("with a lot of leading zeros", function() {
var input = $("#input1").maskMoney();
input.val("000000000123");
input.maskMoney("mask");
equal(input.val(), "123.00", "removes the unecessary zeroes");
});
QUnit.skip("with a pre-formatted number", function() {
var input = $("#input1").maskMoney();
input.val("123,45");
input.maskMoney("mask");
equal(input.val(), "123.45", "keeps the number precision");
});
QUnit.skip("with a pre-formatted number smaller than the set precision", function() {
var input = $("#input1").maskMoney();
input.val("123,4");
input.maskMoney("mask");
equal(input.val(), "123.40", "keeps the number precision");
});
test("with negative symbol and a field that doesn't allow negative ", function() {
var input = $("#input1").maskMoney({allowNegative: false});
input.val("-123");
input.maskMoney("mask");
equal(input.val(), "123.00", "removes negative symbol");
});
QUnit.skip("with a number as parameter", function() {
var input = $("#input1").maskMoney();
input.maskMoney("mask", 123456.70);
equal(input.val(), "123,456.70");
});
test("with a number as parameter", function() {
var input = $("#input1").maskMoney({ precision: 0 });
input.maskMoney("mask", 1000);
equal(input.val(), "1,000");
});
test("with a decimal number as parameter", function() {
var input = $("#input1").maskMoney();
input.maskMoney("mask", 1.1);
equal(input.val(), "1.10");
});
test("with a decimal number as parameter and different symbol", function() {
var input = $("#input1").maskMoney({thousands: ".", decimal: ","});
input.maskMoney("mask", 2001.1);
equal(input.val(), "2.001,10");
});
test("without a decimal number as parameter and different symbol", function() {
var input = $("#input1").maskMoney({thousands: ".", decimal: ","});
input.maskMoney("mask", 2001);
equal(input.val(), "2.001,00");
});
test("with a negative number as parameter", function() {
var input = $("#input1").maskMoney({allowNegative: true});
input.maskMoney("mask", -123456.78);
equal(input.val(), "-123,456.78");
});
test("with a suffix", function() {
var input = $("#input1").maskMoney({suffix: " €"});
input.maskMoney("mask", 20316.22);
equal(input.val(), "20,316.22 €");
});

View File

@@ -0,0 +1,19 @@
"use strict";
module("double click selection");
test("when double clicking", function() {
var input = $("#input1").maskMoney();
input.val("123.45");
input.maskMoney("mask");
input.trigger("dblclick");
equal(input.val(), "123.45", "the content does not change");
});
test("when double clicking and hitting delete", function() {
var input = $("#input1").maskMoney();
input.val("12345");
input.maskMoney("mask");
input.trigger("dblclick");
keydown(input, "backspace");
equal(input.val(), "0.00", "all the content is cleared");
});

View File

@@ -0,0 +1,36 @@
"use strict";
module("typing");
test("accepts keys in sequence", function() {
var input = $("#input1").maskMoney();
input.trigger("focus");
keypress(input, 1);
keypress(input, 2);
keypress(input, 3);
keypress(input, 4);
keypress(input, 5);
keypress(input, 6);
equal(input.val(), "1,234.56", "accept the input and format correctly");
});
test("with a suffix", function() {
var input = $("#input1").maskMoney({suffix: " €"});
input.trigger("focus");
keypress(input, 1);
keypress(input, 2);
keypress(input, 3);
keypress(input, 4);
keypress(input, 5);
equal(input.val(), "123.45 €", "accept the input and format correctly");
});
test("with a pre-set value", function() {
var input = $("#input1").maskMoney();
input.val("1");
input.trigger("focus");
keypress(input, 2);
equal(input.val(), "10.02", "accept the input and format correctly");
});

View File

@@ -0,0 +1,68 @@
"use strict";
module("unmasked");
test("with prefix", function() {
var input = $("#input1"),
unmasked;
input.val("+ 123.456,78");
unmasked = input.maskMoney("unmasked")[0];
equal(unmasked, 123456.78, "unmask method return the correct number when the field value has prefix");
});
test("with suffix", function() {
var input = $("#input1"),
unmasked;
input.val("123.456,78 €");
unmasked = input.maskMoney("unmasked")[0];
equal(unmasked, 123456.78, "unmask method return the correct number when the field value has suffix");
});
test("with prefix and suffix", function() {
var input = $("#input1"),
unmasked;
input.val("+ 123.456,78 €");
unmasked = input.maskMoney("unmasked")[0];
equal(unmasked, 123456.78, "unmask method return the correct number when the field value has prefix and suffix");
});
test("with negative number", function() {
var input = $("#input1"),
unmasked;
input.val("-R$ 123.456,78");
unmasked = input.maskMoney("unmasked")[0];
equal(unmasked, -123456.78, "unmask method return the correct number when the field value has prefix and suffix");
});
test("with collection of fields", function() {
var input = $(".all"),
unmaskedCollection;
$("#input1").val("+ 123.456,78 €");
$("#input2").val("R$ 876.543,21");
unmaskedCollection = input.maskMoney("unmasked").get();
deepEqual(unmaskedCollection, [123456.78, 876543.21], "unmask method return the correct number when the field value has prefix and suffix");
});
test("without options", function() {
var input = $("#input1"),
unmasked;
input.val("123,456");
unmasked = input.maskMoney("unmaskedWithOptions")[0];
equal(unmasked, 123456, "unmask method return the correct number even when options are not passed");
});
test("with decimal part", function() {
var input = $("#input1"),
unmasked;
input.val("123,456.01");
unmasked = input.maskMoney("unmaskedWithOptions")[0];
equal(unmasked, 123456.01, "unmask method return the correct number when the field value has a decimal part");
});
test("with options specified", function() {
var input = $("#input1"),
unmasked;
input.val("123.456");
input.maskMoney({ thousandsForUnmasked : "\\.", thousands:"." });
unmasked = input.maskMoney("unmaskedWithOptions")[0];
equal(unmasked, 123456, "unmask method return the correct number when options are set");
});

View File

@@ -0,0 +1,26 @@
"use strict";
var KEY_TO_KEYCODE_MAP = {
0: 48, 1: 49,
2: 50, 3: 51,
4: 52, 5: 53,
6: 54, 7: 55,
8: 56, 9: 57,
"shift": 16, "ctrl": 17, "alt": 18,
"backspace": 8, "tab": 9,
"enter": 13, "esc": 27, "space": 32,
"left": 37, "up": 38,
"right": 39, "down": 40,
"delete": 46,
"home": 36, "end": 35,
",": 188, ".": 190,
"-": 189, "=": 187,
};
function keypress(input, key) {
input.trigger($.Event("keypress", { keyCode: KEY_TO_KEYCODE_MAP[key] } ));
}
function keydown(input, key) {
input.trigger($.Event("keydown", { keyCode: KEY_TO_KEYCODE_MAP[key] } ));
}