colonymech / docs / www / colonyscout / internal / jeditable / js / jquery.maskedinput.js @ f59acf11
History | View | Annotate | Download (6.55 KB)
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); |