【问题标题】:Issue with custom input field for number input in range format [low-high]范围格式数字输入的自定义输入字段问题 [低-高]
【发布时间】:2021-04-10 00:59:59
【问题描述】:

问题陈述

接受 [1-N] 内的 数字有效范围,其中 N 来自 上一页。

条件:

  • 作为输入输入的任何数字都必须在 [1 - N] 范围内
  • 输入的任何范围都必须以 [low - high] 格式有效,并且 [1

动态防止无效输入。

示例测试用例

如果输入的输入为 N = 45

  • 0 -> 删除它,因为它是无效的,即不在有效范围内 [1 - N]
  • 46 -> 删除第二个数字“6”,因为它使数字大于 N
  • 保留 1 到 45 之间的任何数字,因为它是有效数字
  • 13-14 或 12-24 接受此输入,因为它满足 [1
  • 12-11 或 24-46 -> 删除最后一个数字“1”或“6”,因为它使范围 无效

问题

很难输入有效的范围输入,因为它会在以下情况下剪掉数字 输入范围内的“高”数字。

当保持“高”数字中的第一个数字和第二个数字时正常工作 被输入。这是由于onkeyup 事件未针对第一个数字触发 “高”数。

代码

https://jsfiddle.net/manid2/9onbdamj/5/

需要一些小的改变我不确定它是什么,因为我不知道 主要在前端工作。

【问题讨论】:

    标签: javascript html-input onkeyup


    【解决方案1】:

    如果添加setTimeout这部分,代码会等待一段时间再进行评估。

        else if (KC_DIGITS.includes(key_pressed)) {
        let that = this
        setTimeout(function(){ 
          if (!parseAndValidateOldVal(regex_res)) {
            console.log("text number value is invalid");
            $(that).val(function(i, val) {
              return val.slice(0, -1);
            });
          }
        }, 1000);
      }
    

    现场演示:

    //mz_form_script.js
    
    // global variables
    const USER_UPPER_NUM = 45;
    const KC_BACKSPACE = 8;
    const KC_END = 35;
    const KC_HOME = 36;
    const KC_ARROW_KEYS = [37, 38, 39, 40];
    const KC_NUMPAD_DASH = [109, 173, 189];
    var _kc_digits = []; {
      // Digit0 to Digit9
      for (var i = 48; i < 58; ++i) {
        _kc_digits.push(i);
      }
      // Numpad0 to Numpad9
      for (var i = 96; i < 106; ++i) {
        _kc_digits.push(i);
      }
    }
    const KC_DIGITS = _kc_digits;
    
    $(document).ready(function() {
      // insert num into para
      var user_input_num_p = $("#doc_user_input_p");
      user_input_num_p.text(USER_UPPER_NUM.toString());
    
      // restrict user input
      var user_input_num_t = $("#doc_cb_3_num_input_1");
      user_input_num_t.attr({
        placeholder: "1-" + Number(user_input_num_p.text()),
        min: 1,
        max: Number(user_input_num_p.text()),
      });
      user_input_num_t.keyup(handleDocCb3NumInput);
    });
    
    /**
     * To handle doc cb 3 user input
     *
     * @param {input} event
     */
    function handleDocCb3NumInput(event) {
      const key_pressed = event.which;
      var old_val = $(this).val();
    
      console.log("key_pressed = " + key_pressed);
      console.log("old_val = " + old_val);
    
      // check for valid characters
      // TODO: below regex does not work correctly with onkeyup
      //(/^(\d{0,5}|\b(\d{0,5}-\d{0,5})\b)$/gm);
      var regex_res = old_val.match(/^(\d{0,5}|(\d{0,5}-\d{0,5}))$/g);
      if (null == regex_res) {
        console.log("regex is invalid, key: " + key_pressed);
        $(this).val(function(i, val) {
          return val.slice(0, -1);
        });
        return;
      } else {
        console.log("regex matched: " + regex_res);
      }
    
      var key_char = "";
      // valid ctrl keys
      if (
        KC_BACKSPACE == key_pressed ||
        KC_HOME == key_pressed ||
        KC_END == key_pressed ||
        KC_ARROW_KEYS.includes(key_pressed)
      ) {
        console.log("key_pressed is valid ctrl char");
      } else if (KC_NUMPAD_DASH.includes(key_pressed)) {
        key_char = "-";
        console.log("key_pressed is valid char: " + key_char);
      } else if (KC_DIGITS.includes(key_pressed)) {
        let that = this
        setTimeout(function(){ 
          if (!parseAndValidateOldVal(regex_res)) {
            console.log("text number value is invalid");
            $(that).val(function(i, val) {
              return val.slice(0, -1);
            });
          }
        }, 1000);
      }
      // invalid keys
      else {
        console.log("invalid key: " + key_pressed);
        $(this).val(function(i, val) {
          return val.slice(0, -1);
        });
      }
    }
    
    function parseAndValidateOldVal(regex_res) {
      var input_val = regex_res.toString();
      // is invalid
      if (input_val.startsWith("-") || input_val.endsWith("-")) {
        return false;
      }
      var input_val_num = Number(input_val);
      // is range and range is valid [1 < l < h < USER_UPPER_NUM]
      if (isNaN(input_val_num)) {
        var res = input_val.split("-", 2);
        var low = Number(res[0]);
        var high = Number(res[1]);
        if (low >= high || low < 1 || high > USER_UPPER_NUM) return false;
      }
      // is single number and [1 < val < USER_UPPER_NUM]
      else if (input_val_num < 1 || input_val_num > USER_UPPER_NUM) {
        return false;
      }
      return true;
    }
    <!DOCTYPE html>
    <html lang="en">
    
      <head>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <title>MZ form</title>
      </head>
    
      <body>
        <h1>Handle form input dynamically</h1>
    
        <p>User input: <span id="doc_user_input_p" style="font-weight: bold;"></span></p>
    
        <form id="doc_cb_3" method="get">
          <input type="text" placeholder="1" id="doc_cb_3_num_input_1" name="doc_cb_3_num" />
          <button name="send" type="submit" value="ok">ok</button>
        </form>
    
        <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
        <script src="mz_form_script.js"></script>
      </body>
    
    </html>

    【讨论】:

    • 嗨@dolmushcu 我尝试了这种方法,它的工作原理相同,即使输入范围有效,最后一个数字也会在删除后被删除。谢谢你的建议。我认为也许这种验证不应该实施。
    猜你喜欢
    • 2020-03-15
    • 2011-04-08
    • 1970-01-01
    • 2019-09-27
    • 1970-01-01
    • 2013-10-13
    • 1970-01-01
    • 1970-01-01
    • 2020-01-12
    相关资源
    最近更新 更多