Last active
July 17, 2018 21:45
-
-
Save stephenharris/69138960a45a48549c4d67f66b379c42 to your computer and use it in GitHub Desktop.
Formats currency input and provides a method from extracting the amount (in fractional currency units - i.e. in cents/pennies) http://jsfiddle.net/7g26x0uL/155/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$.widget( "nmk.currencyField", { | |
// Default options. | |
options: { | |
decimalPlaces: 2, | |
decimalSeperator: ".", | |
thousandSeperator: ",", | |
}, | |
_create: function() { | |
if(this.options.decimalSeperator === this.options.thousandSeperator){ | |
this.options.thousandSeperator = null; | |
} | |
if(this.options.decimalPlaces === 0){ | |
this.options.decimalSeperator = null; | |
} | |
this.element.on('keydown', $.proxy(function(evt){ | |
var char = evt.key; | |
var value = $(evt.target).val(); | |
if ( | |
// ALlow delete, backspace, tab, escape, enter and workaround for Samsung | |
$.inArray(evt.which, [46, 8, 9, 27, 13, 229]) !== -1 || | |
// Allow: Ctrl+A/V/X, Command+A/V/X | |
($.inArray(evt.which, [65, 86, 88]) && (evt.ctrlKey === true || evt.metaKey === true)) || | |
// Allow: home, end, left, right, down, up | |
(evt.which >= 35 && evt.which <= 40) || | |
// Allow thousand seperator | |
(this.options.thousandSeperator && char === this.options.thousandSeperator)) { | |
return; | |
} | |
if(char === this.options.decimalSeperator){ | |
return value.indexOf(this.options.decimalSeperator) === -1; | |
} | |
// Abort if not a number | |
if ((evt.shiftKey || (evt.keyCode < 48 || evt.keyCode > 57)) && (evt.keyCode < 96 || evt.keyCode > 105)) { | |
evt.preventDefault(); | |
} | |
// Ensure the maximum number of decimal places is not exceeded | |
var caratPos = evt.target.selectionStart; | |
var dotPos = value.indexOf(this.options.decimalSeperator); | |
var parts = value.split(this.options.decimalSeperator); | |
if( caratPos > dotPos && dotPos > -1 && (parts[1].length > this.options.decimalPlaces - 1)){ | |
return false; | |
} | |
},this)); | |
this.element.on('paste', $.proxy(function(event){ | |
event.preventDefault(); | |
var value = event.originalEvent.clipboardData.getData('text/plain'); | |
this.element.val(this._formatAmount(this._parseAmount(value))); | |
},this)); | |
this.element.on('blur', $.proxy(function(){ | |
this.element.val(this.formattedAmount(this.getAmount())); | |
},this)); | |
}, | |
getAmount: function(){ | |
return this._parseAmount(this.element.val()); | |
}, | |
formattedAmount: function(){ | |
return this._formatAmount(this.getAmount()); | |
}, | |
_parseAmount: function(value){ | |
if(!value){ | |
return 0; | |
} | |
var numeric = value.replace(new RegExp('[^0-9'+this.options.decimalSeperator+']','g'), ''); | |
var regex = new RegExp('^(\\d+(?:'+this.options.decimalSeperator+'\\d{0,'+this.options.decimalPlaces+'})?).*$','g'); | |
var parts = numeric.replace(regex,"$1").split(this.options.decimalSeperator); | |
var integer = parseInt(parts[0],10) * Math.pow(10, this.options.decimalPlaces); | |
if(parts.length > 1){ | |
integer += parseInt(this._pad(parts[1],this.options.decimalPlaces, 'right').slice(0, this.options.decimalPlaces),10); | |
} | |
return integer; | |
}, | |
_formatAmount: function(amountInFractionalUnits){ | |
var parts; | |
if(this.options.decimalPlaces){ | |
var regex = new RegExp('^(\\d+)(\\d{'+this.options.decimalPlaces+'})$'); | |
var parts = this._pad(amountInFractionalUnits, this.options.decimalPlaces + 1, 'left') | |
.replace(regex,"$1"+this.options.decimalSeperator+"$2") | |
.split(this.options.decimalSeperator); | |
} else { | |
parts = [amountInFractionalUnits]; | |
} | |
var rgx = /(\d+)(\d{3})/; | |
while (rgx.test(parts[0])) { | |
parts[0] = parts[0].replace(rgx, '$1' + this.options.thousandSeperator + '$2'); | |
} | |
return this.options.decimalSeperator && parts.length > 1 ? parts[0] + this.options.decimalSeperator + parts[1] : parts[0]; | |
}, | |
_pad: function(string, length, type){ | |
var n = length - (""+string).length; | |
if(n > 0) { | |
var padding = (new Array(n+1).join("0")); | |
string = type === 'left' ? padding + string : string + padding; | |
} | |
return string+""; | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<input data-thousand="," data-decimal="." data-decimalplaces="2" id="input" type="text"/> | |
<p id="render"></p> | |
<p id="render2"></p> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$('#input').currencyField({ | |
decimalPlaces: $('#input').data('decimalplaces'), | |
decimalSeperator: $('#input').data('decimalseperator'), | |
thousandSeperator: $('#input').data('thousandseperator') | |
}); | |
$('#input').on('change blur', function(event){ | |
$('#render').text($(this).currencyField('getAmount')); | |
$('#render2').text($(this).currencyField('formattedAmount')); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment