Browse Source

enhance caret positioning

Robin Herbots 10 years ago
parent
commit
0b25ae45ec

+ 1 - 0
CHANGELOG.md

@@ -22,6 +22,7 @@ All notable changes to this project will be documented in this file.
   - Inputmask.extendAliases
 
 ### Updates
+- enhance caret positioning behavior & radicFocus
 - change alfanumeric uppercase definition from # to &
 - numericInput option also possible on dynamic-masks
 - remove $.inputmask in favor of Inputmask class

+ 1 - 1
bower.json

@@ -1,6 +1,6 @@
 {
   "name": "jquery.inputmask",
-  "version": "3.1.64-154",
+  "version": "3.1.64-155",
   "main": [
     "./dist/inputmask/jquery.inputmask.js",
     "./dist/inputmask/inputmask.js",

+ 1 - 1
component.json

@@ -2,7 +2,7 @@
     "name": "jquery_inputmask",
     "repository": "robinherbots/jquery.inputmask",
     "description": "jquery.inputmask is a jquery plugin which create an input mask.",
-    "version": "3.1.64-154",
+    "version": "3.1.64-155",
     "keywords": [ "jquery", "plugins", "input", "form", "inputmask", "mask" ],
     "main": "./dist/jquery.inputmask.bundle.js",
     "scripts": [

+ 1 - 1
composer.json

@@ -1,7 +1,7 @@
 {
     "name": "robinherbots/jquery.inputmask",
     "description": "jquery.inputmask is a jquery plugin which create an input mask.",
-	"version": "3.1.64-154",
+	"version": "3.1.64-155",
     "type": "library",
     "keywords": ["jquery", "plugins", "input", "form", "inputmask", "mask"],
     "homepage": "http://robinherbots.github.io/jquery.inputmask",

+ 1 - 1
dist/inputmask/inputmask.date.extensions.js

@@ -3,7 +3,7 @@
 * http://github.com/RobinHerbots/jquery.inputmask
 * Copyright (c) 2010 - 2015 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 3.1.64-154
+* Version: 3.1.64-155
 */
 !function(factory) {
     "function" == typeof define && define.amd ? define([ "jquery", "./inputmask" ], factory) : "object" == typeof exports ? module.exports = factory(require("jquery"), require("./inputmask")) : factory(jQuery);

File diff suppressed because it is too large
+ 1 - 1
dist/inputmask/inputmask.date.extensions.min.js


+ 1 - 1
dist/inputmask/inputmask.extensions.js

@@ -3,7 +3,7 @@
 * http://github.com/RobinHerbots/jquery.inputmask
 * Copyright (c) 2010 - 2015 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 3.1.64-154
+* Version: 3.1.64-155
 */
 !function(factory) {
     "function" == typeof define && define.amd ? define([ "jquery", "./inputmask" ], factory) : "object" == typeof exports ? module.exports = factory(require("jquery"), require("./inputmask")) : factory(jQuery);

File diff suppressed because it is too large
+ 1 - 1
dist/inputmask/inputmask.extensions.min.js


+ 23 - 10
dist/inputmask/inputmask.js

@@ -3,7 +3,7 @@
 * http://github.com/RobinHerbots/jquery.inputmask
 * Copyright (c) 2010 - 2015 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 3.1.64-154
+* Version: 3.1.64-155
 */
 !function(factory) {
     "function" == typeof define && define.amd ? define([ "jquery" ], factory) : "object" == typeof exports ? module.exports = factory(require("jquery")) : factory(jQuery);
@@ -776,7 +776,7 @@
                     if ("inputmask" === eventHandler.namespace) {
                         var handler = eventHandler.handler;
                         eventHandler.handler = function(e) {
-                            if (console.log("triggered " + e.type), void 0 === this.inputmask) {
+                            if (void 0 === this.inputmask) {
                                 var imOpts = $(this).data("_inputmask_opts");
                                 imOpts ? new Inputmask(imOpts).mask(this) : $(this).unbind(".inputmask");
                             } else {
@@ -1043,7 +1043,7 @@
                 var $input = $(this), input = this;
                 if (input.inputmask) {
                     var nptValue = input.inputmask._valueGet(), buffer = getBuffer().slice();
-                    firstClick = !0, undoValue !== buffer.join("") && setTimeout(function() {
+                    undoValue !== buffer.join("") && setTimeout(function() {
                         $input.change(), undoValue = buffer.join("");
                     }, 0), "" !== nptValue && (opts.clearMaskOnLostFocus && (-1 === getLastValidPosition() && nptValue === getBufferTemplate().join("") ? buffer = [] : clearOptionalTail(buffer)), 
                     isComplete(buffer) === !1 && (setTimeout(function() {
@@ -1052,7 +1052,7 @@
                     writeBuffer(input, buffer, void 0, e));
                 }
             }).bind("focus.inputmask", function(e) {
-                var input = ($(this), this), nptValue = input.inputmask._valueGet();
+                var input = this, nptValue = input.inputmask._valueGet();
                 opts.showMaskOnFocus && (!opts.showMaskOnHover || opts.showMaskOnHover && "" === nptValue) ? input.inputmask._valueGet() !== getBuffer().join("") && writeBuffer(input, getBuffer(), seekNext(getLastValidPosition())) : mouseEnter === !1 && caret(input, seekNext(getLastValidPosition())), 
                 opts.positionCaretOnTab === !0 && setTimeout(function() {
                     caret(input, seekNext(getLastValidPosition()));
@@ -1065,13 +1065,26 @@
                     writeBuffer(input, buffer));
                 }
             }).bind("click.inputmask", function() {
-                var $input = $(this), input = this;
-                if ($input.is(":focus")) {
+                function doRadixFocus(clickPos) {
+                    if (opts.radixFocus && "" !== opts.radixPoint) {
+                        var vps = getMaskSet().validPositions;
+                        if (void 0 === vps[clickPos] || vps[clickPos].input === getPlaceholder(clickPos)) {
+                            if (clickPos < seekNext(-1)) return !0;
+                            var radixPos = $.inArray(opts.radixPoint, getBuffer());
+                            if (-1 !== radixPos) {
+                                for (var vp in vps) if (vp > radixPos && vps[vp].input !== getPlaceholder(vp)) return !1;
+                                return !0;
+                            }
+                        }
+                    }
+                    return !1;
+                }
+                var input = this;
+                if ($(input).is(":focus")) {
                     var selectedCaret = caret(input);
-                    if (selectedCaret.begin === selectedCaret.end) if (opts.radixFocus && "" !== opts.radixPoint && -1 !== $.inArray(opts.radixPoint, getBuffer()) && (firstClick || getBuffer().join("") === getBufferTemplate().join(""))) caret(input, $.inArray(opts.radixPoint, getBuffer())), 
-                    firstClick = !1; else {
+                    if (selectedCaret.begin === selectedCaret.end) if (doRadixFocus(selectedCaret.begin)) caret(input, $.inArray(opts.radixPoint, getBuffer())); else {
                         var clickPosition = selectedCaret.begin, lastPosition = seekNext(getLastValidPosition(clickPosition));
-                        lastPosition > clickPosition ? caret(input, isMask(clickPosition) ? clickPosition : seekNext(clickPosition)) : caret(input, opts.numericInput ? 0 : lastPosition);
+                        lastPosition > clickPosition ? caret(input, isMask(clickPosition) || isMask(clickPosition - 1) ? clickPosition : seekNext(clickPosition)) : caret(input, opts.numericInput ? 0 : lastPosition);
                     }
                 }
             }).bind("dblclick.inputmask", function() {
@@ -1110,7 +1123,7 @@
             writeBuffer(el, buffer), activeElement === el && caret(el, seekNext(getLastValidPosition())), 
             installEventRuler(el);
         }
-        var undoValue, compositionCaretPos, compositionData, el, $el, maxLength, valueBuffer, isRTL = !1, skipKeyPressEvent = !1, skipInputEvent = !1, ignorable = !1, firstClick = !0, mouseEnter = !0;
+        var undoValue, compositionCaretPos, compositionData, el, $el, maxLength, valueBuffer, isRTL = !1, skipKeyPressEvent = !1, skipInputEvent = !1, ignorable = !1, mouseEnter = !0;
         if (void 0 !== actionObj) switch (actionObj.action) {
           case "isComplete":
             return el = actionObj.el, $el = $(el), maskset = el.inputmask.maskset, opts = el.inputmask.opts, 

File diff suppressed because it is too large
+ 3 - 3
dist/inputmask/inputmask.min.js


+ 4 - 7
dist/inputmask/inputmask.numeric.extensions.js

@@ -3,7 +3,7 @@
 * http://github.com/RobinHerbots/jquery.inputmask
 * Copyright (c) 2010 - 2015 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 3.1.64-154
+* Version: 3.1.64-155
 */
 !function(factory) {
     "function" == typeof define && define.amd ? define([ "jquery", "./inputmask" ], factory) : "object" == typeof exports ? module.exports = factory(require("jquery"), require("./inputmask")) : factory(jQuery);
@@ -25,9 +25,9 @@
                     opts.integerDigits < 1 && (opts.integerDigits = "*");
                 }
                 opts.placeholder.length > 1 && (opts.placeholder = opts.placeholder.charAt(0)), 
-                opts.definitions[";"] = opts.definitions["~"], opts.definitions[";"].definitionSymbol = "~", 
-                opts.numericInput === !0 && (opts.radixFocus = !1, opts.digitsOptional = !1, isNaN(opts.digits) && (opts.digits = 2), 
-                opts.decimalProtect = !1);
+                opts.radixFocus = opts.radixFocus && "" !== opts.placeholder, opts.definitions[";"] = opts.definitions["~"], 
+                opts.definitions[";"].definitionSymbol = "~", opts.numericInput === !0 && (opts.radixFocus = !1, 
+                opts.digitsOptional = !1, isNaN(opts.digits) && (opts.digits = 2), opts.decimalProtect = !1);
                 var mask = autoEscape(opts.prefix);
                 return mask += "[+]", mask += "~{1," + opts.integerDigits + "}", void 0 !== opts.digits && (isNaN(opts.digits) || parseInt(opts.digits) > 0) && (mask += opts.digitsOptional ? "[" + (opts.decimalProtect ? ":" : opts.radixPoint) + ";{" + opts.digits + "}]" : (opts.decimalProtect ? ":" : opts.radixPoint) + ";{" + opts.digits + "}"), 
                 "" !== opts.negationSymbol.back && (mask += "[-]"), mask += autoEscape(opts.suffix), 
@@ -417,9 +417,6 @@
             suffix: " %",
             allowPlus: !1,
             allowMinus: !1
-        },
-        numeric2: {
-            alias: "numeric"
         }
     }), Inputmask;
 });

File diff suppressed because it is too large
+ 2 - 2
dist/inputmask/inputmask.numeric.extensions.min.js


+ 1 - 1
dist/inputmask/inputmask.phone.extensions.js

@@ -3,7 +3,7 @@
 * http://github.com/RobinHerbots/jquery.inputmask
 * Copyright (c) 2010 - 2015 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 3.1.64-154
+* Version: 3.1.64-155
 */
 !function(factory) {
     "function" == typeof define && define.amd ? define([ "jquery", "./inputmask" ], factory) : "object" == typeof exports ? module.exports = factory(require("jquery"), require("./inputmask")) : factory(jQuery);

File diff suppressed because it is too large
+ 1 - 1
dist/inputmask/inputmask.phone.extensions.min.js


+ 1 - 1
dist/inputmask/inputmask.regex.extensions.js

@@ -3,7 +3,7 @@
 * http://github.com/RobinHerbots/jquery.inputmask
 * Copyright (c) 2010 - 2015 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 3.1.64-154
+* Version: 3.1.64-155
 */
 !function(factory) {
     "function" == typeof define && define.amd ? define([ "jquery", "./inputmask" ], factory) : "object" == typeof exports ? module.exports = factory(require("jquery"), require("./inputmask")) : factory(jQuery);

File diff suppressed because it is too large
+ 1 - 1
dist/inputmask/inputmask.regex.extensions.min.js


+ 1 - 1
dist/inputmask/jquery.inputmask.js

@@ -3,7 +3,7 @@
 * http://github.com/RobinHerbots/jquery.inputmask
 * Copyright (c) 2010 - 2015 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 3.1.64-154
+* Version: 3.1.64-155
 */
 !function(factory) {
     "function" == typeof define && define.amd ? define([ "jquery", "./inputmask" ], factory) : "object" == typeof exports ? module.exports = factory(require("jquery"), require("./inputmask")) : factory(jQuery);

File diff suppressed because it is too large
+ 1 - 1
dist/inputmask/jquery.inputmask.min.js


+ 26 - 16
dist/jquery.inputmask.bundle.js

@@ -3,7 +3,7 @@
 * http://github.com/RobinHerbots/jquery.inputmask
 * Copyright (c) 2010 - 2015 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 3.1.64-154
+* Version: 3.1.64-155
 */
 !function($) {
     function Inputmask(options) {
@@ -774,7 +774,7 @@
                     if ("inputmask" === eventHandler.namespace) {
                         var handler = eventHandler.handler;
                         eventHandler.handler = function(e) {
-                            if (console.log("triggered " + e.type), void 0 === this.inputmask) {
+                            if (void 0 === this.inputmask) {
                                 var imOpts = $(this).data("_inputmask_opts");
                                 imOpts ? new Inputmask(imOpts).mask(this) : $(this).unbind(".inputmask");
                             } else {
@@ -1041,7 +1041,7 @@
                 var $input = $(this), input = this;
                 if (input.inputmask) {
                     var nptValue = input.inputmask._valueGet(), buffer = getBuffer().slice();
-                    firstClick = !0, undoValue !== buffer.join("") && setTimeout(function() {
+                    undoValue !== buffer.join("") && setTimeout(function() {
                         $input.change(), undoValue = buffer.join("");
                     }, 0), "" !== nptValue && (opts.clearMaskOnLostFocus && (-1 === getLastValidPosition() && nptValue === getBufferTemplate().join("") ? buffer = [] : clearOptionalTail(buffer)), 
                     isComplete(buffer) === !1 && (setTimeout(function() {
@@ -1050,7 +1050,7 @@
                     writeBuffer(input, buffer, void 0, e));
                 }
             }).bind("focus.inputmask", function(e) {
-                var input = ($(this), this), nptValue = input.inputmask._valueGet();
+                var input = this, nptValue = input.inputmask._valueGet();
                 opts.showMaskOnFocus && (!opts.showMaskOnHover || opts.showMaskOnHover && "" === nptValue) ? input.inputmask._valueGet() !== getBuffer().join("") && writeBuffer(input, getBuffer(), seekNext(getLastValidPosition())) : mouseEnter === !1 && caret(input, seekNext(getLastValidPosition())), 
                 opts.positionCaretOnTab === !0 && setTimeout(function() {
                     caret(input, seekNext(getLastValidPosition()));
@@ -1063,13 +1063,26 @@
                     writeBuffer(input, buffer));
                 }
             }).bind("click.inputmask", function() {
-                var $input = $(this), input = this;
-                if ($input.is(":focus")) {
+                function doRadixFocus(clickPos) {
+                    if (opts.radixFocus && "" !== opts.radixPoint) {
+                        var vps = getMaskSet().validPositions;
+                        if (void 0 === vps[clickPos] || vps[clickPos].input === getPlaceholder(clickPos)) {
+                            if (clickPos < seekNext(-1)) return !0;
+                            var radixPos = $.inArray(opts.radixPoint, getBuffer());
+                            if (-1 !== radixPos) {
+                                for (var vp in vps) if (vp > radixPos && vps[vp].input !== getPlaceholder(vp)) return !1;
+                                return !0;
+                            }
+                        }
+                    }
+                    return !1;
+                }
+                var input = this;
+                if ($(input).is(":focus")) {
                     var selectedCaret = caret(input);
-                    if (selectedCaret.begin === selectedCaret.end) if (opts.radixFocus && "" !== opts.radixPoint && -1 !== $.inArray(opts.radixPoint, getBuffer()) && (firstClick || getBuffer().join("") === getBufferTemplate().join(""))) caret(input, $.inArray(opts.radixPoint, getBuffer())), 
-                    firstClick = !1; else {
+                    if (selectedCaret.begin === selectedCaret.end) if (doRadixFocus(selectedCaret.begin)) caret(input, $.inArray(opts.radixPoint, getBuffer())); else {
                         var clickPosition = selectedCaret.begin, lastPosition = seekNext(getLastValidPosition(clickPosition));
-                        lastPosition > clickPosition ? caret(input, isMask(clickPosition) ? clickPosition : seekNext(clickPosition)) : caret(input, opts.numericInput ? 0 : lastPosition);
+                        lastPosition > clickPosition ? caret(input, isMask(clickPosition) || isMask(clickPosition - 1) ? clickPosition : seekNext(clickPosition)) : caret(input, opts.numericInput ? 0 : lastPosition);
                     }
                 }
             }).bind("dblclick.inputmask", function() {
@@ -1108,7 +1121,7 @@
             writeBuffer(el, buffer), activeElement === el && caret(el, seekNext(getLastValidPosition())), 
             installEventRuler(el);
         }
-        var undoValue, compositionCaretPos, compositionData, el, $el, maxLength, valueBuffer, isRTL = !1, skipKeyPressEvent = !1, skipInputEvent = !1, ignorable = !1, firstClick = !0, mouseEnter = !0;
+        var undoValue, compositionCaretPos, compositionData, el, $el, maxLength, valueBuffer, isRTL = !1, skipKeyPressEvent = !1, skipInputEvent = !1, ignorable = !1, mouseEnter = !0;
         if (void 0 !== actionObj) switch (actionObj.action) {
           case "isComplete":
             return el = actionObj.el, $el = $(el), maskset = el.inputmask.maskset, opts = el.inputmask.opts, 
@@ -1998,9 +2011,9 @@
                     opts.integerDigits < 1 && (opts.integerDigits = "*");
                 }
                 opts.placeholder.length > 1 && (opts.placeholder = opts.placeholder.charAt(0)), 
-                opts.definitions[";"] = opts.definitions["~"], opts.definitions[";"].definitionSymbol = "~", 
-                opts.numericInput === !0 && (opts.radixFocus = !1, opts.digitsOptional = !1, isNaN(opts.digits) && (opts.digits = 2), 
-                opts.decimalProtect = !1);
+                opts.radixFocus = opts.radixFocus && "" !== opts.placeholder, opts.definitions[";"] = opts.definitions["~"], 
+                opts.definitions[";"].definitionSymbol = "~", opts.numericInput === !0 && (opts.radixFocus = !1, 
+                opts.digitsOptional = !1, isNaN(opts.digits) && (opts.digits = 2), opts.decimalProtect = !1);
                 var mask = autoEscape(opts.prefix);
                 return mask += "[+]", mask += "~{1," + opts.integerDigits + "}", void 0 !== opts.digits && (isNaN(opts.digits) || parseInt(opts.digits) > 0) && (mask += opts.digitsOptional ? "[" + (opts.decimalProtect ? ":" : opts.radixPoint) + ";{" + opts.digits + "}]" : (opts.decimalProtect ? ":" : opts.radixPoint) + ";{" + opts.digits + "}"), 
                 "" !== opts.negationSymbol.back && (mask += "[-]"), mask += autoEscape(opts.suffix), 
@@ -2390,9 +2403,6 @@
             suffix: " %",
             allowPlus: !1,
             allowMinus: !1
-        },
-        numeric2: {
-            alias: "numeric"
         }
     }), Inputmask;
 }(jQuery), function($) {

File diff suppressed because it is too large
+ 4 - 4
dist/jquery.inputmask.bundle.min.js


+ 53 - 40
js/inputmask.js

@@ -403,8 +403,9 @@
 				if (lastMatch.isGroup) { //this is not a group but a normal mask => convert
 					lastMatch.isGroup = false;
 					insertTestDefinition(lastMatch, opts.groupmarker.start, 0);
-					if (isOpenGroup !== true)
+					if (isOpenGroup !== true) {
 						insertTestDefinition(lastMatch, opts.groupmarker.end);
+					}
 				}
 			}
 
@@ -439,14 +440,10 @@
 
 			function reverseTokens(maskToken) {
 				function reverseStatic(st) {
-					if (st === opts.optionalmarker.start)
-						st = opts.optionalmarker.end;
-					else if (st === opts.optionalmarker.end)
-						st = opts.optionalmarker.start;
-					else if (st === opts.groupmarker.start)
-						st = opts.groupmarker.end;
-					else if (st === opts.groupmarker.end)
-						st = opts.groupmarker.start;
+					if (st === opts.optionalmarker.start) st = opts.optionalmarker.end;
+					else if (st === opts.optionalmarker.end) st = opts.optionalmarker.start;
+					else if (st === opts.groupmarker.start) st = opts.groupmarker.end;
+					else if (st === opts.groupmarker.end) st = opts.groupmarker.start;
 
 					return st;
 				}
@@ -459,10 +456,11 @@
 						maskToken.matches.splice(match, 1);
 						maskToken.matches.splice(intMatch + 1, 0, qt);
 					}
-					if (maskToken.matches[match].matches !== undefined)
+					if (maskToken.matches[match].matches !== undefined) {
 						maskToken.matches[match] = reverseTokens(maskToken.matches[match]);
-					else
+					} else {
 						maskToken.matches[match] = reverseStatic(maskToken.matches[match]);
+					}
 				}
 
 				return maskToken;
@@ -687,7 +685,6 @@
 			skipInputEvent = false, //skip when triggered from within inputmask
 			ignorable = false,
 			maxLength,
-			firstClick = true,
 			mouseEnter = true;
 
 		//maskset helperfunctions
@@ -1762,15 +1759,14 @@
 					if (eventHandler.namespace === "inputmask") {
 						var handler = eventHandler.handler;
 						eventHandler.handler = function(e) {
-							console.log("triggered " + e.type);
+							// console.log("triggered " + e.type);
 							if (this.inputmask === undefined) { //happens when cloning an object with jquery.clone
 								var imOpts = $(this).data("_inputmask_opts");
-								if (imOpts)
-									(new Inputmask(imOpts)).mask(this);
+								if (imOpts)(new Inputmask(imOpts)).mask(this);
 								else $(this).unbind(".inputmask");
-							} else if (e.type !== "setvalue" && (this.disabled || (this.readOnly && !(e.type === "keydown" && (e.ctrlKey && e.keyCode === 67) || (opts.tabThrough === false && e.keyCode === Inputmask.keyCode.TAB)))))
+							} else if (e.type !== "setvalue" && (this.disabled || (this.readOnly && !(e.type === "keydown" && (e.ctrlKey && e.keyCode === 67) || (opts.tabThrough === false && e.keyCode === Inputmask.keyCode.TAB))))) {
 								e.preventDefault();
-							else {
+							} else {
 								switch (e.type) {
 									case "input":
 										if (skipInputEvent === true || inComposition === true) {
@@ -2285,13 +2281,15 @@
 			if (($el.is(":input") && isInputTypeSupported($el.attr("type"))) || el.isContentEditable) {
 				//bind events
 				$el.closest("form").bind("submit", function() { //trigger change on submit if any
-					if (undoValue !== getBuffer().join(""))
+					if (undoValue !== getBuffer().join("")) {
 						$el.change();
-					if (opts.clearMaskOnLostFocus && getLastValidPosition() === -1 && $el[0].inputmask._valueGet && $el[0].inputmask._valueGet() === getBufferTemplate().join(""))
+					}
+					if (opts.clearMaskOnLostFocus && getLastValidPosition() === -1 && $el[0].inputmask._valueGet && $el[0].inputmask._valueGet() === getBufferTemplate().join("")) {
 						$el[0].inputmask._valueSet(""); //clear masktemplete on submit and still has focus
-
-					if (opts.removeMaskOnSubmit)
+					}
+					if (opts.removeMaskOnSubmit) {
 						$el.inputmask("remove");
+					}
 				}).bind("reset", function() {
 					setTimeout(function() {
 						$el.triggerHandler("setvalue.inputmask");
@@ -2301,16 +2299,17 @@
 					var $input = $(this),
 						input = this;
 					mouseEnter = true;
-					if (!$input.is(":focus") && opts.showMaskOnHover)
-						if (input.inputmask._valueGet() !== getBuffer().join(""))
+					if (!$input.is(":focus") && opts.showMaskOnHover) {
+						if (input.inputmask._valueGet() !== getBuffer().join("")) {
 							writeBuffer(input, getBuffer());
+						}
+					}
 				}).bind("blur.inputmask", function(e) {
 					var $input = $(this),
 						input = this;
 					if (input.inputmask) {
 						var nptValue = input.inputmask._valueGet(),
 							buffer = getBuffer().slice();
-						firstClick = true;
 						if (undoValue !== buffer.join("")) {
 							setTimeout(function() { //change event should be triggered after the other buffer manipulations on blur
 								$input.change();
@@ -2319,9 +2318,9 @@
 						}
 						if (nptValue !== "") {
 							if (opts.clearMaskOnLostFocus) {
-								if (getLastValidPosition() === -1 && nptValue === getBufferTemplate().join(""))
+								if (getLastValidPosition() === -1 && nptValue === getBufferTemplate().join("")) {
 									buffer = [];
-								else { //clearout optional tail of the mask
+								} else { //clearout optional tail of the mask
 									clearOptionalTail(buffer);
 								}
 							}
@@ -2331,11 +2330,10 @@
 								}, 0);
 								if (opts.clearIncomplete) {
 									resetMaskSet();
-									if (opts.clearMaskOnLostFocus)
+									if (opts.clearMaskOnLostFocus) {
 										buffer = [];
-									else {
+									} else {
 										buffer = getBufferTemplate().slice();
-
 									}
 								}
 							}
@@ -2344,8 +2342,7 @@
 						}
 					}
 				}).bind("focus.inputmask", function(e) {
-					var $input = $(this),
-						input = this,
+					var input = this,
 						nptValue = input.inputmask._valueGet();
 					if (opts.showMaskOnFocus && (!opts.showMaskOnHover || (opts.showMaskOnHover && nptValue === ""))) {
 						if (input.inputmask._valueGet() !== getBuffer().join("")) {
@@ -2359,7 +2356,7 @@
 							caret(input, seekNext(getLastValidPosition()));
 						}, 0);
 					}
-					undoValue = getBuffer().join('');
+					undoValue = getBuffer().join("");
 				}).bind("mouseleave.inputmask", function() {
 					var $input = $(this),
 						input = this;
@@ -2368,29 +2365,45 @@
 						var buffer = getBuffer().slice(),
 							nptValue = input.inputmask._valueGet();
 						if (!$input.is(":focus") && nptValue !== $input.attr("placeholder") && nptValue !== "") {
-							if (getLastValidPosition() === -1 && nptValue === getBufferTemplate().join(""))
+							if (getLastValidPosition() === -1 && nptValue === getBufferTemplate().join("")) {
 								buffer = [];
-							else { //clearout optional tail of the mask
+							} else { //clearout optional tail of the mask
 								clearOptionalTail(buffer);
 							}
 							writeBuffer(input, buffer);
 						}
 					}
 				}).bind("click.inputmask", function() {
-					var $input = $(this),
-						input = this;
-					if ($input.is(":focus")) {
+					function doRadixFocus(clickPos) {
+						if (opts.radixFocus && opts.radixPoint !== "") {
+							var vps = getMaskSet().validPositions;
+							if (vps[clickPos] === undefined || (vps[clickPos].input === getPlaceholder(clickPos))) {
+								if (clickPos < seekNext(-1)) return true;
+								var radixPos = $.inArray(opts.radixPoint, getBuffer());
+								if (radixPos !== -1) {
+									for (var vp in vps) {
+										if (radixPos < vp && vps[vp].input !== getPlaceholder(vp)) {
+											return false;
+										}
+									}
+									return true;
+								}
+							}
+						}
+						return false;
+					}
+					var input = this;
+					if ($(input).is(":focus")) {
 						var selectedCaret = caret(input);
 						if (selectedCaret.begin === selectedCaret.end) {
-							if (opts.radixFocus && opts.radixPoint !== "" && $.inArray(opts.radixPoint, getBuffer()) !== -1 && (firstClick || getBuffer().join("") === getBufferTemplate().join(""))) {
+							if (doRadixFocus(selectedCaret.begin)) {
 								caret(input, $.inArray(opts.radixPoint, getBuffer()));
-								firstClick = false;
 							} else {
 								var clickPosition = selectedCaret.begin,
 									lastPosition = seekNext(getLastValidPosition(clickPosition));
 
 								if (clickPosition < lastPosition) {
-									caret(input, isMask(clickPosition) ? clickPosition : seekNext(clickPosition));
+									caret(input, !isMask(clickPosition) && !isMask(clickPosition - 1) ? seekNext(clickPosition) : clickPosition);
 								} else {
 									caret(input, opts.numericInput ? 0 : lastPosition);
 								}

+ 7 - 9
js/inputmask.numeric.extensions.js

@@ -50,8 +50,8 @@ Optional extensions on the jquery.inputmask base
 				if (opts.placeholder.length > 1) {
 					opts.placeholder = opts.placeholder.charAt(0);
 				}
-				//only allow radixfocus when placeholder = 0  ???? why was this needed????
-				// opts.radixFocus = opts.radixFocus && opts.placeholder == "0";
+				//only allow radixfocus when placeholder = 0
+				opts.radixFocus = opts.radixFocus && opts.placeholder !== "";
 
 				opts.definitions[";"] = opts.definitions["~"]; //clone integer def for decimals
 				opts.definitions[";"].definitionSymbol = "~";
@@ -67,12 +67,13 @@ Optional extensions on the jquery.inputmask base
 				mask += "[+]";
 				mask += "~{1," + opts.integerDigits + "}";
 				if (opts.digits !== undefined && (isNaN(opts.digits) || parseInt(opts.digits) > 0)) {
-					if (opts.digitsOptional)
+					if (opts.digitsOptional) {
 						mask += "[" + (opts.decimalProtect ? ":" : opts.radixPoint) + ";{" + opts.digits + "}]";
-					else mask += (opts.decimalProtect ? ":" : opts.radixPoint) + ";{" + opts.digits + "}";
+					} else mask += (opts.decimalProtect ? ":" : opts.radixPoint) + ";{" + opts.digits + "}";
 				}
-				if (opts.negationSymbol.back !== "")
+				if (opts.negationSymbol.back !== "") {
 					mask += "[-]";
+				}
 				mask += autoEscape(opts.suffix);
 
 				opts.greedy = false; //enforce greedy false
@@ -679,10 +680,7 @@ Optional extensions on the jquery.inputmask base
 			suffix: " %",
 			allowPlus: false,
 			allowMinus: false
-		},
-		'numeric2': {
-			alias: "numeric"
-		},
+		}
 	});
 	return Inputmask;
 })(jQuery);

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "jquery.inputmask",
-  "version": "3.1.64-154",
+  "version": "3.1.64-155",
   "description": "jquery.inputmask is a jquery plugin which create an input mask.",
   "main": "./dist/inputmask/jquery.inputmask.js",
   "files": [