PluginProbe
RSVP and Event Management / 1.1.0
RSVP and Event Management v1.1.0
trunk 0.5.0 0.6.0 0.7.0 0.8.0 0.9.0 0.9.5 1.0.0 1.1.0 1.2.0 1.2.1 1.3.0 1.3.1 1.3.2 1.5.0 1.6.0 1.6.1 1.6.2 1.6.5 1.7.0 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 All 136 releases
rsvp / jquery-validate / demo / marketo / jquery.maskedinput.js

jquery.maskedinput.js in RSVP and Event Management 1.1.0, at jquery-validate/demo/marketo/jquery.maskedinput.js

267 lines 7.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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.1
28 * Release: 2007-09-08
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 $.fn.unmask=function(){
73 return this.trigger("unmask");
74 };
75
76 //Main Method
77 $.fn.mask = function(mask,settings) {
78 settings = $.extend({
79 placeholder: "_",
80 completed: null
81 }, settings);
82
83 //Build Regex for format validation
84 var reString="^";
85 for(var i=0;i<mask.length;i++)
86 reString+=(charMap[mask.charAt(i)] || ("\\"+mask.charAt(i)));
87 reString+="$";
88 var re = new RegExp(reString);
89
90 return this.each(function(){
91 var input=$(this);
92 var buffer=new Array(mask.length);
93 var locked=new Array(mask.length);
94
95 //Build buffer layout from mask
96 for(var i=0;i<mask.length;i++){
97 locked[i]=charMap[mask.charAt(i)]==null;
98 buffer[i]=locked[i]?mask.charAt(i):settings.placeholder;
99 }
100
101 /*Event Bindings*/
102 function focusEvent(){
103 checkVal();
104 writeBuffer();
105 setTimeout(function(){
106 setCaretPosition(input[0],0);
107 },0);
108 };
109 input.bind("focus",focusEvent);
110
111 input.bind("blur",checkVal);
112
113 //Paste events for IE and Mozilla thanks to Kristinn Sigmundsson
114 if ($.browser.msie)
115 this.onpaste= function(){setTimeout(checkVal,0);};
116 else if ($.browser.mozilla)
117 this.addEventListener('input',checkVal,false);
118
119 var ignore=false; //Variable for ignoring control keys
120
121 function keydownEvent(e){
122 var pos=getCaretPosition(this);
123 var k = e.keyCode;
124 ignore=(k < 16 || (k > 16 && k < 32 ) || (k > 32 && k < 41));
125
126 //delete selection before proceeding
127 if((pos.begin-pos.end)!=0 && (!ignore || k==8 || k==46)){
128 clearBuffer(pos.begin,pos.end);
129 }
130 //backspace and delete get special treatment
131 if(k==8){//backspace
132 while(pos.begin-->=0){
133 if(!locked[pos.begin]){
134 buffer[pos.begin]=settings.placeholder;
135 if($.browser.opera){
136 //Opera won't let you cancel the backspace, so we'll let it backspace over a dummy character.
137 writeBuffer(pos.begin);
138 setCaretPosition(this,pos.begin+1);
139 }else{
140 writeBuffer();
141 setCaretPosition(this,pos.begin);
142 }
143 return false;
144 }
145 }
146 }else if(k==46){//delete
147 clearBuffer(pos.begin,pos.begin+1);
148 writeBuffer();
149 setCaretPosition(this,pos.begin);
150 return false;
151 }else if (k==27){
152 clearBuffer(0,mask.length);
153 writeBuffer();
154 setCaretPosition(this,0);
155 return false;
156 }
157
158 };
159 input.bind("keydown",keydownEvent);
160
161 function keypressEvent(e){
162 if(ignore){
163 ignore=false;
164 return;
165 }
166 e=e||window.event;
167 var k=e.charCode||e.keyCode||e.which;
168
169 var pos=getCaretPosition(this);
170 var caretPos=pos.begin;
171
172 if(e.ctrlKey || e.altKey){//Ignore
173 return true;
174 }else if ((k>=41 && k<=122) ||k==32 || k>186){//typeable characters
175 while(pos.begin<mask.length){
176 var reString=charMap[mask.charAt(pos.begin)];
177 var match;
178 if(reString){
179 var reChar=new RegExp(reString);
180 match=String.fromCharCode(k).match(reChar);
181 }else{//we're on a mask char, go forward and try again
182 pos.begin+=1;
183 pos.end=pos.begin;
184 caretPos+=1;
185 continue;
186 }
187
188 if(match)
189 buffer[pos.begin]=String.fromCharCode(k);
190 else
191 return false;//reject char
192
193 while(++caretPos<mask.length){//seek forward to next typable position
194 if(!locked[caretPos])
195 break;
196 }
197 break;
198 }
199 }else
200 return false;
201
202 writeBuffer();
203 if(settings.completed && caretPos>=buffer.length)
204 settings.completed.call(input);
205 else
206 setCaretPosition(this,caretPos);
207
208 return false;
209 };
210 input.bind("keypress",keypressEvent);
211
212 /*Helper Methods*/
213 function clearBuffer(start,end){
214 for(var i=start;i<end;i++){
215 if(!locked[i])
216 buffer[i]=settings.placeholder;
217 }
218 };
219
220 function writeBuffer(pos){
221 var s="";
222 for(var i=0;i<mask.length;i++){
223 s+=buffer[i];
224 if(i==pos)
225 s+=settings.placeholder;
226 }
227 input.val(s);
228 return s;
229 };
230
231 function checkVal(){
232 //try to place charcters where they belong
233 var test=input.val();
234 var pos=0;
235 for(var i=0;i<mask.length;i++){
236 if(!locked[i]){
237 while(pos++<test.length){
238 //Regex Test each char here.
239 var reChar=new RegExp(charMap[mask.charAt(i)]);
240 if(test.charAt(pos-1).match(reChar)){
241 buffer[i]=test.charAt(pos-1);
242 break;
243 }
244 }
245 }
246 }
247 var s=writeBuffer();
248 if(!s.match(re)){
249 input.val("");
250 clearBuffer(0,mask.length);
251 }
252 };
253
254 input.one("unmask",function(){
255 input.unbind("focus",focusEvent);
256 input.unbind("blur",checkVal);
257 input.unbind("keydown",keydownEvent);
258 input.unbind("keypress",keypressEvent);
259 if ($.browser.msie)
260 this.onpaste= null;
261 else if ($.browser.mozilla)
262 this.removeEventListener('input',checkVal,false);
263 });
264
265 });
266 };
267 })(jQuery);