diff --git a/numeric/jquery.numeric.js b/numeric/jquery.numeric.js index 417f26c..2342d4e 100644 --- a/numeric/jquery.numeric.js +++ b/numeric/jquery.numeric.js @@ -1,14 +1,20 @@ /* * - * Copyright (c) 2006-2011 Sam Collett (http://www.texotela.co.uk) + * Copyright (c) 2006-2014 Sam Collett (http://www.texotela.co.uk) * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. - * - * Version 1.3.1 + * + * Version 1.4.1 * Demo: http://www.texotela.co.uk/code/jquery/numeric/ * */ -(function($) { +(function(factory){ + if(typeof define === 'function' && define.amd){ + define(['jquery'], factory); + }else{ + factory(window.jQuery); + } +}(function($) { /* * Allows only valid characters to be entered into input boxes. * Note: fixes value when pasting via Ctrl+V, but not when using the mouse to paste @@ -21,7 +27,9 @@ * @example $(".numeric").numeric(); * @example $(".numeric").numeric(","); // use , as separator * @example $(".numeric").numeric({ decimal : "," }); // use , as separator + * @example $(".numeric").numeric({ altDecimal : "," }); // accept , as alternative separator, but use . as separator in output * @example $(".numeric").numeric({ negative : false }); // do not allow negative values + * @example $(".numeric").numeric({ decimalPlaces : 2 }); // only allow 2 decimal places * @example $(".numeric").numeric(null, callback); // use default values, pass on the 'callback' function * */ @@ -29,19 +37,23 @@ $.fn.numeric = function(config, callback) { if(typeof config === 'boolean') { - config = { decimal: config }; + config = { decimal: config, negative: true, decimalPlaces: -1 }; } config = config || {}; // if config.negative undefined, set to true (default is to allow negative numbers) if(typeof config.negative == "undefined") { config.negative = true; } // set decimal point var decimal = (config.decimal === false) ? "" : config.decimal || "."; + // set alternative key as decimal point + var altDecimal = (config.altDecimal === false) ? "" : config.altDecimal || decimal; // allow negatives var negative = (config.negative === true) ? true : false; + // set decimal places + var decimalPlaces = (typeof config.decimalPlaces == "undefined") ? -1 : config.decimalPlaces; // callback function callback = (typeof(callback) == "function" ? callback : function() {}); // set data and methods - return this.data("numeric.decimal", decimal).data("numeric.negative", negative).data("numeric.callback", callback).keypress($.fn.numeric.keypress).keyup($.fn.numeric.keyup).blur($.fn.numeric.blur); + return this.data("numeric.decimal", decimal).data("numeric.altDecimal", altDecimal).data("numeric.negative", negative).data("numeric.callback", callback).data("numeric.decimalPlaces", decimalPlaces).keypress($.fn.numeric.keypress).keyup($.fn.numeric.keyup).blur($.fn.numeric.blur); }; $.fn.numeric.keypress = function(e) @@ -49,6 +61,9 @@ $.fn.numeric.keypress = function(e) // get decimal character and determine if negatives are allowed var decimal = $.data(this, "numeric.decimal"); var negative = $.data(this, "numeric.negative"); + var decimalPlaces = $.data(this, "numeric.decimalPlaces"); + // get an alternative decimal separator + var altDecimal = $.data(this, "numeric.altDecimal"); // get the key that was pressed var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0; // allow enter/return key (only when in an input box) @@ -60,6 +75,10 @@ $.fn.numeric.keypress = function(e) { return false; } + //dont allow #, $, % + else if(key == 35 || key == 36 || key == 37){ + return false; + } var allow = false; // allow Ctrl+A if((e.ctrlKey && key == 97 /* firefox */) || (e.ctrlKey && key == 65) /* opera */) { return true; } @@ -77,9 +96,9 @@ $.fn.numeric.keypress = function(e) { var value = $(this).val(); /* '-' only allowed at start and if negative numbers allowed */ - if(value.indexOf("-") !== 0 && negative && key == 45 && (value.length === 0 || parseInt($.fn.getSelectionStart(this), 10) === 0)) { return true; } + if($.inArray('-', value.split('')) !== 0 && negative && key == 45 && (value.length === 0 || parseInt($.fn.getSelectionStart(this), 10) === 0)) { return true; } /* only one decimal separator allowed */ - if(decimal && key == decimal.charCodeAt(0) && value.indexOf(decimal) != -1) + if(decimal && key == decimal.charCodeAt(0) && $.inArray(decimal, value.split('')) != -1) { allow = false; } @@ -117,10 +136,10 @@ $.fn.numeric.keypress = function(e) } } } - // if key pressed is the decimal and it is not already in the field - if(decimal && key == decimal.charCodeAt(0)) + // if key pressed is the decimal or altDecimal and decimal is not already in the field + if(decimal && key == decimal.charCodeAt(0) || altDecimal && key == altDecimal.charCodeAt(0)) { - if(value.indexOf(decimal) == -1) + if($.inArray(decimal, value.split('')) == -1) { allow = true; } @@ -133,6 +152,17 @@ $.fn.numeric.keypress = function(e) else { allow = true; + // remove extra decimal places + if(decimal && decimalPlaces > 0) + { + var selectionStart = $.fn.getSelectionStart(this); + var selectionEnd = $.fn.getSelectionEnd(this); + var dot = $.inArray(decimal, $(this).val().split('')); + if (selectionStart === selectionEnd && dot >= 0 && selectionStart > dot && $(this).val().length > dot + decimalPlaces) { + allow = false; + } + } + } return allow; }; @@ -144,28 +174,36 @@ $.fn.numeric.keyup = function(e) { // get carat (cursor) position var carat = $.fn.getSelectionStart(this); + var selectionEnd = $.fn.getSelectionEnd(this); // get decimal character and determine if negatives are allowed var decimal = $.data(this, "numeric.decimal"); var negative = $.data(this, "numeric.negative"); - + var decimalPlaces = $.data(this, "numeric.decimalPlaces"); + // get an alternative decimal separator + var altDecimal = $.data(this, "numeric.altDecimal"); + // prepend a 0 if necessary if(decimal !== "" && decimal !== null) { // find decimal point - var dot = val.indexOf(decimal); + var dot = $.inArray(decimal, val.split('')); // if dot at start, add 0 before if(dot === 0) { this.value = "0" + val; + carat++; + selectionEnd++; } // if dot at position 1, check if there is a - symbol before it if(dot == 1 && val.charAt(0) == "-") { this.value = "-0" + val.substring(1); + carat++; + selectionEnd++; } val = this.value; } - + // if pasted in, only allow the following characters var validChars = [0,1,2,3,4,5,6,7,8,9,'-',decimal]; // get length of the value (to loop through) @@ -195,6 +233,12 @@ $.fn.numeric.keyup = function(e) break; } } + // if not a valid character and character is altDecimal, replace + if(!validChar && ch == altDecimal) + { + val = val.substring(0, i) + decimal + val.substring(i + 1); + validChar = true; + } // if not a valid character, or a space, remove if(!validChar || ch == " ") { @@ -202,7 +246,7 @@ $.fn.numeric.keyup = function(e) } } // remove extra decimal characters - var firstDecimal = val.indexOf(decimal); + var firstDecimal = $.inArray(decimal, val.split('')); if(firstDecimal > 0) { for(var k = length - 1; k > firstDecimal; k--) @@ -215,9 +259,20 @@ $.fn.numeric.keyup = function(e) } } } + + // remove extra decimal places + if(decimal && decimalPlaces > 0) + { + var dot = $.inArray(decimal, val.split('')); + if (dot >= 0) + { + val = val.substring(0, dot + decimalPlaces + 1); + selectionEnd = Math.min(val.length, selectionEnd); + } + } // set the value and prevent the cursor moving to the end this.value = val; - $.fn.setSelection(this, carat); + $.fn.setSelection(this, [carat, selectionEnd]); } }; @@ -225,10 +280,11 @@ $.fn.numeric.blur = function() { var decimal = $.data(this, "numeric.decimal"); var callback = $.data(this, "numeric.callback"); + var negative = $.data(this, "numeric.negative"); var val = this.value; if(val !== "") { - var re = new RegExp("^\\d+$|^\\d*" + decimal + "\\d+$"); + var re = new RegExp("^" + (negative?"-?":"") + "\\d+$|^" + (negative?"-?":"") + "\\d*" + decimal + "\\d+$"); if(!re.exec(val)) { callback.apply(this); @@ -238,21 +294,41 @@ $.fn.numeric.blur = function() $.fn.removeNumeric = function() { - return this.data("numeric.decimal", null).data("numeric.negative", null).data("numeric.callback", null).unbind("keypress", $.fn.numeric.keypress).unbind("blur", $.fn.numeric.blur); + return this.data("numeric.decimal", null).data("numeric.altDecimal", null).data("numeric.negative", null).data("numeric.callback", null).data("numeric.decimalPlaces", null).unbind("keypress", $.fn.numeric.keypress).unbind("keyup", $.fn.numeric.keyup).unbind("blur", $.fn.numeric.blur); }; // Based on code from http://javascript.nwbox.com/cursor_position/ (Diego Perini ) $.fn.getSelectionStart = function(o) { - if (o.createTextRange) + if(o.type === "number"){ + return undefined; + } + else if (o.createTextRange && document.selection) { - var r = document.selection.createRange().duplicate(); - r.moveEnd('character', o.value.length); - if (r.text === '') { return o.value.length; } - return o.value.lastIndexOf(r.text); - } else { return o.selectionStart; } + var r = document.selection.createRange().duplicate(); + r.moveEnd('character', o.value.length); + if (r.text == '') return o.value.length; + + return Math.max(0, o.value.lastIndexOf(r.text)); + } else { + try { return o.selectionStart; } + catch(e) { return 0; } + } }; +// Based on code from http://javascript.nwbox.com/cursor_position/ (Diego Perini ) +$.fn.getSelectionEnd = function(o) +{ + if(o.type === "number"){ + return undefined; + } + else if (o.createTextRange && document.selection) { + var r = document.selection.createRange().duplicate() + r.moveStart('character', -o.value.length) + return r.text.length + } else return o.selectionEnd +} + // set the selection, o is the object (input), p is the position ([start, end] or just start) $.fn.setSelection = function(o, p) { @@ -261,20 +337,28 @@ $.fn.setSelection = function(o, p) // only set if p is an array of length 2 if(p && p.constructor == Array && p.length == 2) { - if (o.createTextRange) + if(o.type === "number") { + o.focus(); + } + else if (o.createTextRange) { var r = o.createTextRange(); r.collapse(true); r.moveStart('character', p[0]); - r.moveEnd('character', p[1]); + r.moveEnd('character', p[1] - p[0]); r.select(); } - else if(o.setSelectionRange) - { - o.focus(); - o.setSelectionRange(p[0], p[1]); - } + else { + o.focus(); + try{ + if(o.setSelectionRange) + { + o.setSelectionRange(p[0], p[1]); + } + } catch(e) { + } + } } }; -})(jQuery); +})); diff --git a/numeric/jquery.numeric.min.js b/numeric/jquery.numeric.min.js new file mode 100644 index 0000000..f21817c --- /dev/null +++ b/numeric/jquery.numeric.min.js @@ -0,0 +1,11 @@ +/* + * + * Copyright (c) 2006-2014 Sam Collett (http://www.texotela.co.uk) + * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) + * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. + * + * Version 1.4.1 + * Demo: http://www.texotela.co.uk/code/jquery/numeric/ + * + */ +(function(factory){if(typeof define === 'function' && define.amd){define(['jquery'], factory);}else{factory(window.jQuery);}}(function($){$.fn.numeric=function(config,callback){if(typeof config==="boolean"){config={decimal:config,negative:true,decimalPlaces:-1}}config=config||{};if(typeof config.negative=="undefined"){config.negative=true}var decimal=config.decimal===false?"":config.decimal||".";var altDecimal=config.altDecimal===false?"": config.altDecimal||decimal;var negative=config.negative===true?true:false;var decimalPlaces=typeof config.decimalPlaces=="undefined"?-1:config.decimalPlaces;callback=typeof callback=="function"?callback:function(){};return this.data("numeric.decimal",decimal).data("numeric.altDecimal",altDecimal).data("numeric.negative",negative).data("numeric.callback",callback).data("numeric.decimalPlaces",decimalPlaces).keypress($.fn.numeric.keypress).keyup($.fn.numeric.keyup).blur($.fn.numeric.blur)};$.fn.numeric.keypress=function(e){var decimal=$.data(this,"numeric.decimal");var negative=$.data(this,"numeric.negative");var decimalPlaces=$.data(this,"numeric.decimalPlaces");var altDecimal=$.data(this,"numeric.altDecimal");var key=e.charCode?e.charCode:e.keyCode?e.keyCode:0;if(key==13&&this.nodeName.toLowerCase()=="input"){return true}else if(key==13){return false}var allow=false;if(e.ctrlKey&&key==97||e.ctrlKey&&key==65){return true}if(e.ctrlKey&&key==120||e.ctrlKey&&key==88){return true}if(e.ctrlKey&&key==99||e.ctrlKey&&key==67){return true}if(e.ctrlKey&&key==122||e.ctrlKey&&key==90){return true}if(e.ctrlKey&&key==118||e.ctrlKey&&key==86||e.shiftKey&&key==45){return true}if(key<48||key>57){var value=$(this).val();if($.inArray("-",value.split(""))!==0&&negative&&key==45&&(value.length===0||parseInt($.fn.getSelectionStart(this),10)===0)){return true}if(decimal&&key==decimal.charCodeAt(0)&&$.inArray(decimal,value.split(""))!=-1){allow=false}if(key!=8&&key!=9&&key!=13&&key!=35&&key!=36&&key!=37&&key!=39&&key!=46){allow=false}else{if(typeof e.charCode!="undefined"){if(e.keyCode==e.which&&e.which!==0){allow=true;if(e.which==46){allow=false}}else if(e.keyCode!==0&&e.charCode===0&&e.which===0){allow=true}}}if(decimal&&key==decimal.charCodeAt(0)||altDecimal&&key==altDecimal.charCodeAt(0)){if($.inArray(decimal,value.split(""))==-1){allow=true}else{allow=false}}}else{allow=true;if(decimal&&decimalPlaces>0){var dot=$.inArray(decimal,$(this).val().split(""));if(dot>=0&&$(this).val().length>dot+decimalPlaces){allow=false}}}return allow};$.fn.numeric.keyup=function(e){var val=$(this).val();if(val&&val.length>0){var carat=$.fn.getSelectionStart(this);var selectionEnd=$.fn.getSelectionEnd(this);var decimal=$.data(this,"numeric.decimal");var negative=$.data(this,"numeric.negative");var decimalPlaces=$.data(this,"numeric.decimalPlaces");var altDecimal=$.data(this,"numeric.altDecimal");if(decimal!==""&&decimal!==null){var dot=$.inArray(decimal,val.split(""));if(dot===0){this.value="0"+val;carat++;selectionEnd++}if(dot==1&&val.charAt(0)=="-"){this.value="-0"+val.substring(1);carat++;selectionEnd++}val=this.value}var validChars=[0,1,2,3,4,5,6,7,8,9,"-",decimal];var length=val.length;for(var i=length-1;i>=0;i--){var ch=val.charAt(i);if(i!==0&&ch=="-"){val=val.substring(0,i)+val.substring(i+1)}else if(i===0&&!negative&&ch=="-"){val=val.substring(1)}var validChar=false;for(var j=0;j0){for(var k=length-1;k>firstDecimal;k--){var chch=val.charAt(k);if(chch==decimal){val=val.substring(0,k)+val.substring(k+1)}}}if(decimal&&decimalPlaces>0){var dot=$.inArray(decimal,val.split(""));if(dot>=0){val=val.substring(0,dot+decimalPlaces+1);selectionEnd=Math.min(val.length,selectionEnd)}}this.value=val;$.fn.setSelection(this,[carat,selectionEnd])}};$.fn.numeric.blur=function(){var decimal=$.data(this,"numeric.decimal");var callback=$.data(this,"numeric.callback");var negative=$.data(this,"numeric.negative");var val=this.value;if(val!==""){var re=new RegExp("^" + (negative?"-?":"") + "\\d+$|^" + (negative?"-?":"") + "\\d*" + decimal + "\\d+$");if(!re.exec(val)){callback.apply(this)}}};$.fn.removeNumeric=function(){return this.data("numeric.decimal",null).data("numeric.altDecimal",null).data("numeric.negative",null).data("numeric.callback",null).data("numeric.decimalPlaces",null).unbind("keypress",$.fn.numeric.keypress).unbind("keyup",$.fn.numeric.keyup).unbind("blur",$.fn.numeric.blur)};$.fn.getSelectionStart=function(o){if(o.type==="number"){return undefined}else if(o.createTextRange&&document.selection){var r=document.selection.createRange().duplicate();r.moveEnd("character",o.value.length);if(r.text=="")return o.value.length;return Math.max(0,o.value.lastIndexOf(r.text))}else{try{return o.selectionStart}catch(e){return 0}}};$.fn.getSelectionEnd=function(o){if(o.type==="number"){return undefined}else if(o.createTextRange&&document.selection){var r=document.selection.createRange().duplicate();r.moveStart("character",-o.value.length);return r.text.length}else return o.selectionEnd};$.fn.setSelection=function(o,p){if(typeof p=="number"){p=[p,p]}if(p&&p.constructor==Array&&p.length==2){if(o.type==="number"){o.focus()}else if(o.createTextRange){var r=o.createTextRange();r.collapse(true);r.moveStart("character",p[0]);r.moveEnd("character",p[1]-p[0]);r.select()}else{o.focus();try{if(o.setSelectionRange){o.setSelectionRange(p[0],p[1])}}catch(e){}}}}})); diff --git a/numeric/test.html b/numeric/test.html index 631dbfc..62f91be 100644 --- a/numeric/test.html +++ b/numeric/test.html @@ -8,12 +8,25 @@
Numbers only: +

Integers only: +

No negative values: +

No negative values (integer only): +

+ Numbers with up to 2 decimal places: + +

+ Alternative (,) changes to standard (.) decimal separator: + +

+ Reverse change from alternative (.) to standard (,) decimal separator: + +

Remove numeric
- \ No newline at end of file + diff --git a/selectboxes/jquery.selectboxes.js b/selectboxes/jquery.selectboxes.js index d98f01e..4efe832 100644 --- a/selectboxes/jquery.selectboxes.js +++ b/selectboxes/jquery.selectboxes.js @@ -108,11 +108,17 @@ $.fn.addOption = function() if(this.nodeName.toLowerCase() != "select") return; if(m) { - for(var item in items) - { - add(this, item, items[item], sO, startindex); - startindex += 1; - } + var sel = this; + jQuery.each(items, function(val, text){ + if(typeof(text) == "object"){ + jQuery.each(text, function(k,v){ + val = k; + text = v; + }); + } + add(sel, val, text, sO, startindex); + startindex += 1; + }); } else { @@ -550,4 +556,4 @@ $.fn.selectedOptions = function() return this.find("option:selected"); }; -})(jQuery); \ No newline at end of file +})(jQuery);