【问题标题】:Auto-format credit card number input as user types自动格式化信用卡号输入作为用户类型
【发布时间】:2017-07-25 19:40:09
【问题描述】:

我想使用 JavaScript 创建一个输入,自动将其格式化为正确的信用卡格式。

我想要什么?

  1. 输入应以 4 组为一组进行格式化输入。例如如果我输入1234567890123456,它应该格式化为1234 5678 9012 3456
  2. 最大长度应为 16 位。所以如果我输入1234567890123456789,它应该格式化为“1234 5678 9012 3456”
  3. 应在您键入时进行格式化。所以如果我输入“123456”,它应该格式化为“1234 56”
  4. 应忽略无效字符。所以如果我输入564adsd299 474,它应该格式化为“5642 9947 4”

输入也应该尊重文本框的传统行为。 (这里的| 类似于光标,例如

如果我在输入时输入了 8:

  1. 1234 5|67 它应该转向 1234 58|67
  2. 1234|,应该转到1234 8
  3. 1234| 567 它应该转向 1234 8567
  4. 1234| 5679 它应该转向 1234 8567 9

如果我在输入时删除前一个字符:

  1. 1234 5|67 它应该转向1234 |67
  2. 1234 |567 它应该转向 1234| 567
  3. 1234| 567 它应该转向 123|5 67

接下来可能会有更多测试用例。

示例

基本上,它的行为应该与 Google Play 商店中使用的“输入卡详细信息”完全相同。要查找此页面:在 Android 设备上打开 Play 商店 > 单击帐户 > 付款方式 > 添加信用卡或借记卡。这个屏幕也可以在这里找到:https://play.google.com/store/account

到目前为止我有什么?

这是我目前所拥有的:

var txtCardNumber = document.querySelector("#txtCardNumber");
txtCardNumber.addEventListener("input", onChangeTxtCardNumber);

function onChangeTxtCardNumber(e) {		
    var cardNumber = txtCardNumber.value;
 
	  // Do not allow users to write invalid characters
    var formattedCardNumber = cardNumber.replace(/[^\d]/g, "");
    formattedCardNumber = formattedCardNumber.substring(0, 16);
  
    // Split the card number is groups of 4
    var cardNumberSections = formattedCardNumber.match(/\d{1,4}/g);
    if (cardNumberSections !== null) {
        formattedCardNumber = cardNumberSections.join(' ');	
    }
	
    console.log("'"+ cardNumber + "' to '" + formattedCardNumber + "'");
  
    // If the formmattedCardNumber is different to what is shown, change the value
    if (cardNumber !== formattedCardNumber) {
        txtCardNumber.value = formattedCardNumber;
    }
}
<input id="txtCardNumber"/>

上面完美地格式化了信用编号,但是当我想编辑时问题就开始了。

但是,以上不满足测试用例 5 以后,因为光标只是跳到末尾。

我怎样才能实现这种行为。我知道这是可能的,因为 Google 已经做到了。

(请不要使用 PayPal 答案)

编辑:请注意,我正在寻找原生 JavaScript 解决方案,但请随意建议插件作为 cmets。例外是几乎没有依赖关系的库,因此可以只复制源代码。

我还删除了上述代码中的 jQuery 以鼓励原生 JS 解决方案。

【问题讨论】:

    标签: javascript html


    【解决方案1】:

    我看到您正在使用 jQuery,而不是尝试自己解决这个逻辑,您可以考虑使用屏蔽输入插件。我选择this one 只是因为它在搜索中首先出现。有自定义选项,它似乎可以满足您的所有要求。

    $('#txtCardNumber').mask("9999 9999 9999 9999");
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.maskedinput/1.4.1/jquery.maskedinput.js"></script>
    <input id="txtCardNumber"/>

    【讨论】:

    • 我认为这不值得投反对票,但我正在寻找原生 JavaScript 解决方案。我将编辑我的问题,以便更清楚。
    • 感谢您的建议
    • @YahyaUddin 但您问题中的代码显然使用了 jQuery!
    • 这个插件很好,但没有产生预期的行为。
    • 实际上,我正在查看他们的主要网站。看看你的例子,它看起来不错。我会把{placeholder:" "} 去掉那些相当难看的下划线。
    【解决方案2】:

    这应该可行:

    var format = [9, 2, 3,5,5,5,5,5,5,5,4, 5, 5, 5, 54, 4, 4, 4, 4, 4, 4, 4, 
      4, 4].map((data, index) => {
    
      if ((index + 1) % 4 == 0) {
        data = data + " "
      }
    
      return data
    })
    
    format= format.join("")
    console.log("format", format)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-18
      • 1970-01-01
      • 2022-01-14
      • 2017-08-21
      • 1970-01-01
      • 2011-08-22
      • 2023-04-10
      • 1970-01-01
      相关资源
      最近更新 更多