我使用 accoungting.js
插件来格式化货币。唯一的问题是,它会在键入任何内容时将光标置于值的末尾,因为我为currency
保留了2个十进制值精度,它阻止我输入更多内容。我没有找到任何用于在您键入时立即编辑值的源。我怎样才能做到这一点?找到任何解决方法或黑客?
<input autocomplete="off" type="text" id="Price"/>
JS
var options = {
symbol : "£",
decimal : ".",
thousand: ",",
precision : 2,
format: "%s%v"
};
$("#Price")
.on("input",
function() {
var _this = $(this);
debugger;
var val = _this.val().startsWith("£") ? _this.val().split("£")[1] : _this.val();
var value=accounting.formatMoney(val,options);
_this.val(value);
});
Demo
答案 0 :(得分:1)
完全重新编辑
(为清楚起见)
我认为这是accounting.js
的一种错误修复
在输入字段中keyup
(或类似此处的input
事件)上使用时,问题与光标位置有关。
在此解决方案中,我切换回keyup
事件,因为 - 奇怪的是 - input
事件未提供keycode
号码。
这是最终解决方案
添加我的的小脚本(部分来自SO答案和一些工作,1年前左右......不记得来源)
// --------------------------------------------------------------------------- What is the browser ?
var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
// Opera 8.0+ (UA detection to detect Blink/v8-powered Opera)
var isFirefox = typeof InstallTrigger !== 'undefined'; // Firefox 1.0+
var isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0;
// At least Safari 3+: "[object HTMLElementConstructor]"
var isChrome = !!window.chrome && !isOpera; // Chrome 1+
var isIE = /*@cc_on!@*/false || !!document.documentMode; // At least IE6
function GetCursorPos (field) {
// Initialize
iCaretPos = 0;
if (isIE){ //(document.selection) {
// Set focus on the element
field.focus();
// To get cursor position, get empty selection range
oSel = field.createTextRange();
// Move selection start to 0 position
oSel.moveStart('character', -field.value.length);
// The caret position is selection length
iCaretPos = oSel.text.length;
}
if (isChrome||isSafari){ //(field.selectionStart || field.selectionStart == '0')
iCaretPos = field.selectionStart;
}
if (isFirefox){
iCaretPos = field.selectionStart;
}
return iCaretPos;
}
function SetCursorPos (field,Pos) {
// Set focus on the element
field.focus();
if (isIE){
field.selectionStart=Pos;
}
if (isChrome||isSafari){
field.setSelectionRange(Pos,Pos);
}
if (isFirefox){
field.selectionStart=Pos;
}
return;
}
然后,正是对于accounting.js
,管理onkeyup值更新的方法是:
$("#Price")
.on('keyup', function (event) {
var val = this.value;
var x = event.keyCode; // Get the keycode for backspace check
var offset=0; // Set the offset to zero by default.
if(((x>=96)&&(x<=105))||((x>=37)&&(x<=40))||(x==8)||(x==46)){ // Allow digits from 0 to 9 AND arrows AND backspace AND Delete
var dotPos = val.indexOf("."); // Check for dot position.
var offsetComa = val.length%4; // Variable used to check if a coma is to be added.
// Offset conditions
if(val.length==1){
offset=1; // When the first digit is entered in the field, it's time to offset by 1 for the "£" to be added.
}
if(val.length>1){
if(offsetComa==0){ // when there is no remainder of val.length/4, it's time to offset 1 for the coma to be added.
offset=1;
}
if((offsetComa==0)&&((x==46)||(x==8))){ // when there is no remainder of val.length/4, BUT WE REMOVED A CHARACTER. offset -1 for the coma to be added.
offset=-1;
}
if(dotPos==1){ // If dot is right after "£" => user has backspaced!
val=""; // Consider val as empty!
}
if(dotPos==-1){ // If no dot present reinsert it!
val = val.slice(0, cursorPos-1) + "." + val.slice(cursorPos);
}
if(cursorPos==val.length-2){ // If inputting the second decimal, remove the possible third to avoid rounding.
val = val.slice(0, cursorPos+1);
}
if(cursorPos==val.length-3){ // If inputting decimals, clear offset.
offset=0;
val = val.slice(0, val.length-1)
}
}
}else{ // Removes any non-digit character
if(x!=8){
cursorPos = GetCursorPos(this);
val = val.slice(0, cursorPos-1) + val.slice(cursorPos);
if(val.charAt(cursorPos-1)=="."){ // decimal point
cursorPos+=1;
}
this.value = val;
SetCursorPos(this,cursorPos-1);
}
}
var hasCurrencySymbol = val.startsWith('£');
var formatted = accounting.formatMoney(val.substr(hasCurrencySymbol ? 1 : 0), options);
if(formatted=="£0.00"){
formatted="" // Empty the field instead of showing the problematic "£0.00"
}
cursorPos = GetCursorPos(this); // Get previous cursor position
this.value = formatted; // Return the value to field
SetCursorPos(this,cursorPos+offset); // Correct cursor position
});
它管理计算的游标偏移量onkeyup
它还管理退格/删除«反向偏移»
可以输入小数
奖金,它会立即删除所有非数字字符
:d
答案 1 :(得分:1)
当您以编程方式更改输入值时,您还需要恢复光标位置,因为浏览器会丢失该信息。
最简单的方法是恢复更改前使用的位置。
// pseudocode
.on('input', function () {
var cursorPosition = this.selectionEnd;
var val = this.value;
var hasCurrencySymbol = val.startsWith('£');
var formatted = accounting.formatMoney(val.substr(hasCurrencySymbol ? 1 : 0), options);
this.value = formatted;
this.setSelectionRange(cursorPosition, cursorPosition);
});
但可能更希望将光标放在刚刚插入的数字之后。下面的代码将最后记住的光标位置移动新旧输入文本之间的长度差异,这不是理想的解决方案(特别是对于第一个插入的数字),但是是进一步改进的良好起点。
.on('input', function () {
var cursorPosition = this.selectionEnd;
var val = this.value;
var hasCurrencySymbol = val.startsWith('£');
var formatted = accounting.formatMoney(val.substr(hasCurrencySymbol ? 1 : 0), options);
var lengthDiff = formatted.length - val.length;
this.value = formatted;
this.setSelectionRange(cursorPosition + diff, cursorPosition + diff);
});
代码使用所有流行浏览器(包括IE9 +)支持的setSelectionRange
。