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

Revision

Blame | Letzte Änderung | Log anzeigen | RSS feed

/*
        Masked Input plugin for jQuery
        Copyright (c) 2007-2013 Josh Bush (digitalbush.com)
        Licensed under the MIT license (http://digitalbush.com/projects/masked-input-plugin/#license)
        Version: 1.3.1
*/
(function($) {
        function getPasteEvent() {
    var el = document.createElement('input'),
        name = 'onpaste';
    el.setAttribute(name, '');
    return (typeof el[name] === 'function')?'paste':'input';
}

var pasteEventName = getPasteEvent() + ".mask",
        ua = navigator.userAgent,
        iPhone = /iphone/i.test(ua),
        android=/android/i.test(ua),
        caretTimeoutId;

$.mask = {
        //Predefined character definitions
        definitions: {
                '9': "[0-9]",
                'a': "[A-Za-z]",
                '*': "[A-Za-z0-9]"
        },
        dataName: "rawMaskFn",
        placeholder: '_',
};

$.fn.extend({
        //Helper Function for Caret positioning
        caret: function(begin, end) {
                var range;

                if (this.length === 0 || this.is(":hidden")) {
                        return;
                }

                if (typeof begin == 'number') {
                        end = (typeof end === 'number') ? end : begin;
                        return this.each(function() {
                                if (this.setSelectionRange) {
                                        this.setSelectionRange(begin, end);
                                } else if (this.createTextRange) {
                                        range = this.createTextRange();
                                        range.collapse(true);
                                        range.moveEnd('character', end);
                                        range.moveStart('character', begin);
                                        range.select();
                                }
                        });
                } else {
                        if (this[0].setSelectionRange) {
                                begin = this[0].selectionStart;
                                end = this[0].selectionEnd;
                        } else if (document.selection && document.selection.createRange) {
                                range = document.selection.createRange();
                                begin = 0 - range.duplicate().moveStart('character', -100000);
                                end = begin + range.text.length;
                        }
                        return { begin: begin, end: end };
                }
        },
        unmask: function() {
                return this.trigger("unmask");
        },
        mask: function(mask, settings) {
                var input,
                        defs,
                        tests,
                        partialPosition,
                        firstNonMaskPos,
                        len;

                if (!mask && this.length > 0) {
                        input = $(this[0]);
                        return input.data($.mask.dataName)();
                }
                settings = $.extend({
                        placeholder: $.mask.placeholder, // Load default placeholder
                        completed: null
                }, settings);


                defs = $.mask.definitions;
                tests = [];
                partialPosition = len = mask.length;
                firstNonMaskPos = null;

                $.each(mask.split(""), function(i, c) {
                        if (c == '?') {
                                len--;
                                partialPosition = i;
                        } else if (defs[c]) {
                                tests.push(new RegExp(defs[c]));
                                if (firstNonMaskPos === null) {
                                        firstNonMaskPos = tests.length - 1;
                                }
                        } else {
                                tests.push(null);
                        }
                });

                return this.trigger("unmask").each(function() {
                        var input = $(this),
                                buffer = $.map(
                                mask.split(""),
                                function(c, i) {
                                        if (c != '?') {
                                                return defs[c] ? settings.placeholder : c;
                                        }
                                }),
                                focusText = input.val();

                        function seekNext(pos) {
                                while (++pos < len && !tests[pos]);
                                return pos;
                        }

                        function seekPrev(pos) {
                                while (--pos >= 0 && !tests[pos]);
                                return pos;
                        }

                        function shiftL(begin,end) {
                                var i,
                                        j;

                                if (begin<0) {
                                        return;
                                }

                                for (i = begin, j = seekNext(end); i < len; i++) {
                                        if (tests[i]) {
                                                if (j < len && tests[i].test(buffer[j])) {
                                                        buffer[i] = buffer[j];
                                                        buffer[j] = settings.placeholder;
                                                } else {
                                                        break;
                                                }

                                                j = seekNext(j);
                                        }
                                }
                                writeBuffer();
                                input.caret(Math.max(firstNonMaskPos, begin));
                        }

                        function shiftR(pos) {
                                var i,
                                        c,
                                        j,
                                        t;

                                for (i = pos, c = settings.placeholder; i < len; i++) {
                                        if (tests[i]) {
                                                j = seekNext(i);
                                                t = buffer[i];
                                                buffer[i] = c;
                                                if (j < len && tests[j].test(t)) {
                                                        c = t;
                                                } else {
                                                        break;
                                                }
                                        }
                                }
                        }

                        function keydownEvent(e) {
                                var k = e.which,
                                        pos,
                                        begin,
                                        end;

                                //backspace, delete, and escape get special treatment
                                if (k === 8 || k === 46 || (iPhone && k === 127)) {
                                        pos = input.caret();
                                        begin = pos.begin;
                                        end = pos.end;

                                        if (end - begin === 0) {
                                                begin=k!==46?seekPrev(begin):(end=seekNext(begin-1));
                                                end=k===46?seekNext(end):end;
                                        }
                                        clearBuffer(begin, end);
                                        shiftL(begin, end - 1);

                                        e.preventDefault();
                                } else if (k == 27) {//escape
                                        input.val(focusText);
                                        input.caret(0, checkVal());
                                        e.preventDefault();
                                }
                        }

                        function keypressEvent(e) {
                                var k = e.which,
                                        pos = input.caret(),
                                        p,
                                        c,
                                        next;

                                if (e.ctrlKey || e.altKey || e.metaKey || k < 32) {//Ignore
                                        return;
                                } else if (k) {
                                        if (pos.end - pos.begin !== 0){
                                                clearBuffer(pos.begin, pos.end);
                                                shiftL(pos.begin, pos.end-1);
                                        }

                                        p = seekNext(pos.begin - 1);
                                        if (p < len) {
                                                c = String.fromCharCode(k);
                                                if (tests[p].test(c)) {
                                                        shiftR(p);

                                                        buffer[p] = c;
                                                        writeBuffer();
                                                        next = seekNext(p);

                                                        if(android){
                                                                setTimeout($.proxy($.fn.caret,input,next),0);
                                                        }else{
                                                                input.caret(next);
                                                        }

                                                        if (settings.completed && next >= len) {
                                                                settings.completed.call(input);
                                                        }
                                                }
                                        }
                                        e.preventDefault();
                                }
                        }

                        function clearBuffer(start, end) {
                                var i;
                                for (i = start; i < end && i < len; i++) {
                                        if (tests[i]) {
                                                buffer[i] = settings.placeholder;
                                        }
                                }
                        }

                        function writeBuffer() { input.val(buffer.join('')); }

                        function checkVal(allow) {
                                //try to place characters where they belong
                                var test = input.val(),
                                        lastMatch = -1,
                                        i,
                                        c;

                                for (i = 0, pos = 0; i < len; i++) {
                                        if (tests[i]) {
                                                buffer[i] = settings.placeholder;
                                                while (pos++ < test.length) {
                                                        c = test.charAt(pos - 1);
                                                        if (tests[i].test(c)) {
                                                                buffer[i] = c;
                                                                lastMatch = i;
                                                                break;
                                                        }
                                                }
                                                if (pos > test.length) {
                                                        break;
                                                }
                                        } else if (buffer[i] === test.charAt(pos) && i !== partialPosition) {
                                                pos++;
                                                lastMatch = i;
                                        }
                                }
                                if (allow) {
                                        writeBuffer();
                                } else if (lastMatch + 1 < partialPosition) {
                                        input.val("");
                                        clearBuffer(0, len);
                                } else {
                                        writeBuffer();
                                        input.val(input.val().substring(0, lastMatch + 1));
                                }
                                return (partialPosition ? i : firstNonMaskPos);
                        }

                        input.data($.mask.dataName,function(){
                                return $.map(buffer, function(c, i) {
                                        return tests[i]&&c!=settings.placeholder ? c : null;
                                }).join('');
                        });

                        if (!input.attr("readonly"))
                                input
                                .one("unmask", function() {
                                        input
                                                .unbind(".mask")
                                                .removeData($.mask.dataName);
                                })
                                .bind("focus.mask", function() {
                                        clearTimeout(caretTimeoutId);
                                        var pos,
                                                moveCaret;

                                        focusText = input.val();
                                        pos = checkVal();

                                        caretTimeoutId = setTimeout(function(){
                                                writeBuffer();
                                                if (pos == mask.length) {
                                                        input.caret(0, pos);
                                                } else {
                                                        input.caret(pos);
                                                }
                                        }, 10);
                                })
                                .bind("blur.mask", function() {
                                        checkVal();
                                        if (input.val() != focusText)
                                                input.change();
                                })
                                .bind("keydown.mask", keydownEvent)
                                .bind("keypress.mask", keypressEvent)
                                .bind(pasteEventName, function() {
                                        setTimeout(function() {
                                                var pos=checkVal(true);
                                                input.caret(pos);
                                                if (settings.completed && pos == input.val().length)
                                                        settings.completed.call(input);
                                        }, 0);
                                });
                        checkVal(); //Perform initial check for existing values
                });
        }
});


})(jQuery);