PageRenderTime 23ms CodeModel.GetById 9ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/jquery-validate/demo/multipart/js/jquery.maskedinput-1.0.js

#
JavaScript | 246 lines | 207 code | 6 blank | 33 comment | 7 complexity | da4c4e089d4eb63d427db261c6a0d27c MD5 | raw file
  1/*
  2 * Copyright (c) 2007 Josh Bush (digitalbush.com)
  3 * 
  4 * Permission is hereby granted, free of charge, to any person
  5 * obtaining a copy of this software and associated documentation
  6 * files (the "Software"), to deal in the Software without
  7 * restriction, including without limitation the rights to use,
  8 * copy, modify, merge, publish, distribute, sublicense, and/or sell
  9 * copies of the Software, and to permit persons to whom the
 10 * Software is furnished to do so, subject to the following
 11 * conditions:
 12
 13 * The above copyright notice and this permission notice shall be
 14 * included in all copies or substantial portions of the Software.
 15 * 
 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 18 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 20 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 23 * OTHER DEALINGS IN THE SOFTWARE. 
 24 */
 25 
 26/*
 27 * Version: 1.0
 28 * Release: 2007-07-25
 29 */ 
 30(function($) {
 31	//Helper Functions for Caret positioning
 32	function getCaretPosition(ctl){
 33		var res = {begin: 0, end: 0 };
 34		if (ctl.setSelectionRange){
 35			res.begin = ctl.selectionStart;
 36			res.end = ctl.selectionEnd;
 37		}else if (document.selection && document.selection.createRange){
 38			var range = document.selection.createRange();			
 39			res.begin = 0 - range.duplicate().moveStart('character', -100000);
 40			res.end = res.begin + range.text.length;
 41		}
 42		return res;
 43	};
 44
 45	function setCaretPosition(ctl, pos){
 46		if(ctl.setSelectionRange){
 47			ctl.focus();
 48			ctl.setSelectionRange(pos,pos);
 49		}else if (ctl.createTextRange){
 50			var range = ctl.createTextRange();
 51			range.collapse(true);
 52			range.moveEnd('character', pos);
 53			range.moveStart('character', pos);
 54			range.select();
 55		}
 56	};
 57	
 58	//Predefined character definitions
 59	var charMap={
 60		'9':"[0-9]",
 61		'a':"[A-Za-z]",
 62		'*':"[A-Za-z0-9]"
 63	};
 64	
 65	//Helper method to inject character definitions
 66	$.mask={
 67		addPlaceholder : function(c,r){
 68			charMap[c]=r;
 69		}
 70	};
 71	
 72	//Main Method
 73	$.fn.mask = function(mask,settings) {	
 74		settings = $.extend({
 75			placeholder: "_",
 76			completed: null
 77		}, settings);
 78			
 79		//Build Regex for format validation
 80		var reString="^";	
 81		for(var i=0;i<mask.length;i++)
 82			reString+=(charMap[mask.charAt(i)] || ("\\"+mask.charAt(i)));					
 83		reString+="$";
 84		var re = new RegExp(reString);
 85
 86		return this.each(function(){		
 87			var input=$(this);
 88			var buffer=new Array(mask.length);
 89			var locked=new Array(mask.length);		
 90
 91			//Build buffer layout from mask
 92			for(var i=0;i<mask.length;i++){
 93				locked[i]=charMap[mask.charAt(i)]==null;
 94				buffer[i]=locked[i]?mask.charAt(i):settings.placeholder;					
 95			}
 96			
 97			/*Event Bindings*/
 98			input.focus(function(){					
 99				checkVal();
100				writeBuffer();
101				setCaretPosition(this,0);		
102			});
103
104			input.blur(checkVal);
105			
106			//Paste events for IE and Mozilla thanks to Kristinn Sigmundsson
107			if ($.browser.msie) 
108				this.onpaste= function(){setTimeout(checkVal,0);};                     
109			else if ($.browser.mozilla)
110				this.addEventListener('input',checkVal,false);
111			
112			var ignore=false;  //Variable for ignoring control keys
113			
114			input.keydown(function(e){
115				var pos=getCaretPosition(this);													
116				var k = e.keyCode;
117				ignore=(k < 16 || (k > 16 && k < 32 ) || (k > 32 && k < 41));
118				
119				//delete selection before proceeding
120				if((pos.begin-pos.end)!=0 && (!ignore || k==8 || k==46)){
121					clearBuffer(pos.begin,pos.end);
122				}	
123				//backspace and delete get special treatment
124				if(k==8){//backspace					
125					while(pos.begin-->=0){
126						if(!locked[pos.begin]){								
127							buffer[pos.begin]=settings.placeholder;
128							if($.browser.opera){
129								//Opera won't let you cancel the backspace, so we'll let it backspace over a dummy character.								
130								writeBuffer(pos.begin);
131								setCaretPosition(this,pos.begin+1);
132							}else{
133								writeBuffer();
134								setCaretPosition(this,pos.begin);
135							}									
136							return false;								
137						}
138					}						
139				}else if(k==46){//delete
140					clearBuffer(pos.begin,pos.begin+1);
141					writeBuffer();
142					setCaretPosition(this,pos.begin);
143					return false;
144				}else if (k==27){
145					clearBuffer(0,mask.length);
146					writeBuffer();
147					setCaretPosition(this,0);
148					return false;
149				}
150									
151			});
152
153			input.keypress(function(e){					
154				if(ignore){
155					ignore=false;
156					return;
157				}
158				e=e||window.event;
159				var k=e.charCode||e.keyCode||e.which;
160
161				var pos=getCaretPosition(this);					
162				var caretPos=pos.begin;	
163				
164				if(e.ctrlKey || e.altKey){//Ignore
165					return true;
166				}else if ((k>=41 && k<=122) ||k==32 || k>186){//typeable characters
167					while(pos.begin<mask.length){	
168						var reString=charMap[mask.charAt(pos.begin)];
169						var match;
170						if(reString){
171							var reChar=new RegExp(reString);
172							match=String.fromCharCode(k).match(reChar);
173						}else{//we're on a mask char, go forward and try again
174							pos.begin+=1;
175							pos.end=pos.begin;
176							caretPos+=1;
177							continue;
178						}
179
180						if(match)
181							buffer[pos.begin]=String.fromCharCode(k);
182						else
183							return false;//reject char
184
185						while(++caretPos<mask.length){//seek forward to next typable position
186							if(!locked[caretPos])							
187								break;							
188						}
189						break;
190					}
191				}else
192					return false;								
193
194				writeBuffer();
195				if(settings.completed && caretPos>=buffer.length)
196					settings.completed.call(input);
197				else
198					setCaretPosition(this,caretPos);
199				
200				return false;				
201			});
202
203			/*Helper Methods*/
204			function clearBuffer(start,end){
205				for(var i=start;i<end;i++){
206					if(!locked[i])
207						buffer[i]=settings.placeholder;
208				}				
209			};
210			
211			function writeBuffer(pos){
212				var s="";
213				for(var i=0;i<mask.length;i++){
214					s+=buffer[i];
215					if(i==pos)
216						s+=settings.placeholder;
217				}
218				input.val(s);
219				return s;
220			};
221			
222			function checkVal(){	
223				//try to place charcters where they belong
224				var test=input.val();
225				var pos=0;
226				for(var i=0;i<mask.length;i++){
227					if(!locked[i]){
228						while(pos++<test.length){
229							//Regex Test each char here.
230							var reChar=new RegExp(charMap[mask.charAt(i)]);
231							if(test.charAt(pos-1).match(reChar)){
232								buffer[i]=test.charAt(pos-1);
233								break;
234							}									
235						}
236					}
237				}
238				var s=writeBuffer();
239				if(!s.match(re)){							
240					input.val("");	
241					clearBuffer(0,mask.length);
242				}					
243			};				
244		});
245	};
246})(jQuery);