Subversion-Projekte lars-tiefland.marine-sales.de

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
2 lars 1
/*
2
	Masked Input plugin for jQuery
3
	Copyright (c) 2007-2013 Josh Bush (digitalbush.com)
4
	Licensed under the MIT license (http://digitalbush.com/projects/masked-input-plugin/#license)
5
	Version: 1.3.1
6
*/
7
(function($) {
8
	function getPasteEvent() {
9
    var el = document.createElement('input'),
10
        name = 'onpaste';
11
    el.setAttribute(name, '');
12
    return (typeof el[name] === 'function')?'paste':'input';
13
}
14
 
15
var pasteEventName = getPasteEvent() + ".mask",
16
	ua = navigator.userAgent,
17
	iPhone = /iphone/i.test(ua),
18
	android=/android/i.test(ua),
19
	caretTimeoutId;
20
 
21
$.mask = {
22
	//Predefined character definitions
23
	definitions: {
24
		'9': "[0-9]",
25
		'a': "[A-Za-z]",
26
		'*': "[A-Za-z0-9]"
27
	},
28
	dataName: "rawMaskFn",
29
	placeholder: '_',
30
};
31
 
32
$.fn.extend({
33
	//Helper Function for Caret positioning
34
	caret: function(begin, end) {
35
		var range;
36
 
37
		if (this.length === 0 || this.is(":hidden")) {
38
			return;
39
		}
40
 
41
		if (typeof begin == 'number') {
42
			end = (typeof end === 'number') ? end : begin;
43
			return this.each(function() {
44
				if (this.setSelectionRange) {
45
					this.setSelectionRange(begin, end);
46
				} else if (this.createTextRange) {
47
					range = this.createTextRange();
48
					range.collapse(true);
49
					range.moveEnd('character', end);
50
					range.moveStart('character', begin);
51
					range.select();
52
				}
53
			});
54
		} else {
55
			if (this[0].setSelectionRange) {
56
				begin = this[0].selectionStart;
57
				end = this[0].selectionEnd;
58
			} else if (document.selection && document.selection.createRange) {
59
				range = document.selection.createRange();
60
				begin = 0 - range.duplicate().moveStart('character', -100000);
61
				end = begin + range.text.length;
62
			}
63
			return { begin: begin, end: end };
64
		}
65
	},
66
	unmask: function() {
67
		return this.trigger("unmask");
68
	},
69
	mask: function(mask, settings) {
70
		var input,
71
			defs,
72
			tests,
73
			partialPosition,
74
			firstNonMaskPos,
75
			len;
76
 
77
		if (!mask && this.length > 0) {
78
			input = $(this[0]);
79
			return input.data($.mask.dataName)();
80
		}
81
		settings = $.extend({
82
			placeholder: $.mask.placeholder, // Load default placeholder
83
			completed: null
84
		}, settings);
85
 
86
 
87
		defs = $.mask.definitions;
88
		tests = [];
89
		partialPosition = len = mask.length;
90
		firstNonMaskPos = null;
91
 
92
		$.each(mask.split(""), function(i, c) {
93
			if (c == '?') {
94
				len--;
95
				partialPosition = i;
96
			} else if (defs[c]) {
97
				tests.push(new RegExp(defs[c]));
98
				if (firstNonMaskPos === null) {
99
					firstNonMaskPos = tests.length - 1;
100
				}
101
			} else {
102
				tests.push(null);
103
			}
104
		});
105
 
106
		return this.trigger("unmask").each(function() {
107
			var input = $(this),
108
				buffer = $.map(
109
				mask.split(""),
110
				function(c, i) {
111
					if (c != '?') {
112
						return defs[c] ? settings.placeholder : c;
113
					}
114
				}),
115
				focusText = input.val();
116
 
117
			function seekNext(pos) {
118
				while (++pos < len && !tests[pos]);
119
				return pos;
120
			}
121
 
122
			function seekPrev(pos) {
123
				while (--pos >= 0 && !tests[pos]);
124
				return pos;
125
			}
126
 
127
			function shiftL(begin,end) {
128
				var i,
129
					j;
130
 
131
				if (begin<0) {
132
					return;
133
				}
134
 
135
				for (i = begin, j = seekNext(end); i < len; i++) {
136
					if (tests[i]) {
137
						if (j < len && tests[i].test(buffer[j])) {
138
							buffer[i] = buffer[j];
139
							buffer[j] = settings.placeholder;
140
						} else {
141
							break;
142
						}
143
 
144
						j = seekNext(j);
145
					}
146
				}
147
				writeBuffer();
148
				input.caret(Math.max(firstNonMaskPos, begin));
149
			}
150
 
151
			function shiftR(pos) {
152
				var i,
153
					c,
154
					j,
155
					t;
156
 
157
				for (i = pos, c = settings.placeholder; i < len; i++) {
158
					if (tests[i]) {
159
						j = seekNext(i);
160
						t = buffer[i];
161
						buffer[i] = c;
162
						if (j < len && tests[j].test(t)) {
163
							c = t;
164
						} else {
165
							break;
166
						}
167
					}
168
				}
169
			}
170
 
171
			function keydownEvent(e) {
172
				var k = e.which,
173
					pos,
174
					begin,
175
					end;
176
 
177
				//backspace, delete, and escape get special treatment
178
				if (k === 8 || k === 46 || (iPhone && k === 127)) {
179
					pos = input.caret();
180
					begin = pos.begin;
181
					end = pos.end;
182
 
183
					if (end - begin === 0) {
184
						begin=k!==46?seekPrev(begin):(end=seekNext(begin-1));
185
						end=k===46?seekNext(end):end;
186
					}
187
					clearBuffer(begin, end);
188
					shiftL(begin, end - 1);
189
 
190
					e.preventDefault();
191
				} else if (k == 27) {//escape
192
					input.val(focusText);
193
					input.caret(0, checkVal());
194
					e.preventDefault();
195
				}
196
			}
197
 
198
			function keypressEvent(e) {
199
				var k = e.which,
200
					pos = input.caret(),
201
					p,
202
					c,
203
					next;
204
 
205
				if (e.ctrlKey || e.altKey || e.metaKey || k < 32) {//Ignore
206
					return;
207
				} else if (k) {
208
					if (pos.end - pos.begin !== 0){
209
						clearBuffer(pos.begin, pos.end);
210
						shiftL(pos.begin, pos.end-1);
211
					}
212
 
213
					p = seekNext(pos.begin - 1);
214
					if (p < len) {
215
						c = String.fromCharCode(k);
216
						if (tests[p].test(c)) {
217
							shiftR(p);
218
 
219
							buffer[p] = c;
220
							writeBuffer();
221
							next = seekNext(p);
222
 
223
							if(android){
224
								setTimeout($.proxy($.fn.caret,input,next),0);
225
							}else{
226
								input.caret(next);
227
							}
228
 
229
							if (settings.completed && next >= len) {
230
								settings.completed.call(input);
231
							}
232
						}
233
					}
234
					e.preventDefault();
235
				}
236
			}
237
 
238
			function clearBuffer(start, end) {
239
				var i;
240
				for (i = start; i < end && i < len; i++) {
241
					if (tests[i]) {
242
						buffer[i] = settings.placeholder;
243
					}
244
				}
245
			}
246
 
247
			function writeBuffer() { input.val(buffer.join('')); }
248
 
249
			function checkVal(allow) {
250
				//try to place characters where they belong
251
				var test = input.val(),
252
					lastMatch = -1,
253
					i,
254
					c;
255
 
256
				for (i = 0, pos = 0; i < len; i++) {
257
					if (tests[i]) {
258
						buffer[i] = settings.placeholder;
259
						while (pos++ < test.length) {
260
							c = test.charAt(pos - 1);
261
							if (tests[i].test(c)) {
262
								buffer[i] = c;
263
								lastMatch = i;
264
								break;
265
							}
266
						}
267
						if (pos > test.length) {
268
							break;
269
						}
270
					} else if (buffer[i] === test.charAt(pos) && i !== partialPosition) {
271
						pos++;
272
						lastMatch = i;
273
					}
274
				}
275
				if (allow) {
276
					writeBuffer();
277
				} else if (lastMatch + 1 < partialPosition) {
278
					input.val("");
279
					clearBuffer(0, len);
280
				} else {
281
					writeBuffer();
282
					input.val(input.val().substring(0, lastMatch + 1));
283
				}
284
				return (partialPosition ? i : firstNonMaskPos);
285
			}
286
 
287
			input.data($.mask.dataName,function(){
288
				return $.map(buffer, function(c, i) {
289
					return tests[i]&&c!=settings.placeholder ? c : null;
290
				}).join('');
291
			});
292
 
293
			if (!input.attr("readonly"))
294
				input
295
				.one("unmask", function() {
296
					input
297
						.unbind(".mask")
298
						.removeData($.mask.dataName);
299
				})
300
				.bind("focus.mask", function() {
301
					clearTimeout(caretTimeoutId);
302
					var pos,
303
						moveCaret;
304
 
305
					focusText = input.val();
306
					pos = checkVal();
307
 
308
					caretTimeoutId = setTimeout(function(){
309
						writeBuffer();
310
						if (pos == mask.length) {
311
							input.caret(0, pos);
312
						} else {
313
							input.caret(pos);
314
						}
315
					}, 10);
316
				})
317
				.bind("blur.mask", function() {
318
					checkVal();
319
					if (input.val() != focusText)
320
						input.change();
321
				})
322
				.bind("keydown.mask", keydownEvent)
323
				.bind("keypress.mask", keypressEvent)
324
				.bind(pasteEventName, function() {
325
					setTimeout(function() {
326
						var pos=checkVal(true);
327
						input.caret(pos);
328
						if (settings.completed && pos == input.val().length)
329
							settings.completed.call(input);
330
					}, 0);
331
				});
332
			checkVal(); //Perform initial check for existing values
333
		});
334
	}
335
});
336
 
337
 
338
})(jQuery);