diff --git a/src/jquery.mask.js b/src/jquery.mask.js index 521973c8..92b39e4e 100755 --- a/src/jquery.mask.js +++ b/src/jquery.mask.js @@ -197,21 +197,21 @@ behaviour: function(e) { e = e || window.event; p.invalid = []; - var keyCode = e.keyCode || e.which; - if ($.inArray(keyCode, jMask.byPassKeys) === -1) { - var caretPos = p.getCaret(), - currVal = p.val(), - currValL = currVal.length, - changeCaret = caretPos < currValL, - newVal = p.getMasked(), - newValL = newVal.length, - maskDif = p.getMCharsBeforeCount(newValL - 1) - p.getMCharsBeforeCount(currValL - 1); + var keyCode = el.data('mask-keycode'); + + if ($.inArray(keyCode, jMask.byPassKeys) === -1) { + var caretPos = p.getCaret(), + currVal = p.val(), + currValL = currVal.length, + newVal = p.getMasked(), + newValL = newVal.length, + maskDif = p.getMCharsBeforeCount(newValL - 1) - p.getMCharsBeforeCount(currValL - 1), + changeCaret = caretPos < currValL; p.val(newVal); - // change caret but avoid CTRL+A - if (changeCaret && !(keyCode === 65 && e.ctrlKey)) { + if (changeCaret) { // Avoid adjusting caret on backspace or delete if (!(keyCode === 8 || keyCode === 46)) { caretPos = p.caretPos(caretPos, currValL, newValL, maskDif); @@ -359,7 +359,7 @@ // this is necessary, otherwise if the user submit the form // and then press the "back" button, the autocomplete will erase // the data. Works fine on IE9+, FF, Opera, Safari. - if ($('input').length && 'oninput' in $('input')[0] === false && el.attr('autocomplete') === 'on') { + if (el.data('mask')) { el.attr('autocomplete', 'off'); } @@ -381,40 +381,52 @@ $.maskWatchers = {}; var HTMLAttributes = function () { - var input = $(this), - options = {}, - prefix = 'data-mask-', - mask = input.attr('data-mask'); + var input = $(this), + options = {}, + prefix = 'data-mask-', + mask = input.attr('data-mask'); - if (input.attr(prefix + 'reverse')) { - options.reverse = true; - } + if (input.attr(prefix + 'reverse')) { + options.reverse = true; + } - if (input.attr(prefix + 'clearifnotmatch')) { - options.clearIfNotMatch = true; - } + if (input.attr(prefix + 'clearifnotmatch')) { + options.clearIfNotMatch = true; + } - if (input.attr(prefix + 'selectonfocus') === 'true') { - options.selectOnFocus = true; - } + if (input.attr(prefix + 'selectonfocus') === 'true') { + options.selectOnFocus = true; + } - if (notSameMaskObject(input, mask, options)) { - return input.data('mask', new Mask(this, mask, options)); + if (notSameMaskObject(input, mask, options)) { + return input.data('mask', new Mask(this, mask, options)); + } + }, + notSameMaskObject = function(field, mask, options) { + options = options || {}; + var maskObject = $(field).data('mask'), + stringify = JSON.stringify, + value = $(field).val() || $(field).text(); + try { + if (typeof mask === 'function') { + mask = mask(value); } - }, - notSameMaskObject = function(field, mask, options) { - options = options || {}; - var maskObject = $(field).data('mask'), - stringify = JSON.stringify, - value = $(field).val() || $(field).text(); - try { - if (typeof mask === 'function') { - mask = mask(value); - } - return typeof maskObject !== 'object' || stringify(maskObject.options) !== stringify(options) || maskObject.mask !== mask; - } catch (e) {} - }; + return typeof maskObject !== 'object' || stringify(maskObject.options) !== stringify(options) || maskObject.mask !== mask; + } catch (e) {} + }, + eventSupported = function(eventName) { + var el = document.createElement("div"); + eventName = "on" + eventName; + + var isSupported = (eventName in el); + if ( !isSupported ) { + el.setAttribute(eventName, "return;"); + isSupported = typeof el[eventName] === "function"; + } + el = null; + return isSupported; + }; $.fn.mask = function(mask, options) { options = options || {}; @@ -465,6 +477,7 @@ dataMask: true, watchInterval: 300, watchInputs: true, + useInput: eventSupported('input'), watchDataMask: false, byPassKeys: [9, 16, 17, 18, 36, 37, 38, 39, 40, 91], translation: { diff --git a/test/jquery.mask.test.js b/test/jquery.mask.test.js index c0c589d2..37848694 100644 --- a/test/jquery.mask.test.js +++ b/test/jquery.mask.test.js @@ -10,10 +10,10 @@ $(document).ready(function(){ typeTest = function (typedValue, obj) { obj = typeof obj === "undefined" ? testfield : obj; - return obj.keydown().val(typedValue).keyup().val(); + return obj.keydown().val(typedValue).trigger('input').val(); }, typeDivTest = function(typedValue){ - return testdiv.keydown().text(typedValue).keyup().text(); + return testdiv.keydown().text(typedValue).trigger('input').text(); }; module('Setting Up'); @@ -49,11 +49,11 @@ $(document).ready(function(){ test("When I change the mask on-the-fly with onChange callback things should work normally", function(){ - var masks = ['0000.00009', '0.0000.0000']; + var masks = ['0000.00009', '0.0000.0000']; var SPphoneMask = function(phone){ return phone.length <= 9 ? masks[0] : masks[1]; }; - + testfield.mask(SPphoneMask, {onChange: function(phone, e, currentField, options){ $(currentField).mask(SPphoneMask(phone), options); }}); @@ -67,16 +67,16 @@ $(document).ready(function(){ equal( typeTest("1234567"), "1234.567"); equal( typeTest("12345678"), "1234.5678"); equal( typeTest("123456789"), "1.2345.6789"); - + }); test("When I change the mask on-the-fly with onKeyPress callback things should work normally", function(){ - var masks = ['0000.00009', '0.0000.0000']; + var masks = ['0000.00009', '0.0000.0000']; var SPphoneMask = function(phone){ return phone.length <= 9 ? masks[0] : masks[1]; }; - + testfield.mask(SPphoneMask, {onKeyPress: function(phone, e, currentField, options){ $(currentField).mask(SPphoneMask(phone), options); }}); @@ -90,7 +90,7 @@ $(document).ready(function(){ equal( typeTest("1234567"), "1234.567"); equal( typeTest("12345678"), "1234.5678"); equal( typeTest("123456789"), "1.2345.6789"); - + }); test("#onInvalid callback. should call when invalid", function(){ @@ -138,10 +138,10 @@ $(document).ready(function(){ equal( typeTest("00/00/0"), "00/00/0"); equal( typeTest("00/00/00"), "00/00/00"); }); - + test("Testing masks with a literal on the last char", function () { testfield.mask("(99)"); - + equal( typeTest("(99"), "(99)"); }); @@ -226,7 +226,7 @@ $(document).ready(function(){ equal( typeTest("12.345.678-90"), "12.345.678-90"); equal( typeTest("123.456.789-00"), "123.456.789-00"); equal( typeTest("123.456.789-00"), "123.456.789-00"); - + equal( typeTest("123.456.789a00"), "123.456.789-00"); equal( typeTest("123-a5"), "12-35"); @@ -266,7 +266,7 @@ $(document).ready(function(){ equal(typeTest("12.345.678,9"), "1.234.567,89"); equal(typeTest("1.234.567,8"), "123.456,78"); }); - + test("Testing numbers with recursive mask", function(){ testfield.mask("0#.#"); @@ -284,7 +284,7 @@ $(document).ready(function(){ equal(typeTest("12.34.56"), "12.34.56"); equal(typeTest("12.34.5"), "12.34.5"); }); - + test("Testing numbers with recursive mask with one #", function(){ testfield.mask("0#", {}); @@ -319,7 +319,7 @@ $(document).ready(function(){ }); test("Testing reversible masks with a literal on the last char", function () { testfield.mask("(99)"); - + equal( typeTest("(99"), "(99)"); }); @@ -382,7 +382,7 @@ $(document).ready(function(){ testfield.mask('11/00/1111'); equal( typeTest('12/12/5678'), '12/00/1256'); - + $.jMaskGlobals.translation = old_translation; }); @@ -457,11 +457,11 @@ $(document).ready(function(){ equal( typeDivTest('00000000'), '00/00/0000'); equal( typeDivTest('00/00/0000'), '00/00/0000'); equal( typeDivTest('0a/00/0000'), '00/00/000'); - + }); module('Testing data-mask attribute support'); - + test("Testing data-mask attribute", function(){ equal( typeTest("00/", testfieldDataMask), "00/"); equal( typeTest("00a", testfieldDataMask), "00/"); @@ -489,7 +489,7 @@ $(document).ready(function(){ var typeAndBlur = function(typedValue){ testfield.trigger('keydown'); testfield.val(typedValue); - testfield.trigger('keyup'); + testfield.trigger('input'); testfield.trigger("blur"); }; @@ -519,7 +519,7 @@ $(document).ready(function(){ }); } - + test('onDrop Test', function(){ ok(true, "todo"); @@ -529,7 +529,7 @@ $(document).ready(function(){ test('test when clearifnotmatch javascript notation', 4, function(){ var typeAndFocusOut = function(typedValue){ - testfield.keydown().val(typedValue).keyup(); + testfield.keydown().val(typedValue).trigger('input'); testfield.trigger("focusout"); }; @@ -552,7 +552,7 @@ $(document).ready(function(){ test('test when clearifnotmatch javascript notation #2', 4, function(){ var typeAndFocusOut = function(typedValue){ - testfield.keydown().val(typedValue).keyup(); + testfield.keydown().val(typedValue).trigger('input'); testfield.trigger("focusout"); }; @@ -575,7 +575,7 @@ $(document).ready(function(){ test('test when clearifnotmatch is HTML notation', 3, function(){ var typeAndFocusOut = function(typedValue){ - testfieldDataMaskWithClearIfNotMatch.keydown().val(typedValue).keyup(); + testfieldDataMaskWithClearIfNotMatch.keydown().val(typedValue).trigger('input'); testfieldDataMaskWithClearIfNotMatch.trigger("focusout"); }; @@ -601,7 +601,7 @@ $(document).ready(function(){ test('test when clearifnotmatch with optional mask', 9, function(){ // html notation var typeAndBlur = function(field, typedValue){ - field.keydown().val(typedValue).keyup(); + field.keydown().val(typedValue).trigger('input'); field.trigger("focusout"); }; @@ -639,7 +639,7 @@ $(document).ready(function(){ test('test when clearifnotmatch with recursive mask', 4, function(){ // html notation var typeAndBlur = function(field, typedValue){ - field.keydown().val(typedValue).keyup(); + field.keydown().val(typedValue).trigger('input'); field.trigger("focusout"); }; @@ -670,7 +670,7 @@ $(document).ready(function(){ var c = 0; function write() { - + if (c >= 5) { clearInterval(ticker); clearInterval(tester); @@ -679,12 +679,12 @@ $(document).ready(function(){ c++; - $container.append('