diff --git a/README.md b/README.md index 59aae34..2ec72c3 100644 --- a/README.md +++ b/README.md @@ -1,63 +1,65 @@ -Just a simple way to create masks to your currency form fields with [jQuery](http://jquery.com/). - -*** -### Show Time! - -To view a complete demonstration of it's features and usage, access our [examples page](http://plentz.org/maskmoney)! - -*** -### Usage: -``` html - - - - - - - - -``` - -*** -### Options: - -The options that you can set are: - - * symbol: the symbol to be used before of the user values. default: 'US$' - * showSymbol: set if the symbol must be displayed or not. default: false - * symbolStay: set if the symbol will stay in the field after the user exists the field. default: false - * thousands: the thousands separator. default: ',' - * decimal: the decimal separator. default: '.' - * precision: how many decimal places are allowed. default: 2 - * defaultZero: when the user enters the field, it sets a default mask using zero. default: true - * 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 - -*** -### Bonus! - -We have 2 bonus methods that can be useful to you: - - * .unmaskMoney() which removes maskMoney from an element. - * .mask() which causes maskMoney to actually apply the mask to your input. - -*** -### Contributors: - - * [Aurélio Saraiva](mailto:aureliosaraiva@gmail.com) - * [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) - -*** -### License: - +Just a simple way to create masks to your currency form fields with [jQuery](http://jquery.com/). + +*** +### Show Time! + +To view a complete demonstration of it's features and usage, access our [examples page](http://plentz.org/maskmoney)! + +*** +### Usage: +``` html + + + + + + + + +``` + +*** +### Options: + +The options that you can set are: + + * symbol: the symbol to be used before of the user values. default: 'US$' + * showSymbol: set if the symbol must be displayed or not. default: false + * symbolStay: set if the symbol will stay in the field after the user exists the field. default: false + * thousands: the thousands separator. default: ',' + * decimal: the decimal separator. default: '.' + * precision: how many decimal places are allowed. default: 2 + * defaultZero: when the user enters the field, it sets a default mask using zero. default: true + * 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 + * symbolLocation: use this setting to position the symbol at the left or right hand side of the value ('left'/'right') + +*** +### Bonus! + +We have 2 bonus methods that can be useful to you: + + * .unmaskMoney() which removes maskMoney from an element. + * .mask() which causes maskMoney to actually apply the mask to your input. + +*** +### Contributors: + + * [Aurélio Saraiva](mailto:aureliosaraiva@gmail.com) + * [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) + * [André Silva] (http://github.com/cattox) + +*** +### License: + __jQuery-maskMoney__ is released under the MIT license. \ No newline at end of file diff --git a/jquery.maskMoney.js b/jquery.maskMoney.js index 5d5c786..fe9beff 100644 --- a/jquery.maskMoney.js +++ b/jquery.maskMoney.js @@ -1,354 +1,362 @@ -/* -* @Copyright (c) 2011 Aurélio Saraiva, Diego Plentz -* @Page http://github.com/plentz/jquery-maskmoney -* try at http://plentz.org/maskmoney - -* 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. -*/ - -/* -* @Version: 1.4.1 -* @Release: 2011-11-01 -*/ -;(function($) { - $.fn.maskMoney = function(settings) { - settings = $.extend({ - symbol: 'US$', - showSymbol: false, - symbolStay: false, - thousands: ',', - decimal: '.', - precision: 2, - defaultZero: true, - allowZero: false, - allowNegative: false - }, settings); - - return this.each(function() { - var input = $(this); - var dirty = false; - - function markAsDirty() { - dirty = true; - } - - function clearDirt(){ - dirty = false; - } - - function keypressEvent(e) { - e = e||window.event; - var k = e.charCode||e.keyCode||e.which; - if (k == undefined) return false; //needed to handle an IE "special" event - if (input.attr('readonly') && (k!=13&&k!=9)) return false; // don't allow editing of readonly fields but allow tab/enter - - if (k<48||k>57) { // any key except the numbers 0-9 - if (k==45) { // -(minus) key - markAsDirty(); - input.val(changeSign(input)); - return false; - } else if (k==43) { // +(plus) key - markAsDirty(); - input.val(input.val().replace('-','')); - return false; - } else if (k==13||k==9) { // enter key or tab key - if(dirty){ - clearDirt(); - $(this).change(); - } - return true; - } else if (k==37||k==39) { // left arrow key or right arrow key - return true; - } else { // any other key with keycode less than 48 and greater than 57 - preventDefault(e); - return true; - } - } else if (input.val().length>=input.attr('maxlength')) { - return false; - } else { - preventDefault(e); - - var key = String.fromCharCode(k); - var x = input.get(0); - var selection = input.getInputSelection(x); - var startPos = selection.start; - var endPos = selection.end; - x.value = x.value.substring(0, startPos) + key + x.value.substring(endPos, x.value.length); - maskAndPosition(x, startPos + 1); - markAsDirty(); - return false; - } - } - - function keydownEvent(e) { - e = e||window.event; - var k = e.charCode||e.keyCode||e.which; - if (k == undefined) return false; //needed to handle an IE "special" event - if (input.attr('readonly') && (k!=13&&k!=9)) return false; // don't allow editing of readonly fields but allow tab/enter - - var x = input.get(0); - var selection = input.getInputSelection(x); - var startPos = selection.start; - var endPos = selection.end; - - if (k==8) { // backspace key - preventDefault(e); - - if(startPos == endPos){ - // Remove single character - x.value = x.value.substring(0, startPos - 1) + x.value.substring(endPos, x.value.length); - startPos = startPos - 1; - } else { - // Remove multiple characters - x.value = x.value.substring(0, startPos) + x.value.substring(endPos, x.value.length); - } - maskAndPosition(x, startPos); - markAsDirty(); - return false; - } else if (k==9) { // tab key - if(dirty) { - $(this).change(); - clearDirt(); - } - return true; - } else if (k==46||k==63272) { // delete key (with special case for safari) - preventDefault(e); - if(x.selectionStart == x.selectionEnd){ - // Remove single character - x.value = x.value.substring(0, startPos) + x.value.substring(endPos + 1, x.value.length); - } else { - //Remove multiple characters - x.value = x.value.substring(0, startPos) + x.value.substring(endPos, x.value.length); - } - maskAndPosition(x, startPos); - markAsDirty(); - return false; - } else { // any other key - return true; - } - } - - function focusEvent(e) { - var mask = getDefaultMask(); - if (input.val()==mask) { - input.val(''); - } else if (input.val()==''&&settings.defaultZero) { - input.val(setSymbol(mask)); - } else { - input.val(setSymbol(input.val())); - } - if (this.createTextRange) { - var textRange = this.createTextRange(); - textRange.collapse(false); // set the cursor at the end of the input - textRange.select(); - } - } - - function blurEvent(e) { - if ($.browser.msie) { - keypressEvent(e); - } - - if (input.val()==''||input.val()==setSymbol(getDefaultMask())||input.val()==settings.symbol) { - if(!settings.allowZero) input.val(''); - else if (!settings.symbolStay) input.val(getDefaultMask()); - else input.val(setSymbol(getDefaultMask())); - } else { - if (!settings.symbolStay) input.val(input.val().replace(settings.symbol,'')); - else if (settings.symbolStay&&input.val()==settings.symbol) input.val(setSymbol(getDefaultMask())); - } - } - - function preventDefault(e) { - if (e.preventDefault) { //standard browsers - e.preventDefault(); - } else { // internet explorer - e.returnValue = false - } - } - - function maskAndPosition(x, startPos) { - var originalLen = input.val().length; - input.val(maskValue(x.value)); - var newLen = input.val().length; - startPos = startPos - (originalLen - newLen); - input.setCursorPosition(startPos); - } - - function maskValue(v) { - v = v.replace(settings.symbol,''); - - var strCheck = '0123456789'; - var len = v.length; - var a = '', t = '', neg=''; - - if(len!=0 && v.charAt(0)=='-'){ - v = v.replace('-',''); - if(settings.allowNegative){ - neg = '-'; - } - } - - if (len==0) { - if (!settings.defaultZero) return t; - t = '0.00'; - } - - for (var i = 0; i=1;) { - t = t.substr(0,p)+settings.thousands+t.substr(p); - } - - return (settings.precision>0) - ? setSymbol(neg+t+settings.decimal+d+Array((settings.precision+1)-d.length).join(0)) - : setSymbol(neg+t); - } - - function mask() { - var value = input.val(); - input.val(maskValue(value)); - } - - function getDefaultMask() { - var n = parseFloat('0')/Math.pow(10,settings.precision); - return (n.toFixed(settings.precision)).replace(new RegExp('\\.','g'),settings.decimal); - } - - function setSymbol(v) { - if (settings.showSymbol) { - if (v.substr(0, settings.symbol.length) != settings.symbol) return settings.symbol+v; - } - return v; - } - - function changeSign(i){ - if (settings.allowNegative) { - var vic = i.val(); - if (i.val()!='' && i.val().charAt(0)=='-'){ - return i.val().replace('-',''); - } else{ - return '-'+i.val(); - } - } else { - return i.val(); - } - } - - input.bind('keypress.maskMoney',keypressEvent); - input.bind('keydown.maskMoney',keydownEvent); - input.bind('blur.maskMoney',blurEvent); - input.bind('focus.maskMoney',focusEvent); - input.bind('mask', mask); - - input.one('unmaskMoney',function() { - input.unbind('.maskMoney'); - - if ($.browser.msie) { - this.onpaste= null; - } else if ($.browser.mozilla) { - this.removeEventListener('input',blurEvent,false); - } - }); - }); - } - - $.fn.unmaskMoney=function() { - return this.trigger('unmaskMoney'); - }; - - $.fn.mask=function() { - return this.trigger('mask'); - }; - - $.fn.setCursorPosition = function(pos) { - this.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(); - } - }); - return this; - }; - - $.fn.getInputSelection = function(el) { - var 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 - }; - } -})(jQuery); +/* +* @Copyright (c) 2011 Aurélio Saraiva, Diego Plentz +* @Page http://github.com/plentz/jquery-maskmoney +* try at http://plentz.org/maskmoney + +* 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. +*/ + +/* +* @Version: 1.4.1 +* @Release: 2011-11-01 +*/ + +;(function($) { + $.fn.maskMoney = function(settings) { + settings = $.extend({ + symbol: 'US$', + showSymbol: false, + symbolStay: false, + thousands: ',', + decimal: '.', + precision: 2, + defaultZero: true, + allowZero: false, + allowNegative: false, + symbolLocation: 'right' + }, settings); + + return this.each(function() { + var input = $(this); + var dirty = false; + + function markAsDirty() { + dirty = true; + } + + function clearDirt(){ + dirty = false; + } + + function keypressEvent(e) { + e = e||window.event; + var k = e.charCode||e.keyCode||e.which; + if (k == undefined) return false; //needed to handle an IE "special" event + if (input.attr('readonly') && (k!=13&&k!=9)) return false; // don't allow editing of readonly fields but allow tab/enter + + if (k<48||k>57) { // any key except the numbers 0-9 + if (k==45) { // -(minus) key + markAsDirty(); + input.val(changeSign(input)); + return false; + } else if (k==43) { // +(plus) key + markAsDirty(); + input.val(input.val().replace('-','')); + return false; + } else if (k==13||k==9) { // enter key or tab key + if(dirty){ + clearDirt(); + $(this).change(); + } + return true; + } else if (k==37||k==39) { // left arrow key or right arrow key + return true; + } else { // any other key with keycode less than 48 and greater than 57 + preventDefault(e); + return true; + } + } else if (input.val().length>=input.attr('maxlength')) { + return false; + } else { + preventDefault(e); + + var key = String.fromCharCode(k); + var x = input.get(0); + var selection = input.getInputSelection(x); + var startPos = selection.start; + var endPos = selection.end; + x.value = x.value.substring(0, startPos) + key + x.value.substring(endPos, x.value.length); + maskAndPosition(x, startPos + 1); + markAsDirty(); + return false; + } + } + + function keydownEvent(e) { + e = e||window.event; + var k = e.charCode||e.keyCode||e.which; + if (k == undefined) return false; //needed to handle an IE "special" event + if (input.attr('readonly') && (k!=13&&k!=9)) return false; // don't allow editing of readonly fields but allow tab/enter + + var x = input.get(0); + var selection = input.getInputSelection(x); + var startPos = selection.start; + var endPos = selection.end; + + if (k==8) { // backspace key + preventDefault(e); + + if(startPos == endPos){ + // Remove single character + x.value = x.value.substring(0, startPos - 1) + x.value.substring(endPos, x.value.length); + startPos = startPos - 1; + } else { + // Remove multiple characters + x.value = x.value.substring(0, startPos) + x.value.substring(endPos, x.value.length); + } + maskAndPosition(x, startPos); + markAsDirty(); + return false; + } else if (k==9) { // tab key + if(dirty) { + $(this).change(); + clearDirt(); + } + return true; + } else if (k==46||k==63272) { // delete key (with special case for safari) + preventDefault(e); + if(x.selectionStart == x.selectionEnd){ + // Remove single character + x.value = x.value.substring(0, startPos) + x.value.substring(endPos + 1, x.value.length); + } else { + //Remove multiple characters + x.value = x.value.substring(0, startPos) + x.value.substring(endPos, x.value.length); + } + maskAndPosition(x, startPos); + markAsDirty(); + return false; + } else { // any other key + return true; + } + } + + function focusEvent(e) { + var mask = getDefaultMask(); + if (input.val()==mask) { + input.val(''); + } else if (input.val()==''&&settings.defaultZero) { + input.val(setSymbol(mask)); + } else { + input.val(setSymbol(input.val())); + } + if (this.createTextRange) { + var textRange = this.createTextRange(); + textRange.collapse(false); // set the cursor at the end of the input + textRange.select(); + } + } + + function blurEvent(e) { + if ($.browser.msie) { + keypressEvent(e); + } + + if (input.val()==''||input.val()==setSymbol(getDefaultMask())||input.val()==settings.symbol) { + if(!settings.allowZero) input.val(''); + else if (!settings.symbolStay) input.val(getDefaultMask()); + else input.val(setSymbol(getDefaultMask())); + } else { + if (!settings.symbolStay) input.val(input.val().replace(settings.symbol,'')); + else if (settings.symbolStay&&input.val()==settings.symbol) input.val(setSymbol(getDefaultMask())); + } + } + + function preventDefault(e) { + if (e.preventDefault) { //standard browsers + e.preventDefault(); + } else { // internet explorer + e.returnValue = false + } + } + + function maskAndPosition(x, startPos) { + var originalLen = input.val().length; + input.val(maskValue(x.value)); + var newLen = input.val().length; + startPos = startPos - (originalLen - newLen); + input.setCursorPosition(startPos); + } + + function maskValue(v) { + v = v.replace(settings.symbol,''); + + var strCheck = '0123456789'; + var len = v.length; + var a = '', t = '', neg=''; + + if(len!=0 && v.charAt(0)=='-'){ + v = v.replace('-',''); + if(settings.allowNegative){ + neg = '-'; + } + } + + if (len==0) { + if (!settings.defaultZero) return t; + t = '0.00'; + } + + for (var i = 0; i=1;) { + t = t.substr(0,p)+settings.thousands+t.substr(p); + } + + return (settings.precision>0) + ? setSymbol(neg+t+settings.decimal+d+Array((settings.precision+1)-d.length).join(0)) + : setSymbol(neg+t); + } + + function mask() { + var value = input.val(); + input.val(maskValue(value)); + } + + function getDefaultMask() { + var n = parseFloat('0')/Math.pow(10,settings.precision); + return (n.toFixed(settings.precision)).replace(new RegExp('\\.','g'),settings.decimal); + } + + function setSymbol(v) { + if (settings.showSymbol) { + if (v.substr(0, settings.symbol.length) != settings.symbol && v.substr(v.length-settings.symbol.length, v.length) != settings.symbol){ + if(settings.symbolLocation == "left"){ + return settings.symbol+v; + } else { + return v+settings.symbol; + } + } + } + return v; + } + + function changeSign(i){ + if (settings.allowNegative) { + var vic = i.val(); + if (i.val()!='' && i.val().charAt(0)=='-'){ + return i.val().replace('-',''); + } else{ + return '-'+i.val(); + } + } else { + return i.val(); + } + } + + input.bind('keypress.maskMoney',keypressEvent); + input.bind('keydown.maskMoney',keydownEvent); + input.bind('blur.maskMoney',blurEvent); + input.bind('focus.maskMoney',focusEvent); + input.bind('mask', mask); + + input.one('unmaskMoney',function() { + input.unbind('.maskMoney'); + + if ($.browser.msie) { + this.onpaste= null; + } else if ($.browser.mozilla) { + this.removeEventListener('input',blurEvent,false); + } + }); + }); + } + + $.fn.unmaskMoney=function() { + return this.trigger('unmaskMoney'); + }; + + $.fn.mask=function() { + return this.trigger('mask'); + }; + + $.fn.setCursorPosition = function(pos) { + this.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(); + } + }); + return this; + }; + + $.fn.getInputSelection = function(el) { + var 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 + }; + } +})(jQuery); \ No newline at end of file