/* * jQuery Numeric Input - v0.2.2 - 2016-04-13 * https://github.com/manuelvanrijn/jquery-numeric_input * Copyright (c) 2016 Manuel van Rijn * Licensed MIT, GPL */ ;(function( $, window, document, undefined ) { var NumericInput = function( elem, options ) { this.elem = elem; this.$elem = $(elem); this.options = options; }; NumericInput.prototype = { init: function() { // set instance variable var _instance = this; _instance.ctrlDown = false; _instance.options = $.extend({}, $.fn.numeric_input.defaults, _instance.options); // bind the keypress event _instance.$elem.keypress(function( e ) { if( _instance.preventDefaultForKeyCode(e.which) === true) { e.preventDefault(); } var newValue = _instance.getNewValueForKeyCode( e.which, _instance.$elem.val(), this.selectionStart ); if( newValue !== false) { _instance.$elem.val( newValue ); _instance.options.callback.call(_instance, newValue); } }); if( _instance.options.parseOnBlur === true ) { // bind the blur event to (re)parse value _instance.$elem.on('blur', function( e ) { var parsedValue = _instance.parseValue( _instance.$elem.val() ); _instance.$elem.val( parsedValue ); }); } if( _instance.options.clearInputOnBlurForZeroValue === true ) { _instance.$elem.on('focus', function( e ) { var result = _instance.$elem.val(); result = result.replace(/[A-Za-z$]/g, ''); result = result.replace( '-', '' ); result = result.replace( _instance.options.decimal, '.' ); if( parseFloat(result) === 0 ) { _instance.$elem.val( '' ); } }); } // trigger callback on change _instance.$elem.on('input propertychange', function(){ var parsedValue = _instance.parseValue( _instance.$elem.val() ); _instance.options.callback.call(_instance, parsedValue); }); // initial parse values if( _instance.options.initialParse === true ) { var parsedValue = _instance.parseValue( _instance.$elem.val() ); _instance.$elem.val( parsedValue ); } // event for checking ctrl/cmd var ctrlKey = 17; var cmdKey = 91; $(document).keydown(function(e) { // ctrl or command key if (e.keyCode === ctrlKey || e.keyCode === cmdKey) { _instance.ctrlDown = true; } }).keyup(function(e) { if (e.keyCode === ctrlKey || e.keyCode === cmdKey) { _instance.ctrlDown = false; } }); return _instance; }, preventDefaultForKeyCode: function( keyCode ) { // copy past var keySelectAll = 97, keyCut = 120, keyCopy = 99, keyPaste = 118; if( this.ctrlDown && keyCode === keySelectAll || this.ctrlDown && keyCode === keyCut || this.ctrlDown && keyCode === keyCopy || this.ctrlDown && keyCode === keyPaste ) { return false; } // numeric if( keyCode >= 48 && keyCode <= 57) { return false; } // special key's switch ( keyCode ) { case 0 : // browser specific special key case 8 : // backspace case 9 : // tab case 35 : // end case 36 : // home case 37 : // left case 39 : // right case 144 : // num lock return false; default: return true; } }, getNewValueForKeyCode: function( keyCode, currentValue, position) { // if a comma or a dot is pressed... if( keyCode === 44 || keyCode === 46 || keyCode === 188 || keyCode === 190 ) { // and we do not have a options.decimal present... if( currentValue.indexOf( this.options.decimal ) === -1 ) { // append leading zero if currentValue is empty and leadingZeroCheck is active if( $.trim(currentValue) === '' && this.options.leadingZeroCheck ) { currentValue = '0'; position += 1; } // append the options.decimal instead of the dot or comma on the correct position return [currentValue.slice(0, position), this.options.decimal, currentValue.slice(position)].join(''); } } // prepend the minus if( keyCode === 45 && this.options.allowNegative ) { if( currentValue.charAt(0) !== '-' ) { return '-' + currentValue; } } return false; }, parseValue: function( value ) { var seperatorKey = '||SEP||'; var minusWasStripped = false; var result = value.replace(/[^\d.,\-]/g, ''); if(result.length === 0 && this.options.allowEmpty) { return ''; } result = result.replace( ',', seperatorKey ).replace( '.', seperatorKey ); // strip minus and prepend later if( result.indexOf('-') !== -1 ) { result = result.replace( '-', '' ); minusWasStripped = true; } if ( result.indexOf( seperatorKey ) === 0 ) { result = '0' + result; } if ( minusWasStripped === true && this.options.allowNegative === true) { result = '-' + result; } if ( this.options.numberOfDecimals !== null ) { var decimals = result.split( seperatorKey )[1]; if( decimals !== undefined ) { if( decimals.length > this.options.numberOfDecimals ) { result = Number(Number(String('0.' + decimals)).toFixed(this.options.numberOfDecimals)) + Math.floor(Number(result.replace(seperatorKey, '.'))); } if( decimals.length < this.options.numberOfDecimals ) { result += new Array( this.options.numberOfDecimals - decimals.length + 1 ).join('0'); } } var num = Number(String(result).replace(seperatorKey, '.')).toFixed(this.options.numberOfDecimals); result = String(num).replace('.', seperatorKey); } return result.split( seperatorKey ).join( this.options.decimal ); } }; $.fn.numeric_input = function ( options ) { return this.each(function () { if ( !$.data(this, 'numeric_input') ) { $.data( this, 'numeric_input', new NumericInput(this, options).init() ); } }); }; $.fn.numeric_input.defaults = { decimal: ',', numberOfDecimals: null, leadingZeroCheck: true, initialParse: true, parseOnBlur: true, clearInputOnBlurForZeroValue: true, allowNegative: false, allowEmpty: false, callback: function() {} }; }( jQuery, window, document ));