jstepper
Version:
A jQuery plugin for making a numeric textfield value easy to increase or decrease.
469 lines (329 loc) • 10.8 kB
JavaScript
// jStepper 1.5.4
// A jQuery plugin by EmKay usable for making a numeric textfield value easy to increase or decrease.
(function(jQuery) {
jQuery.fn.jStepper = function(param1, param2, param3) {
if (this.length > 1) {
this.each(function() { $(this).jStepper(param1) });
return this;
}
if (typeof param1 === 'string') {
if (param1 === 'option') {
if (param3 === null) {
param3 = jQuery.fn.jStepper.defaults[param2];
}
this.data('jstepper.o')[param2] = param3;
}
return this;
}
var o = jQuery.extend({}, jQuery.fn.jStepper.defaults, param1);
if (jQuery.metadata) {
o = jQuery.extend({}, o, this.metadata());
}
this.data('jstepper.o', o);
if (o.disableAutocomplete) {
this.attr('autocomplete', 'off');
}
if (jQuery.isFunction(this.mousewheel)) {
this.mousewheel(function(e, intDelta) {
if (intDelta > 0) { // Up
var objDownEvent = jQuery.Event('keydown');
objDownEvent.keyCode = 38;
MakeStep(1, objDownEvent, this);
return false;
}
else if (intDelta < 0) { // Down
var objDownEvent = jQuery.Event('keydown');
objDownEvent.keyCode = 40;
MakeStep(0, objDownEvent, this);
return false;
}
});
}
this.blur(function() {
CheckValue(this, null);
});
this.keydown(function(e) {
var key = e.keyCode;
if (key === 38) { // Up
MakeStep(1, e, this);
} else if (key === 40) { // Down
MakeStep(0, e, this);
} else {
if (o.overflowMode === 'ignore') {
var objValueToCheck = $(this).val().indexOf("-") === 0 ? o.minValue : o.maxValue;
if (objValueToCheck) {
if ($(this).val().length >= objValueToCheck.toString().length) {
if (
((key >= 48 && key <= 57) || (key >= 96 && key <= 105)) &&
(this.selectionStart === this.selectionEnd)
) {
return false;
}
}
}
}
}
});
this.keyup(function(e) {
CheckValue(this, e);
});
var CheckValue = function(objElm, key) {
var $objElm = jQuery(objElm);
var strValue = $objElm.val();
var initialStrValue = strValue;
if (o.disableNonNumeric) {
strValue = strValue.replace(/[^\d\.,\-]/gi, '');
strValue = strValue.replace(/-{2,}/g, '-');
strValue = strValue.replace(/(.+)\-+/g, '$1');
}
var bOverflow = false;
if (o.maxValue !== null) {
if (parseFloat(strValue) > o.maxValue) {
strValue = o.maxValue;
bOverflow = true;
}
}
if (o.minValue !== null) {
if (strValue != '' && parseFloat(strValue) < parseFloat(o.minValue)) {
strValue = o.minValue;
bOverflow = true;
}
}
if (IsUpOrDownKey(key) === true || key === null || bOverflow === true) {
strValue = DoTheChecks(strValue);
}
if (initialStrValue != strValue) {
$objElm.val(strValue);
}
};
var MakeStep = function(bDirection, key, objElm) {
var $objElm = jQuery(objElm);
var stepToUse;
if (key) {
if (key.ctrlKey) {
stepToUse = o.ctrlStep;
} else if (key.shiftKey) {
stepToUse = o.shiftStep;
} else {
stepToUse = o.normalStep;
}
} else {
stepToUse = o.normalStep;
}
var numValue = $objElm.val();
var intSelectionStart = numValue.length - objElm.selectionStart;
var intSelectionEnd = numValue.length - objElm.selectionEnd;
numValue = numValue.replace(/,/g, '.');
numValue = numValue.replace(o.decimalSeparator, '.');
numValue = numValue + '';
if (numValue.indexOf('.') != -1) {
numValue = numValue.match(new RegExp('-{0,1}[0-9]+[\\.][0-9]*'));
}
numValue = numValue + '';
if (numValue.indexOf('-') != -1) {
numValue = numValue.match(new RegExp('-{0,1}[0-9]+[\\.]*[0-9]*'));
}
numValue = numValue + '';
numValue = numValue.match(new RegExp('-{0,1}[0-9]+[\\.]*[0-9]*'));
if (numValue === '' || numValue == '-' || numValue === null) {
numValue = o.defaultValue;
}
if (bDirection === 1) {
numValue = jQuery.fn.jStepper.AddOrSubtractTwoFloats(numValue, stepToUse, true);
} else {
numValue = jQuery.fn.jStepper.AddOrSubtractTwoFloats(numValue, stepToUse, false);
}
var bLimitReached = false;
if (o.maxValue !== null) {
if (numValue >= o.maxValue) {
numValue = o.maxValue;
bLimitReached = true;
}
}
if (o.minValue !== null) {
if (numValue <= o.minValue) {
numValue = o.minValue;
bLimitReached = true;
}
}
numValue = numValue.toString().replace(/\./, o.decimalSeparator);
$objElm.val(numValue);
objElm.selectionStart = numValue.length - intSelectionStart;
objElm.selectionEnd = numValue.length - intSelectionEnd;
CheckValue(objElm, key);
if (o.onStep) {
o.onStep($objElm, bDirection, bLimitReached);
}
return false;
};
var DoTheChecks = function(strValue) {
var strResult = strValue.toString();
strResult = CheckMinDecimals(strResult);
strResult = CheckMaxDecimals(strResult);
strResult = CheckAllowDecimals(strResult);
strResult = CheckMinLength(strResult);
return strResult;
};
var CheckMinDecimals = function(strValue) {
var strResult = strValue;
if (o.minDecimals > 0) {
var intDecimalsMissing;
if (strResult.indexOf('.') != -1) {
var intDecimalsNow = strResult.length - (strResult.indexOf('.') + 1);
if (intDecimalsNow < o.minDecimals) {
intDecimalsMissing = o.minDecimals - intDecimalsNow;
}
} else {
intDecimalsMissing = o.minDecimals;
strResult = strResult + '.';
}
for (var intDecimalIndex = 1; intDecimalIndex <= intDecimalsMissing; intDecimalIndex++) {
strResult = strResult + '0';
}
}
return strResult;
};
var CheckMaxDecimals = function(strValue) {
var strResult = strValue;
if (o.maxDecimals > 0) {
var intDecimalsNow = 0;
if (strResult.indexOf('.') != -1) {
intDecimalsNow = strResult.length - (strResult.indexOf('.') + 1);
if (o.maxDecimals < intDecimalsNow) {
strResult = strResult.substring(0, strResult.indexOf('.')) + '.' + strResult.substring(strResult.indexOf('.') + 1, strResult.indexOf('.') + 1 + o.maxDecimals);
}
}
}
return strResult;
};
var CheckAllowDecimals = function(strValue) {
var strResult = strValue;
if (!o.allowDecimals) {
strResult = strResult.toString().replace(o.decimalSeparator, '.');
strResult = strResult.replace(new RegExp('[\\.].+'), '');
}
return strResult;
};
var CheckMinLength = function(strValue) {
var strResult = strValue;
if (o.minLength !== null) {
var intLengthNow = strResult.length;
if (strResult.indexOf('.') != -1) {
intLengthNow = strResult.indexOf('.');
}
var bIsNegative = false;
if (strResult.indexOf('-') != -1) {
bIsNegative = true;
strResult = strResult.replace(/-/, '');
}
if (intLengthNow < o.minLength) {
for (var i = 1; i <= (o.minLength - intLengthNow) ; i++) {
strResult = '0' + strResult;
}
}
if (bIsNegative) {
strResult = '-' + strResult;
}
}
return strResult;
};
var IsUpOrDownKey = function(key) {
var bResult = false;
if (key !== null) {
if (key.keyCode === 38 || key.keyCode === 40) {
bResult = true;
}
}
return bResult;
};
var GetOption = function(strOptionName) {
return this.data('jstepper.o')[strOptionName];
};
return this;
};
jQuery.fn.jStepper.AddOrSubtractTwoFloats = function(fltValue1, fltValue2, bAddSubtract) {
var strNumber1 = fltValue1.toString();
var strNumber2 = fltValue2.toString();
var strResult = '';
if (strNumber1.indexOf('.') > -1 || strNumber2.indexOf('.') > -1) {
// If no decimals on one of them, then put them on!
if (strNumber1.indexOf('.') === -1) {
strNumber1 = strNumber1 + '.0';
}
if (strNumber2.indexOf('.') === -1) {
strNumber2 = strNumber2 + '.0';
}
// Get only decimals
var strDecimals1 = strNumber1.substr(strNumber1.indexOf('.') + 1);
var strDecimals2 = strNumber2.substr(strNumber2.indexOf('.') + 1);
// Getting the integers...
var strInteger1 = strNumber1.substr(0, strNumber1.indexOf('.'));
var strInteger2 = strNumber2.substr(0, strNumber2.indexOf('.'));
//Make sure that the two decimals are same length (ie .02 vs .001) and append zeros as necessary.
var bNotSameLength = true;
while (bNotSameLength) {
if (strDecimals1.length !== strDecimals2.length) {
if (strDecimals1.length < strDecimals2.length) {
strDecimals1 += '0';
} else {
strDecimals2 += '0';
}
} else {
bNotSameLength = false;
}
}
var intOriginalDecimalLength = strDecimals1.length;
for (var intCharIndex = 0; intCharIndex <= strDecimals1.length - 1; intCharIndex++) {
strInteger1 = strInteger1 + strDecimals1.substr(intCharIndex, 1);
strInteger2 = strInteger2 + strDecimals2.substr(intCharIndex, 1);
}
var intInteger1 = Number(strInteger1);
var intInteger2 = Number(strInteger2);
var intResult;
if (bAddSubtract) {
intResult = intInteger1 + intInteger2;
} else {
intResult = intInteger1 - intInteger2;
}
var bIsNegative = false;
if (intResult < 0) {
bIsNegative = true;
intResult = Math.abs(intResult);
}
strResult = intResult.toString();
for (var intZerosAdded = 0; intZerosAdded < ((intOriginalDecimalLength - strResult.length) + 1) ; intZerosAdded++) {
strResult = '0' + strResult;
}
if (strResult.length >= intOriginalDecimalLength) {
strResult = strResult.substring(0, strResult.length - intOriginalDecimalLength) + '.' + strResult.substring(strResult.length - intOriginalDecimalLength);
}
if (bIsNegative === true) {
strResult = '-' + strResult;
}
} else {
if (bAddSubtract) {
strResult = Number(fltValue1) + Number(fltValue2);
} else {
strResult = Number(fltValue1) - Number(fltValue2);
}
}
return Number(strResult);
};
jQuery.fn.jStepper.defaults = {
maxValue: null,
minValue: null,
normalStep: 1,
shiftStep: 5,
ctrlStep: 10,
minLength: null,
disableAutocomplete: true,
defaultValue: 1,
decimalSeparator: ',',
allowDecimals: true,
minDecimals: 0,
maxDecimals: null,
disableNonNumeric: true,
onStep: null,
overflowMode: 'default'
};
})(jQuery);