【问题标题】:HTML "number" input not allowing JavaScript to display commasHTML“数字”输入不允许 JavaScript 显示逗号
【发布时间】:2018-04-05 21:26:59
【问题描述】:

注意:我知道这与其他问题相似,但出于语义和其他原因(例如 iOS 上的输入方便),我特别希望 HTML 输入为 type="number"。这就是问题所在......

我正在尝试设置一个 HTML 表单,以便数字字段显示数千个逗号——例如“10,000,000”而不是“10000000”。我想设置它,以便该字段显示逗号,但是当它获得实际编辑的焦点时,逗号消失了。

我可以手动将逗号添加到值中,没有任何问题(我主要在 Firefox ~59 中进行测试);但是每当我尝试让 JavaScript 添加逗号时,该字段就会被空白。有谁知道如何进行这项工作?

(注意,我在这里使用 Numerals.js 进行格式化...http://numeraljs.com/

这是我所拥有的:

$(document).ready(function(){
    var numberFields = $("input[type=number]");
    numberFields.each( function(){
        $(this).val( numeral( $(this).val() ).format('0') );
    });
    numberFields.focus( function(){
        $(this).val( numeral( $(this).val() ).format('0') );
    });
    numberFields.blur( function(){
        $(this).val( numeral( $(this).val() ).format('0,0') );
    });
});

HTML 输入示例:

<input name="myField" value="0" type="number">

(顺便说一句——而且很方便,我已经确认向 HTML 表单处理脚本提交带逗号的数字只会删除逗号并将未格式化的数字放入数据库中。太好了!)

【问题讨论】:

  • 如果您使用 HTML 类型的输入,您必须接受用于数字解析的 HTML 规则。这些不允许使用逗号。
  • 是的,我知道。我已经注意到,如果您将光标放在字段中并且只是普通类型的逗号,它就可以接受这些。希望 JS 可以通过某种方式完成我可以用键盘完成的工作......
  • 使用type="text" pattern="[0-9,]*" 将其限制为带逗号的数字。
  • 是的,您可以在字段中输入您想要的内容,但是当您的表单被发布或您从 JavaScript 访问 .value 时,您什么也得不到。我同意这是不令人满意的行为。
  • 你也可以使用Javascript表单验证。

标签: javascript jquery html formatting


【解决方案1】:

我不熟悉 numeric.js,但如果我这样做,我只会将数值保存为数据属性,然后使用 .toLocaleString 格式化,记住你有 switch textnumber 类型之间,以便您可以显示逗号

看到 iOS 的问题,我相信以下方法会起作用。您可以克隆元素,然后将原始元素设置为 text 输入。然后,获取原始元素的位置,并将新元素设置为绝对定位在原始元素之上。现在,将数字输入设置为opacity: 0,这样你就不会看到它,但是当他们点击时,它会点击你的克隆。单击克隆时,将其设置为opacity: 1,当它模糊时,将原始输入设置为克隆输入的值,但使用toLocaleString。我检查了它在 Firefox 中是否可以工作,理论上它应该也可以在 iOS 上工作。

$(document).ready(function(){
        var $clones = [];
        var numberFields = $("input[type='number']");
        numberFields.each(function(i){
            var $clone = $(this).clone();
            $(this).attr('type', 'text');
            var destination = $(this).offset();
            var width = $(this).width();
            $clones.push($clone.css({
                position: 'absolute',
                top: destination.top,
                left: destination.left,
                opacity: '0',
                width: width
            }));
            $(this).after($clone);
            var that = this;
            $clone.on('focus', function() {
                $(this).css('opacity', '1');
            });
            $clone.on('blur', function() {
                $(this).css('opacity', '0');
                $(that).val('' + $(this).val() ? parseInt($(this).val()).toLocaleString() : '');
            });
        });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="number" pattern="[0-9,]*" />

【讨论】:

  • Numeral.js 允许这样做:numeral( $(this).val() ).format('0,0')。我避免toLocaleString,因为没有fromLocaleString,但在你的例子中我不需要那个。好主意!
  • 奖励:我不熟悉“模式”属性。 :-)
  • Aaaa 而且它对 iOS 浏览器也没有帮助。显然,移动 Safari 浏览器会在应用焦点事件之前决定字段获得什么类型的键盘。从概念上讲,您的答案很好,但实际上它并不完全奏效。 :-(
  • 当我看到你的更新时,我真的笑了。太疯狂了,这应该如此复杂;但是您的代码看起来很可靠。我明天得考试。
  • 我想对于台式机来说,将原始(显示)字段上的选项卡索引设置为 -1 也很聪明,因此这些字段实际上无法通过键盘选择
【解决方案2】:

注意:我将留下这个原始答案,以防万一这里的东西在路上有用;但请参阅我的另一个答案,这是对原始问题的完整解决方案。

我找不到完全按照我的意愿行事的方法。在不同的浏览器中,输入“type”的futzing太不一致了;并且无论如何在iOS上都不起作用(这是90%)。但是,我确实“非常接近”地顺利完成了以下工作。 (注意这里使用了 numeric.js 库进行格式化):

JavaScript:

<script>
$(document).ready(function(){
    var intFields = $("input[data-format=integer]");
    intFields.each( function(){
        $(this).attr( "pattern", "[0-9,]*" );
        $(this).val( numeral( $(this).val() ).format('0,0') );
    });
    intFields.focus( function(){
        $(this).val( numeral( $(this).val() ).format('0') );
    });
    intFields.blur( function(){
        $(this).val( numeral( $(this).val() ).format('0,0') );
    });
    $("form#myForm").on( "submit", function(){
        intFields.each( function() {
            $(this).val( numeral( $(this).val() ).format('0') );
        } );
        return true;
    } );
});
</script>

HTML:

<input type="text" data-format="integer" name="some_number" value="12345678>">

总的来说,对于这样一个常见的用例来说,工作量太大了。我希望浏览器制造商尽快提出解决方案!需要有一种简单、标准的方式在字段中显示数字。

【讨论】:

    【解决方案3】:

    我的最终功能,基于戴夫的回答。 Dave 的功能并不完整(尽管是有效的概念证明)。这会处理 name 属性(这是表单提交所必需的),并将输入叠加层相对于原始输入定位,而不是页面(如果调整窗口大小,这会防止事情发生 catywampus)。

    重要提示:使用此功能时,您的数字字段必须使用&lt;label&gt;...&lt;/label&gt;&lt;input&gt;,而不是&lt;label&gt;...&lt;input&gt;&lt;/label&gt; 已修复!

    $(document).ready(function() {
          format_integers();
        });
    
        /**
         * Any form inputs with type=number and data-format=integer will display contents with commas when input not in focus.
         * @param container string to be used as jQuery search. Defaults to 'body'; but can be any specific element
         */
        function format_integers(container) {
          container = (typeof container !== 'undefined') ? container : 'body';
          var $wrapper = $('<span>').css({
            position: 'relative',
            display: 'inline-block',
            padding: 0
          });
          $(container + " input[type='number'][data-format=integer]").each(function() {
            var $clone = $(this).clone();
            var $parentLabel = $(this).parent('label');
            if( $parentLabel.length !== 0 ) {
                $parentLabel.css( 'display', 'inline-flex' );
                $clone.css( 'order', 1 );
                $(this).css( 'order', 2 );
            }
            $(this).wrapAll($wrapper).css({
                position: 'absolute',
                top: 0,
                left: 0,
                opacity: 0
              })
              .attr('pattern', '[0-9]*');
            $clone.removeAttr('name class id pattern')
              .attr('type', 'text')
              .attr('tabindex', -1)
              .css('width', $(this).width)
              .val($(this).val() ? parseInt($(this).val()).toLocaleString() : '');
            $(this).before($clone);
            $(this).on('focus', function() {
              $(this).css('opacity', '1');
            });
            $(this).on('blur', function() {
              $(this).css('opacity', '0');
              $clone.val($(this).val() ? parseInt($(this).val()).toLocaleString() : '');
            });
          });
        }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <form>
      <label>Integer Input:&nbsp; <input type="number" data-format="integer" name="test" id="num_input" value="123456789" /></label><br>
      <label for="num_input2">Integer Input: </label>
      <input type="number" data-format="integer" name="test2" id="num_input2" value="10000000" /><br>
      <label>Textarea <textarea>Something to focus other than the number fields</textarea></label>
    </form>

    【讨论】:

      猜你喜欢
      • 2023-03-18
      • 1970-01-01
      • 2015-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-09-22
      相关资源
      最近更新 更多