1/* 2 * 3 * Copyright (c) 2006-2010 Sam Collett (http://www.texotela.co.uk) 4 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 5 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. 6 * 7 * Version 1.2 8 * Demo: http://www.texotela.co.uk/code/jquery/numeric/ 9 * 10 */ 11(function($) { 12/* 13 * Allows only valid characters to be entered into input boxes. 14 * Note: does not validate that the final text is a valid number 15 * (that could be done by another script, or server-side) 16 * 17 * @name numeric 18 * @param decimal Decimal separator (e.g. '.' or ',' - default is '.'). Pass false for integers 19 * @param callback A function that runs if the number is not valid (fires onblur) 20 * @author Sam Collett (http://www.texotela.co.uk) 21 * @example $(".numeric").numeric(); 22 * @example $(".numeric").numeric(","); 23 * @example $(".numeric").numeric(null, callback); 24 * 25 */ 26$.fn.numeric = function(decimal, callback) { 27 decimal = (decimal === false) ? "" : decimal || "."; 28 callback = typeof callback == "function" ? callback : function(){}; 29 $(document).on('input', this.selector, $.fn.numeric.input) 30 return this.data("numeric.decimal", decimal).data("numeric.callback", callback).data("numeric.negative", true).keyup($.fn.numeric.keyup).keypress($.fn.numeric.keypress).blur($.fn.numeric.blur); 31} 32 33 34$.fn.numeric.keypress = function(e) { 35 var min = $(this).attr('min') || undefined; 36 var max = $(this).attr('max') || undefined; 37 var decimal = $.data(this, "numeric.decimal"); 38 39 var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0; 40 41 // allow enter/return key (only when in an input box) 42 if(key == 13 && this.nodeName.toLowerCase() == "input"){ 43 return true; 44 }else if(key == 13){ 45 return false; 46 } 47 48 var allow = false; 49 50 // allow Ctrl+A 51 if((e.ctrlKey && key == 97 /* firefox */) || (e.ctrlKey && key == 65) /* opera */) return true; 52 // allow Ctrl+X (cut) 53 if((e.ctrlKey && key == 120 /* firefox */) || (e.ctrlKey && key == 88) /* opera */) return true; 54 // allow Ctrl+C (copy) 55 if((e.ctrlKey && key == 99 /* firefox */) || (e.ctrlKey && key == 67) /* opera */) return true; 56 // allow Ctrl+Z (undo) 57 if((e.ctrlKey && key == 122 /* firefox */) || (e.ctrlKey && key == 90) /* opera */) return true; 58 // allow or deny Ctrl+V (paste), Shift+Ins 59 if((e.ctrlKey && key == 118 /* firefox */) || (e.ctrlKey && key == 86) /* opera */ 60 || (e.shiftKey && key == 45)) return true; 61 62 63 /* number under fn keys */ /* Number pad keys */ 64 if ((key >= 48 && key <= 57)) { 65 // A number was pressed but we need to check the min and max 66 allow = true; 67 68 // check min 69 if (min !== undefined) { 70 if (parseInt(this.value) < parseInt(min)) { 71 e.preventDefault(); 72 this.value = min; 73 } 74 } 75 76 // check max 77 if (max !== undefined) { 78 if (parseInt(this.value) > parseInt(max)) { 79 e.preventDefault(); 80 this.value = max; 81 } 82 } 83 84 }else { 85 86 var allowNeg = true; 87 88 if (min != undefined && parseInt(min) >= 0) { 89 allowNeg = false; 90 } 91 92 /* '-' only allowed at start */ 93 if(key == 45 && this.value.length == 0 && allowNeg) { 94 return true; 95 } 96 97 /* only one decimal separator allowed */ 98 if(decimal && key == decimal.charCodeAt(0) && this.value.indexOf(decimal) != -1) { 99 allow = false; 100 } 101 102 // check for other keys that have special purposes 103 if( 104 key != 8 /* backspace */ && 105 key != 9 /* tab */ && 106 key != 13 /* enter */ && 107 key != 35 /* end */ && 108 key != 36 /* home */ && 109 key != 37 /* left */ && 110 key != 39 /* right */ && 111 key != 46 /* del */ 112 ){ 113 allow = false; 114 }else { 115 116 // for detecting special keys (listed above) 117 // IE does not support 'charCode' and ignores them in keypress anyway 118 if(typeof e.charCode != "undefined") { 119 // special keys have 'keyCode' and 'which' the same (e.g. backspace) 120 if(e.keyCode == e.which && e.which != 0) { 121 allow = true; 122 // . and delete share the same code, don't allow . (will be set to true later if it is the decimal point) 123 if(e.which == 46) allow = false; 124 } 125 // or keyCode != 0 and 'charCode'/'which' = 0 126 else if(e.keyCode != 0 && e.charCode == 0 && e.which == 0){ 127 allow = true; 128 } 129 } 130 } 131 132 // if key pressed is the decimal and it is not already in the field
133 if(decimal && key == decimal.charCodeAt(0)) { 134 if(this.value.indexOf(decimal) == -1) { 135 allow = true; 136 }else { 137 allow = false; 138 } 139 } 140 } 141 142 return allow; 143} 144 145 146$.fn.numeric.keyup = function(e) { 147 var min = $(this).attr('min') || undefined; 148 var max = $(this).attr('max') || undefined; 149 var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0; 150 151 // if a number was pressed 152 if ((key >= 48 && key <= 57) || (key >= 96 && key <= 105)) { 153 154 // check min 155 if (min !== undefined) { 156 if (parseInt(this.value) < parseInt(min)) { 157 e.preventDefault(); 158 this.value = min; 159 return false; 160 } 161 } 162 163 // check max 164 if (max !== undefined) { 165 if (parseInt(this.value) > parseInt(max)) { 166 e.preventDefault(); 167 this.value = max; 168 return false; 169 } 170 } 171 172 } 173 174 return true; 175} 176 177$.fn.numeric.input = function(e) 178{ 179 var val = $(this).val(); 180 if(val && val.length > 0) 181 { 182 // get carat (cursor) position 183 var carat = $.fn.getSelectionStart(this); 184 var selectionEnd = $.fn.getSelectionEnd(this); 185 // get decimal character and determine if negatives are allowed 186 var decimal = $.data(this, "numeric.decimal"); 187 var negative = $.data(this, "numeric.negative"); 188 var decimalPlaces = $.data(this, "numeric.decimalPlaces"); 189 // get an alternative decimal separator 190 var altDecimal = $.data(this, "numeric.altDecimal"); 191 192 // prepend a 0 if necessary 193 if(decimal !== "" && decimal !== null) 194 { 195 // find decimal point 196 var dot = $.inArray(decimal, val.split('')); 197 // if dot at start, add 0 before 198 if(dot === 0) 199 { 200 this.value = "0" + val; 201 carat++; 202 selectionEnd++; 203 } 204 // if dot at position 1, check if there is a - symbol before it 205 if(dot == 1 && val.charAt(0) == "-") 206 { 207 this.value = "-0" + val.substring(1); 208 carat++; 209 selectionEnd++; 210 } 211 val = this.value; 212 } 213 214 // if pasted in, only allow the following characters 215 var validChars = [0,1,2,3,4,5,6,7,8,9,'-',decimal]; 216 // get length of the value (to loop through) 217 var length = val.length; 218 // loop backwards (to prevent going out of bounds) 219 for(var i = length - 1; i >= 0; i--) 220 { 221 var ch = val.charAt(i); 222 // remove '-' if it is in the wrong place 223 if(i !== 0 && ch == "-") 224 { 225 val = val.substring(0, i) + val.substring(i + 1); 226 } 227 // remove character if it is at the start, a '-' and negatives aren't allowed 228 else if(i === 0 && !negative && ch == "-") 229 { 230 val = val.substring(1); 231 } 232 var validChar = false; 233 // loop through validChars 234 for(var j = 0; j < validChars.length; j++) 235 { 236 // if it is valid, break out the loop 237 if(ch == validChars[j]) 238 { 239 validChar = true; 240 break; 241 } 242 } 243 // if not a valid character and character is altDecimal, replace 244 if(!validChar && ch == altDecimal) 245 { 246 val = val.substring(0, i) + decimal + val.substring(i + 1); 247 validChar = true; 248 } 249 // if not a valid character, or a space, remove 250 if(!validChar || ch == " ") 251 { 252 val = val.substring(0, i) + val.substring(i + 1); 253 } 254 } 255 // remove extra decimal characters 256 var firstDecimal = $.inArray(decimal, val.split('')); 257 if(firstDecimal > 0) 258 { 259 for(var k = length - 1; k > firstDecimal; k--) 260 { 261 var chch = val.charAt(k); 262 // remove decimal character 263 if(chch == decimal) 264 { 265 val = val.substring(0, k) + val.substring(k + 1); 266 } 267 } 268 } 269 270 // remove extra decimal places 271 if(decimal && decimalPlaces > 0) 272 { 273 var dot = $.inArray(decimal, val.split('')); 274 if (dot >= 0) 275 { 276 val = val.substring(0, dot + decimalPlaces + 1); 277 selectionEnd = Math.min(val.length, selectionEnd); 278 } 279 } 280 // set the value and prevent the cursor moving to the end 281 this.value = val; 282 $.fn.setSelection(this, [carat, selectionEnd]); 283 } 284}; 285 286$.fn.numeric.blur = function() { 287 var decimal = $.data(this, "numeric.decimal"); 288 var callback = $.data(this, "numeric.callback"); 289 var val = $(this).val(); 290 291 if(val != "") { 292 var re = new RegExp("^\\d+$|\\d*" + decimal + "\\d+"); 293 if(!re.exec(val)) { 294 callback.apply(this); 295 } 296 } 297} 298 299$.fn.removeNumeric = function(){ 300 $(document).off('input', this.selector, $.fn.numeric.input) 301 return this.data("numeric.decimal", null).data("numeric.callback", null).unbind("
vendor: 1,899 bytes, lines 301-368
301keypress", $.fn.numeric.keypress).unbind("keyup", $.fn.numeric.keyup).unbind("blur", $.fn.numeric.blur); 302} 303 304// Based on code from http://javascript.nwbox.com/cursor_position/ (Diego Perini <[email protected]>) 305$.fn.getSelectionStart = function(o) 306{ 307 if(o.type === "number"){ 308 return undefined; 309 } 310 else if (o.createTextRange && document.selection) 311 { 312 var r = document.selection.createRange().duplicate(); 313 r.moveEnd('character', o.value.length); 314 if (r.text == '') return o.value.length; 315 316 return Math.max(0, o.value.lastIndexOf(r.text)); 317 } else { 318 try { return o.selectionStart; } 319 catch(e) { return 0; } 320 } 321}; 322 323// Based on code from http://javascript.nwbox.com/cursor_position/ (Diego Perini <[email protected]>) 324$.fn.getSelectionEnd = function(o) 325{ 326 if(o.type === "number"){ 327 return undefined; 328 } 329 else if (o.createTextRange && document.selection) { 330 var r = document.selection.createRange().duplicate() 331 r.moveStart('character', -o.value.length) 332 return r.text.length 333 } else return o.selectionEnd 334} 335 336// set the selection, o is the object (input), p is the position ([start, end] or just start) 337$.fn.setSelection = function(o, p) 338{ 339 // if p is number, start and end are the same 340 if(typeof p == "number") { p = [p, p]; } 341 // only set if p is an array of length 2 342 if(p && p.constructor == Array && p.length == 2) 343 { 344 if(o.type === "number") { 345 o.focus(); 346 } 347 else if (o.createTextRange) 348 { 349 var r = o.createTextRange(); 350 r.collapse(true); 351 r.moveStart('character', p[0]); 352 r.moveEnd('character', p[1] - p[0]); 353 r.select(); 354 } 355 else { 356 o.focus(); 357 try{ 358 if(o.setSelectionRange) 359 { 360 o.setSelectionRange(p[0], p[1]); 361 } 362 } catch(e) { 363 } 364 } 365 } 366}; 367 368})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.