【问题标题】:how to format input box text as I am typing it如何在我输入时格式化输入框文本
【发布时间】:2023-03-17 22:13:01
【问题描述】:

在 html 输入框中输入数字时如何格式化?

例如,我想输入数字 2000,当我输入第 4 个数字时,文本(当前显示在文本框中)将自动格式化为 2,000(带逗号)。

//my modified code based on Moob answer below

<input type="text" class="formattedNumberField" onkeyup="myFunc()">

//jQuery
$(".formattedNumberField").on('keyup', function(){
    var n = parseInt($(this).val().replace(/\D/g,''),10);
    $(this).val(n.toLocaleString());
});

function myFunc(){
// doing something else
}

虽然此代码如 Moob Fiddle 所示完美运行,但它在我的最终无法运行可能是因为我在输入框中还有另一个 onkeyup 事件???

【问题讨论】:

  • onkeyup 测试字段值是否为数字,然后进行相应的格式化
  • @Moob 你能给我举个例子吗?谢谢
  • 当然。请看下面我的回答。 :)

标签: javascript jquery


【解决方案1】:

纯 JS(无 jQuery):

var fnf = document.getElementById("formattedNumberField");
fnf.addEventListener('keyup', function(evt){
    var n = parseInt(this.value.replace(/\D/g,''),10);
    fnf.value = n.toLocaleString();
}, false);

Native JS Example Fiddle

使用 jQuery:

$("#formattedNumberField").on('keyup', function(){
    var n = parseInt($(this).val().replace(/\D/g,''),10);
    $(this).val(n.toLocaleString());
    //do something else as per updated question
    myFunc(); //call another function too
});

With jQuery Example Fiddle

允许小数:

$("#formattedNumberField").on('keyup', function(evt){
    if (evt.which != 110 ){//not a fullstop
        var n = parseFloat($(this).val().replace(/\,/g,''),10);
        $(this).val(n.toLocaleString());
    }
});

Obligatory Example

【讨论】:

  • 虽然 Fiddle 可以完美运行,但它对我来说不起作用,因为我已经有一个 onkeyup 可以在输入框中触发一个函数。我该如何规避这个?任何想法?谢谢
  • 你用的是jQuery还是原生JS?最可能的解决方案是将这两个功能合二为一。更新您的问题以包含您的 keyup 功能(或发布小提琴)
  • 我已经更新了我上面的问题,以反映根据您的代码所做的更改。谢谢
  • 从您的输入框中删除onkeyup="myFunc()",并从我们创建的.on('keyup' 函数中调用myFunc()。喜欢this
  • 酷,我认为input 事件可以表现得更好
【解决方案2】:

使用其他答案的一些代码位,我创建了以下工作示例。代码没有 jquery,但比其他一些示例要长一点。但它解决了很多其他人的问题。

http://jsfiddle.net/kcz4a2ca/10/

代码:

var input = document.getElementById('my_textbox');
var currentValue;

input.addEventListener('input', function(event) {
  var cursorPosition = getCaretPosition(input);
  var valueBefore = input.value;
    var lengthBefore = input.value.length;
  var specialCharsBefore = getSpecialCharsOnSides(input.value);
  var number = removeThousandSeparators(input.value);

  if (input.value == '') {
    return;
  }

  input.value = formatNumber(number.replace(getCommaSeparator(), '.'));

    // if deleting the comma, delete it correctly
  if (currentValue == input.value && currentValue == valueBefore.substr(0, cursorPosition) + getThousandSeparator() + valueBefore.substr(cursorPosition)) {
    input.value = formatNumber(removeThousandSeparators(valueBefore.substr(0, cursorPosition-1) + valueBefore.substr(cursorPosition)));
    cursorPosition--;
  }

  // if entering comma for separation, leave it in there (as well support .000)
  var commaSeparator = getCommaSeparator();
    if (valueBefore.endsWith(commaSeparator) || valueBefore.endsWith(commaSeparator+'0') || valueBefore.endsWith(commaSeparator+'00') || valueBefore.endsWith(commaSeparator+'000')) {
    input.value = input.value + valueBefore.substring(valueBefore.indexOf(commaSeparator));
  }

  // move cursor correctly if thousand separator got added or removed
  var specialCharsAfter = getSpecialCharsOnSides(input.value);
  if (specialCharsBefore[0] < specialCharsAfter[0]) {
        cursorPosition += specialCharsAfter[0] - specialCharsBefore[0];
  } else if (specialCharsBefore[0] > specialCharsAfter[0]) {
        cursorPosition -= specialCharsBefore[0] - specialCharsAfter[0];
  }
  setCaretPosition(input, cursorPosition);

  currentValue = input.value;
});

function getSpecialCharsOnSides(x, cursorPosition) {
    var specialCharsLeft = x.substring(0, cursorPosition).replace(/[0-9]/g, '').length;
  var specialCharsRight = x.substring(cursorPosition).replace(/[0-9]/g, '').length;
  return [specialCharsLeft, specialCharsRight]
}

function formatNumber(x) {
   return getNumberFormat().format(x);
}

function removeThousandSeparators(x) {
  return x.toString().replace(new RegExp(escapeRegExp(getThousandSeparator()), 'g'), "");
}

function getThousandSeparator() {
  return getNumberFormat().format('1000').replace(/[0-9]/g, '')[0];
}

function getCommaSeparator() {
  return getNumberFormat().format('0.01').replace(/[0-9]/g, '')[0];
}

function getNumberFormat() {
    return new Intl.NumberFormat();
}

/* From: http://stackoverflow.com/a/6969486/496992 */
function escapeRegExp(str) {
  return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}

/*
** Returns the caret (cursor) position of the specified text field.
** Return value range is 0-oField.value.length.
** From: http://stackoverflow.com/a/2897229/496992
*/
function getCaretPosition (oField) {
  // Initialize
  var iCaretPos = 0;

  // IE Support
  if (document.selection) {

    // Set focus on the element
    oField.focus();

    // To get cursor position, get empty selection range
    var oSel = document.selection.createRange();

    // Move selection start to 0 position
    oSel.moveStart('character', -oField.value.length);

    // The caret position is selection length
    iCaretPos = oSel.text.length;
  }

  // Firefox support
  else if (oField.selectionStart || oField.selectionStart == '0')
    iCaretPos = oField.selectionStart;

  // Return results
  return iCaretPos;
}

/* From: http://stackoverflow.com/a/512542/496992 */
function setCaretPosition(elem, caretPos) {
    if(elem != null) {
        if(elem.createTextRange) {
            var range = elem.createTextRange();
            range.move('character', caretPos);
            range.select();
        }
        else {
            if(elem.selectionStart) {
                elem.focus();
                elem.setSelectionRange(caretPos, caretPos);
            }
            else
                elem.focus();
        }
    }
}

【讨论】:

  • 这是最好的答案,不会出现空字段问题,并且可以在不丢失光标位置的情况下编辑中间的数字。但是确实会遇到不是有效数字的字符导致错误而不是被忽略。
  • 我该怎么做,只用逗号而不是点作为分隔符?
  • 我明白了 - 它需要 'en' 参数。 Intl.NumberFormat('en'); 另外,这显然是最好的答案——它解决了光标位置问题!
  • 我花了很多时间寻找一个可接受的解决方案,这是迄今为止最完整的解决方案。
  • 如何在此解决方案中添加小数点?我试过这个:Intl.NumberFormat('en', { maximumFractionDigits: 2 }, { minimumFractionDigits: 2 }); 但不工作
【解决方案3】:

试试这个插件,效果不错http://robinherbots.github.io/jquery.inputmask/

【讨论】:

  • 这非常接近我想要的。会试一试,如果它对我有用。我会告诉你的。谢谢
  • 虽然这看起来很有希望.. 我尽量减少插件的使用,@Moob 展示了一个完美的例子。无论如何谢谢:)
【解决方案4】:

您可以使用 ngx-format-field。这是一个用于格式化将出现在视图中的输入值的指令。它不会操纵将保存在后端的输入值。见链接here

例子:

component.html:

<input type="text" formControlName="currency" [appFormatFields]="CURRENCY"
(change)="onChangeCurrency()">

component.ts

onChangeCurrency() {
this.currency.patchValue(this.currency.value);
}

观看演示:here!

【讨论】:

    【解决方案5】:

    根据您给出的示例,您可以使用以下内容:

    $("#my_textbox").keyup(function(){
        if($("#my_textbox").val().length == 4){
            var my_val = $("#my_textbox").val();
            $("#my_textbox").val(Number(my_val).toLocaleString('en'));
        }
    });
    

    我在上面使用了jQuery,但也可以用纯JS来完成。

    工作示例here

    【讨论】:

    • NaN 如果用户输入的不是数字!
    • @Moob 你必须添加更多的 JavaScript 来验证不同的场景
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-30
    相关资源
    最近更新 更多