【问题标题】:HTML Input type number Thousand separatorHTML 输入类型数字千位分隔符
【发布时间】:2015-10-30 07:08:38
【问题描述】:

我想在我的输入字段中有千位分隔符(例如 1,000,000)。但是,它必须是 number 类型,因为我需要能够使用“step”来调整它的值。代码:

<input type="number" id='myNumber' value="40,000" step='100'>

我尝试使用 Javascript 来调整该值,但没有奏效。任何帮助,将不胜感激。谢谢!

【问题讨论】:

  • 您可以创建一组自定义控件来控制step
  • 你可以试试autoNumeric Plugin decorplanit.com/plugin
  • 在 type=number 中不能这样做
  • 我很确定如果 parseFloat() 无法解析该值,“数字”输入字段将不起作用。
  • @Sushil 不幸的是,autoNumeric 支持输入类型number,根据doc

标签: javascript html


【解决方案1】:

使用 autoNumeric 插件,您可以将字段设置为具有不同分隔符的数字输入。

包含插件:

<script src="~/Scripts/autoNumeric/autoNumeric.min.js" type="text/javascript"></script>

HTML:

 <input type="text" id="DEMO" data-a-sign="" data-a-dec="," data-a-sep="." class="form-control"> 

脚本:

<script>
 jQuery(function($) {
$('#DEMO').autoNumeric('init');   
 });
</script>

您只能输入数字,如果输入 100000,99,您将看到 100.000,99。

更多:https://github.com/autoNumeric/autoNumeric

【讨论】:

  • 我用过这个插件。这很棒,但也有问题。当您只想在输入元素中使用它时它工作得很好,但如果您想对输入做一些其他事情(使用 JavaScript),它会以一种特殊的方式工作!如果您想使用它,请记住这一点。
  • @Mahsa:是的,你是对的。但是对于其他想要解决方案的人,我们现在可以使用 watchExternalChanges:true(默认为 false)来使用 javascript 来管理您的输入(我设置了 value 和 readonly 属性)。像这样初始化: let optionsDefault = { ... watchExternalChanges: true, // 当我们需要通过 JS 更改值时为真。否则,在输入悬停时,值将重置为初始值。 unformatOnSubmit: true // 在表单提交时,rawValue 正在替换要发送到服务器的格式化值 }; new AutoNumeric.multiple('.auto-numeric', null, optionsDefault);
【解决方案2】:
  • 检查此 webdesign.tutsplus.com tutorial
  • 最终结果总结在这里(看direct Codepen playground

    $("#formInput".on("keyup", function(event ) {                   
        // When user select text in the document, also abort.
        var selection = window.getSelection().toString(); 
        if (selection !== '') {
            return; 
        }       
        // When the arrow keys are pressed, abort.
        if ($.inArray(event.keyCode, [38, 40, 37, 39]) !== -1) {
            return; 
        }       
        var $this = $(this);            
        // Get the value.
        var input = $this.val();            
        input = input.replace(/[\D\s\._\-]+/g, ""); 
        input = input?parseInt(input, 10):0; 
        $this.val(function () {
            return (input === 0)?"":input.toLocaleString("en-US"); 
        }); 
    }); 
    

注意事项:

  • toLocaleString() javascript 函数实际显示千位分隔符 (example and doc)
  • 在您的控制台中运行以下代码以获取想法

    (30000000).toLocaleString('en-US',{useGrouping:true})

【讨论】:

  • 这太好了,谢谢。我对其进行了一些修改,以在文本字段中保留美元符号,并允许向上/向下箭头将值递增和递减 1000。jsfiddle.net/e3czy926
【解决方案3】:

您可以通过使用伪元素来显示逗号版本来伪造此功能。

div[comma-value]{
  position:relative;
}
div[comma-value]:before{
  content: attr(comma-value);
  position:absolute;
  left:0;
}
div[comma-value] input{
  color:#fff;
}

需要一个包装 div,因为输入不能有伪元素。

<div>
  <input type="number" id='myNumber' value="40000" step='100'>
</div>

还有一点 JavaScript 可以每隔三个字符插入逗号

myNumber.value = commify(myNumber.value)
myNumber.addEventListener("change", function(){
  commify(event.target.value)
})

function commify(value){
  var chars = value.split("").reverse()
  var withCommas = []
  for(var i = 1; i <= chars.length; i++ ){
    withCommas.push(chars[i-1])
    if(i%3==0 && i != chars.length ){  
      withCommas.push(",")
    }
  }
  var val = withCommas.reverse().join("")
  myNumber.parentNode.setAttribute("comma-value",val)
}

查看fiddle

【讨论】:

  • 看不到输入的过程,可能需要稍微修改一下。
  • 这个问题是:用户可以输入一个值并且伪字段没有更新(你可以添加一个额外的更改监听器来解决这个问题),并且;您仍然可以突出显示数字字段的白色文本。总而言之,这不是用户或浏览器友好的解决方案
  • 我个人不喜欢这个。尝试突出显示输入的内容,您会自己看到。
  • 这在 Chrome 中有效,但在 FF 中无效。其他浏览器没试过。
  • 你不能编辑这个值,如果他们需要小数怎么办 - 这真的不适用于法国或印度数字
【解决方案4】:

试试

function addCommas(nStr)
{
    nStr += '';
    x = nStr.split('.');
    x1 = x[0];
    x2 = x.length > 1 ? ',' + x[1] : '';
    var rgx = /(\d+)(\d{3})/;
    while (rgx.test(x1)) {
        x1 = x1.replace(rgx, '$1' + ',' + '$2');
    }
    return x1 + x2;
}

【讨论】:

    【解决方案5】:

    csq 建议使用jQuery autoNumeric plugin。我发现它使用起来非常简单直观。

    我唯一的抱怨是它强制&lt;input type="text"&gt; 而不是&lt;input type="number"&gt;。这意味着您将失去 step 的功能,但您的网站用户可以在字段中使用逗号。

    我猜您可以将小于 1,000 的预期值用作 &lt;input type="number"&gt;,将大于 1,000 的值用作 &lt;input type="text"&gt;

    【讨论】:

    • 我还没有测试这是否适合移动设备。我怀疑不是
    • AutoNumeric 支持 Android Chrome,正如其网站上所说:autonumeric.github.io
    【解决方案6】:

    创建一个显示格式化数字的掩码输入。此解决方案避免更改输入的类型或值。

    $("input.mask").each((i,ele)=>{
                let clone=$(ele).clone(false)
                clone.attr("type","text")
                let ele1=$(ele)
                clone.val(Number(ele1.val()).toLocaleString("en"))
                $(ele).after(clone)
                $(ele).hide()
                clone.mouseenter(()=>{
    
                    ele1.show()
                    clone.hide()
                })
                setInterval(()=>{
                    let newv=Number(ele1.val()).toLocaleString("en")
                    if(clone.val()!=newv){
                        clone.val(newv)
                    }
                },10)
    
                $(ele).mouseleave(()=>{
                    $(clone).show()
                    $(ele1).hide()
                })
                
    
            })
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <input class="mask" type="number" value="12345.678"/>

    【讨论】:

      【解决方案7】:

      function addCommas(nStr) { ....

      除了 yovanny 的回答之外,我还创建了一个使用此功能的 Vue 组件。

          Vue.component("in-n", {
          template:
              `<input @keyup="keyup" @keypress="isNumber($event)" v-model="text" type="text" />`,
          props: ["value"],
          data() {
              return {
                  text: ""
              }
          },
          methods: {
              addCommas(nStr) {
                  nStr += '';
                  x = nStr.split('.');
                  x1 = x[0];
                  x2 = x.length > 1 ? ',' + x[1] : '';
                  var rgx = /(\d+)(\d{3})/;
                  while (rgx.test(x1)) {
                      x1 = x1.replace(rgx, '$1' + ',' + '$2');
                  }
                  return x1 + x2;
              },
              isNumber: function (evt) {
                  evt = (evt) ? evt : window.event;
                  var charCode = (evt.which) ? evt.which : evt.keyCode;
                  if ((charCode > 31 && (charCode < 48 || charCode > 57)) && charCode !== 46) {
                      evt.preventDefault();;
                  } else {
                      return true;
                  }
              },
              keyup() {
                  this.text = this.addCommas(this.text.replace(/,/g, ''));
                  this.$emit("input", parseInt(this.text.replace(/,/g, '')))
              }
          }
      })
      

      【讨论】:

        【解决方案8】:

        我找到了一个更简单的答案:

        • &lt;input type="text"&gt; 开头。您仍然可以添加 min、max 和 step 属性。
        • 将 onfocus 和 onblur 处理程序添加到 &lt;input&gt; 节点:
        node.addEventListener('onfocus', () => {
          const value = node.value;
          node.type = 'number';
          node.value = Number(value.replace(/,/g, '')); // or equivalent per locale
        });
        
        node.addEventListener('onblur', () => {
          const value = node.value;
          node.type = 'text';
          node.value = value.toLocaleString();  // or other formatting
        });
        

        当用户选择输入时,它将转换为删除了千位分隔符的常规数字输入,但带有一个普通的微调器。当用户模糊输入时,它会恢复为格式化文本。

        我添加了一个 onkeyup 处理程序,它会在按下“enter”键时模糊输入。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-06-16
          • 1970-01-01
          相关资源
          最近更新 更多