[英]Input field caret position not getting set correctly
我在下面将这个指令用于<input type="text>
字段
myApp.directive('onlyDecimal', function ()
{
return {
require: '?ngModel',
link: function(scope, element, attrs, ngModelCtrl)
{
if(!ngModelCtrl)
{
return;
}
ngModelCtrl.$parsers.push(function(val)
{
if (angular.isUndefined(val))
{
var val = "";
}
var clean = "";
if(val !== null)
{
clean = val.replace(/[^0-9\.]/g, "");
}
var start = element[0].selectionStart;
var end = element[0].selectionEnd + clean.length - val.length;
var negativeCheck = clean.split("-");
var decimalCheck = clean.split(".");
if(!angular.isUndefined(negativeCheck[1]))
{
negativeCheck[1] = negativeCheck[1].slice(0, negativeCheck[1].length);
clean = negativeCheck[0] + '-' + negativeCheck[1];
if(negativeCheck[0].length > 0)
{
clean = negativeCheck[0];
}
}
if(!angular.isUndefined(decimalCheck[1]))
{
decimalCheck[1] = decimalCheck[1].slice(0,2);
clean = decimalCheck[0] + "." + decimalCheck[1];
}
if (val !== clean)
{
ngModelCtrl.$setViewValue(clean);
ngModelCtrl.$render();
}
element[0].setSelectionRange(start, end);
return clean;
});
element.bind("keypress", function(event)
{
if(event.keyCode === 32)
{
event.preventDefault();
}
});
var decimalCount = 2;
var decimalPoint = ".";
ngModelCtrl.$render = function()
{
if (ngModelCtrl.$modelValue != null && ngModelCtrl.$modelValue >= 0)
{
if (typeof decimalCount === "number")
{
element.val(ngModelCtrl.$modelValue.toFixed(decimalCount).toString().replace(".", ","));
}
else
{
element.val(ngModelCtrl.$modelValue.toString().replace(".", ","));
}
}
}
element.on("change", function(e)
{
var floatValue = parseFloat(element.val().replace(",", "."));
if (!isNaN(floatValue) && typeof decimalCount === "number")
{
if (decimalCount === 0)
{
element.val(parseInt(floatValue));
}
else
{
var strValue = floatValue.toFixed(decimalCount);
element.val(strValue.replace(".", decimalPoint));
}
}
});
}
};
});
该指令的目的是在字段中仅允许数字和1个小数。
假设我有一个50.00
的值,然后将插入号设置在位置0之前,然后输入密钥b
的无效值。 在设置选择范围之前,我先设置了console.log,然后得到了这些值:
START: 0 END: 1
START: 0 END: 0
它运行两次,似乎仍将插入号移动到下一个位置。
您的代码中至少有两个问题会导致出现问题的行为:
在ngModelCtrl.$render
,您正在检查decimalCount
的类型,以确定$modelValue
是数字还是字符串。 一旦开始键入, ngModelCtrl.$modelValue
就会变成一个字符串,但是您的逻辑仍然尝试在其上调用.toFixed()
,从而导致render引发异常,并阻止解析器调用setSelectionRange
。
格式化程序中未使用将逗号替换为小数的逻辑。 带有逗号的值将输入,而创建clean
的正则表达式将删除它,因为它期望使用小数。 解决此问题后,还必须最后修复val
和clean
之间的比较,以将小数交换回clean
逗号。
总体而言,我将提出以下建议:
if (typeof decimalCount === "number")
交换为if (typeof ngModelCtrl.$modelValue === "number")
clean
之前,用小数替换所有逗号 clean
比较回原来的前val
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.