代码之家  ›  专栏  ›  技术社区  ›  Jeni

允许/替换逗号作为使用rails输入type=“number”的数字分隔符

  •  0
  • Jeni  · 技术社区  · 7 年前

    我正在使用rails,我有以下功能:

    <%= item.number_field :price, step: 0.01, class: "item_price" %>
    

    从而生成以下HTML:

    <input step="0.01" class="item_price" name="something" id="something" type="number">
    

    我的网站是针对保加利亚观众,那里的官方数字分隔符是逗号“,”

    例如,有人很可能会键入“5,90”,但这不是一个有效的数字,而且它不会通过rails/html内置的验证。

    我试图使用javascript将逗号替换为“.”,但对于数字输入字段,如果它不是一个有效的数字(5,90不是有效的数字),则根本无法获取该值,因此我陷入了困境。 我使用了以下代码:

    $(document).ready(function(){
      $("input").keyup(function (){
        alert(this)
        alert(this.value)
        var v = this.value.replace(/,/g,'.');
        if (v!=this.value)
        this.value = v;
        alert(this.value)
      });
    });
    

    当我在字段中键入1时,警报显示“1”,当我键入“1”时,警报为空。

    我能想到的唯一可能的解决方案是将字段更改为文本字段,但是这样我会丢失所有漂亮的rails附加功能,所以我想避免它。

    我想要的是“5,90”和“5.90”一样。任何用户输入都应该有效。

    欢迎使用任何javascript、jquery或rails解决方案。 好的

    更新:在chrome上,我甚至不允许在字段中键入“,”这不太好,因为我在键盘上按了逗号,结果什么也没发生,这不是很好的ux

    我最初的测试是在ff上,在这里我可以键入“comma”,但它是无效的

    在android上,内置浏览器:我在只有“.”的地方获得数字键盘,这没问题。

    4 回复  |  直到 7 年前
        1
  •  1
  •   Pierre Capo    7 年前

    我做了一些研究,这是一个非常有趣的话题。 奇怪的是,默认情况下会使用本地约定,但浏览器会将其转换为点十进制分隔符。例如,如果您来自保加利亚,如果您在输入中键入5,90:

    $(document).ready(function(){
      $("input").keyup(function (){
        console.log(this.value); // will still log 5.90 (dot separator)
      });
    });
    

    总之,在这两种情况下,如果英国人写5.90,或者保加利亚人写5.90,输入的javascript值将是5.90。

    不管出于什么原因,如果您想知道哪个十进制分隔符使用您的客户端,此函数将返回他的十进制分隔符:

    function whatDecimalSeparator() {
        var n = 1.1;
        n = n.toLocaleString().substring(1, 2);
        return n;
    }
    

    查看更多 here

        2
  •  0
  •   T.J. Crowder    7 年前

    在处理用户输入时 input 元素,使用 输入 事件,不是 keyup 是的。 输入 每当值更改时激发(通过击键、右键单击并粘贴、浏览器提供的递增/递减按钮等)。

    然后,在支持 type="number" ,使用 valueAsNumber 访问数值。你可以可靠地回到 value 访问字段中的文本,然后对其进行操作。

    所以:

    $(document).ready(function(){
      $("input").on("input", function (){                  // `input` event
        var value;
        if ("valueAsNumber" in this) {                     // Use `valueAsNumber` if provided
            value = this.valueAsNumber;
        } else {
            value = +this.value.trim().replace(/,/g, "."); // Use `value` if not, convert to num
        }
        console.log(value);
      });
    });
    

    (注意,有很多方法可以转换成数字;我使用了一元 + 上面。见 this answer 有关详细信息。)

        3
  •  0
  •   Maxence    7 年前

    您可以在ruby中的控制器操作中更改它:

    params[:myparam] = params[:myparam].gsub(',','.').to_f

    但您也可以在模型中添加 before_validation 钩子。

    用ruby做很方便,因为:

    • 它是后端。所以你根本不在乎前端改造是否成功。例如,当浏览器中禁用javascript时
    • 如果这是您所在国家/地区的官方分隔符,则允许在浏览器中保留逗号。
        4
  •  0
  •   Jeni    7 年前

    以下是我对这个问题的发现,尽管它没有完全解决,但它们都是纯html与rails无关的。 这是一篇很好的文章: https://www.w3.org/International/wiki/Locale-based_forms 是的。

    所以我找到的部分解决方案是添加“lang”=>“bg bg”(rails代码)/lang=“bg bg”(html):

    <%= item.number_field :price, step: 0.01, class: "item_price", "lang" => "bg-BG" %>
    

    它的作用: 在FF中:

    • 它同时接受“,”和“.”作为十进制分隔符,这太棒了!
    • 它显示的是已经保存的带有“,”的数字,例如“5,89”,我不太喜欢,但实际上是正确的

      在Gchrome和Android内置浏览器中:

    • 没有效果,至少我找不到

    下面是另一篇非常好的文章,以及一个表格,其中显示了哪个浏览器的操作系统支持什么: https://www.ctrl.blog/entry/html5-input-number-localizatione

    结论:由于浏览器支持不好,而且绝对不一致,因为FF的使用率目前很低,但是Gchrome的行为(当你键入时,无声地省略逗号)非常糟糕,我将不得不切换到文本字段并为验证/解析等做一些自定义魔术,或者只保留默认行为,让用户恨我。