【问题标题】:Prevent the user from entering a number in the input field if a certain number of them already have a value如果一定数量的数字已经有值,则阻止用户在输入字段中输入数字
【发布时间】:2020-01-12 22:19:46
【问题描述】:

我目前正在研究费用计算器。以下是我正在处理的部分规则:

  • 有 9 个数字输入字段,A 到 I
  • 输入字段 D、E 和 F 为必填项。用户必须在这 3 个输入框中的至少 1 个输入一个数字(大于 0)(我已经处理了这方面的问题)
  • 用户最多只能在 9 个输入中的 6 个输入一个数字(大于 0,无限制)

我已经用这个应用程序实现了一些东西,我在页面上有几个复选框,用户必须选择至少 1 个,最多 5 个。一旦用户选中了其中的 5 个,他们就无法选中第 6 个。如果他们取消选中 5 个中的一个,他们可以重新选中另一个。

所以,我希望通过这些数字输入实现类似的效果。

一旦用户在 9 个输入字段中的最多 6 个输入了数字(同样大于 0),他们就无法在剩下的 3 个输入之一中输入内容。但是,如果他们要从 6 个字段之一中删除他们的输入,他们应该能够在其他 4 个输入之一中输入一个数字,因为现在他们中只有 5 个输入了一些内容。同样,这个数字可以是大于 0 的任何值。它可以是 10、10,000 或 100,000 等。输入的总值无关紧要,只需将值放入 9 个输入中的多少(同样最多 6 个)最大)。

我不是就计算本身寻求帮助,也不是就复选框寻求帮助。我只是想要一些关于上面段落中提到的功能的帮助。

此外,这必须用普通的 JavaScript 完成,而不是 jQuery。

任何帮助找到此解决方案将不胜感激!谢谢!

这里是 HTML

<div>
    <div>
      <label for="Input A">Input A</label>
      <input class="entity-input license-input" type="number" name="Input A" value="0" min="0">
    </div>
    <div>
      <label for="Input B">Input B</label>
      <input class="entity-input license-input" type="number" name="Input B" value="0" min="0">
    </div>
    <div>
      <label for="Input C">Input C</label>
      <input class="entity-input license-input" type="number" name="Input C" value="0" min="0">
    </div>
    <div>
      <label for="Input D">Input D</label>
      <input class="entity-input license-input-mandatory" type="number" name="Input D" value="0" min="0">
    </div>
    <div>
      <label for="Input E">Input E</label>
      <input class="entity-input license-input-mandatory" type="number" name="Input E" value="0" min="0">
    </div>
    <div>
      <label for="Input F">Input F</label>
      <input class="entity-input license-input-mandatory" type="number" name="Input F" value="0" min="0">
    </div>
    <div>
      <label for="Input G">Input G</label>
      <input class="entity-input distribution-input" type="number" name="Input G" value="0" min="0">
    </div>
    <div>
      <label for="Input H">Input H</label>
      <input class="entity-input distribution-input" type="number" name="Input H" value="0" min="0">
    </div>
    <div>
      <label for="Input I">Input I</label>
      <input class="entity-input distribution-input" type="number" name="Input I" value="0" min="0">
    </div>
  </div>

这是我目前拥有的 JavaScript

// Select all elements with class of entity-input
const ENTITY_INPUTS = document.querySelectorAll('.entity-input');

// Prevent user from entering a number on 7th number input (cannot fill in more than 6)
ENTITY_INPUTS.forEach((input) => {
  const MAX = 6;

  // Upon leaving the input, assign a data-changed attr with a value of true or false depending on whether the value has changed
  input.addEventListener('blur', () => {
    if (input.value == 0) {
      input.removeAttribute('data-changed', 'true');
      input.setAttribute('data-changed', 'false');
    } else if (input.value !== 0) {
      input.removeAttribute('data-changed', 'false');
      input.setAttribute('data-changed', 'true');
    }

    let unchangedInputs = document.querySelectorAll('[data-changed="false"]');
    if (unchangedInputs.length !== []) {
      console.log(`The number of inputs with a value still at zero is ${unchangedInputs.length}`);
    }
  });

  // Count the number of inputs with data-changed set to true - can't be more than 6
  input.addEventListener('focus', () => {
    let changedInputs = document.querySelectorAll('[data-changed="true"]');
    console.log(`The number of inputs with a value more than zero is ${changedInputs.length}`);

    if (changedInputs.length == MAX && input.value > 0) {
      console.log(`You may change this element`);
    } else if (changedInputs.length == MAX) {
      console.log(`You can't enter any more numbers!`);
    }
  });
});

编辑:在对我的 HTML 和 JS 稍作修改后,我能够解决这个问题。

默认情况下,我给所有 9 个输入属性 data-changed="false",而不是根据用户输入动态分配它。和@7iiBob的回答类似,我把所有的东西都放到blur中,得到了我需要的效果:

   ENTITY_INPUTS.forEach((input) => {
      const REMAINING_INPUTS = 3;

      // Upon leaving the input, assign a data-changed attr with a value of true or false depending on whether the value has changed
      input.addEventListener('blur', () => {
        if (input.value == 0) {
          input.removeAttribute('data-changed', 'true');
          input.setAttribute('data-changed', 'false');
        } else if (input.value !== 0) {
          input.removeAttribute('data-changed', 'false');
          input.setAttribute('data-changed', 'true');
        }

        // upon leaving, check number of elements still with data-changed set to false
        // if the number of elements is equal to 3, set them to disabled
        // else, leave them alone (set disabled to false)
        let unchangedInputs = document.querySelectorAll('[data-changed="false"]');

        if (unchangedInputs.length == REMAINING_INPUTS) {
          unchangedInputs.forEach((input) => {
            input.disabled = true;
          });
        } else {
          unchangedInputs.forEach((input) => {
            input.disabled = false;
          });
        }
      });
    });

【问题讨论】:

    标签: javascript html validation input


    【解决方案1】:

    你看起来非常接近解决这个问题。

    为什么不把所有东西都放到blur 中呢?

    // Select all elements with class of entity-input
    const ENTITY_INPUTS = document.querySelectorAll('.entity-input');
    
    // Prevent user from entering a number on 7th number input (cannot fill in more than 6)
    ENTITY_INPUTS.forEach(input => {
      const MAX = 6;
    
      // Upon leaving the input, assign a data-changed attr with a value of true or false depending on whether the value has changed
      input.addEventListener('blur', () => {
        if (input.value == 0) {
          input.removeAttribute('data-changed', 'true');
          input.setAttribute('data-changed', 'false');
        } else if (input.value !== 0) {
          input.removeAttribute('data-changed', 'false');
          input.setAttribute('data-changed', 'true');
        }
    
        let changedInputs = document.querySelectorAll('[data-changed="true"]');
        let unchangedInputs = document.querySelectorAll('[data-changed="false"]');
    
        if (changedInputs.length == MAX) {
          unchangedInputs.forEach(inputToDisable =>
            inputToDisable.setAttribute('disabled', 'true')
          );
        } else if (changedInputs.length < MAX) {
          unchangedInputs.forEach(inputToEnable =>
            inputToEnable.setAttribute('disabled', 'false')
          );
        }
      });
    });
    

    【讨论】:

    • 是的,我把所有东西都模糊了!谢谢!
    • 不错。不用担心。
    【解决方案2】:

    这就是逻辑。

    植入复选框:

    let inputCheckboxesLength = 0; // initial counter to 0
    const inputCheckboxes = document.querySelectorAll('#inputCheck input'); // target the checkboxes
    for (var i=0; i < inputCheckboxes.length; i++) { // iterate checkboxes
      inputCheckboxes[i].addEventListener('change', function() { // listen to changne event:
        if (this.checked) { // if one of the checkboxes selected:
          ++inputCheckboxesLength; // increase the count
          if (inputCheckboxesLength === 6) { // if the count more then 5 (equal to 6)
            alert ('You cannot check more then 5 checkboxes!'); // alert error message 
            inputCheckboxesLength = 5; // change the count back to 5
            this.checked = false; // remove the checked for the last checkbox
          }
        }    
        else {  
          --inputCheckboxesLength // decrease the count - will tirgger when user remove check-mark from checkbox
        } 
    
      });
    }
    <fieldset id="inputCheck">
      <label for="check1">1<input type="checkbox" id="check1" /></label>
      <label for="check2">2<input type="checkbox" id="check2" /></label>
      <label for="check3">3<input type="checkbox" id="check3" /></label>
      <label for="check4">4<input type="checkbox" id="check4" /></label>
      <label for="check5">5<input type="checkbox" id="check5" /></label>
      <label for="check6">6<input type="checkbox" id="check6" /></label>
      <label for="check7">7<input type="checkbox" id="check7" /></label>
      <label for="check8">8<input type="checkbox" id="check8" /></label>
    </fieldset>

    植入输入:

    let inputNumberLength = 0; // initial counter to 0
    const inputNumbers = document.querySelectorAll('#inputNumber input'); // target the inputs
    for (var i=0; i < inputNumbers.length; i++) { // iterate inputs
      inputNumbers[i].addEventListener('change', function() { // listen to changne event:
       if (this.value.length > 0) {
          ++inputNumberLength; // increase the count
          if (inputNumberLength === 6) { // if the count more then 5 (equal to 6)
            alert ('You cannot put more then 5 values!'); // alert error message 
            inputNumberLength = 5; // change the count back to 5
            this.value = ''; // remove the value for the last input
          }
        }    
        else {  
          --inputNumberLength // decrease the count - will tirgger when user remove check-mark from checkbox
        } 
    
      });
    }
    <fieldset id="inputNumber">
      <label for="a"><input type="number" id="a" /></label>
      <label for="b"><input type="number" id="b" /></label>
      <label for="c"><input type="number" id="c" /></label>
      <label for="d"><input type="number" id="d" /></label>
      <label for="e"><input type="number" id="e" /></label>
      <label for="f"><input type="number" id="f" /></label>
      <label for="g"><input type="number" id="g" /></label>
      <label for="h"><input type="number" id="h" /></label>
      <label for="i"><input type="number" id="i" /></label>
    </fieldset>

    【讨论】:

    • 你好梅舒。如前所述,我已经在页面上拥有复选框的功能,因为我最多可以检查 5 个框,但不能检查第 6 个。正如我所说,我想要实现的功能类似于复选框。我希望用户能够在 9 个框中的最多 6 个中输入数字,一旦发生这种情况,他们就无法在其余 3 个字段中输入数字。但是,如果他们应该从 6 个输入之一中删除他们的输入,那么现在在剩下的 4 个输入之一中再次输入一些内容。我将重新提出我的问题。不过谢谢你的回答。
    • 嘿 Meshu,对不起,但这也不是我想要的。输入的总值无关紧要。每个单独输入的值没有限制。可能是 10、100 或 10,000,没关系。重要的是用户输入了多少个值。它不能超过 9 个中的 6 个。我已经编辑了我的问题再次提及这一点。
    • 我使用 value 来了解是否限制用户在其他输入上输入数据。抱歉,这是我现在能带的最好的。祝你好运。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-27
    • 2017-11-18
    • 2015-02-27
    • 1970-01-01
    • 2012-03-06
    • 2023-03-30
    相关资源
    最近更新 更多