简体   繁体   English

如果一定数量的数字已经具有值,则阻止用户在输入字段中输入数字

[英]Prevent the user from entering a number in the input field if a certain number of them already have a value

I am currently working on a fee calculator.我目前正在研究费用计算器。 Here are the rules for the part of it that I am working on:以下是我正在研究的部分的规则:

  • There are 9 number input fields, A through I有 9 个数字输入字段,A 到 I
  • Input fields D, E, & F are mandatory.输入字段 D、E 和 F 是必需的。 The user MUST input a number (greater than 0) in AT LEAST 1 of these 3 input boxes (I have taken care of this aspect already)用户必须在这 3 个输入框中的至少1 个中输入一个数字(大于 0)(我已经处理过这方面的问题)
  • The user can only enter a number (greater than 0, no limit) into up to 6 of the 9 inputs, maximum用户最多只能在 9 个输入中的 6 个中输入一个数字(大于 0,无限制),最大

Something I have already achieved with this app, I have a few check boxes on the page, and the user must select at least 1, up to 5 maximum.我已经通过这个应用程序实现了一些目标,我在页面上有几个复选框,用户必须至少选择 1 个,最多选择 5 个。 Once a user checks 5 of those boxes, they cannot check a 6th.一旦用户选中了其中的 5 个框,他们就无法选中第 6 个。 If they un-check one of the 5, they can re-check a different one.如果他们取消选中 5 个中的一个,他们可以重新选中另一个。

So, I am looking to achieve a similar effect with these number inputs.因此,我希望通过这些数字输入实现类似的效果。

Once the user has entered a number (again, greater than 0) in up to 6 of the 9 input fields, they cannot enter something in the one of the 3 remaining inputs.一旦用户在 9 个输入字段中的最多 6 个中输入了一个数字(再次大于 0),他们将无法在剩余的 3 个输入之一中输入内容。 But if they were to remove their input from one of the 6 fields, they should be able to enter a number in one of the 4 other inputs, as now only 5 of them have something entered.但是,如果他们要从 6 个字段之一中删除他们的输入,他们应该能够在其他 4 个输入之一中输入一个数字,因为现在只有 5 个输入了内容。 Again this number can be any value greater than 0. It could be 10, 10,000 or 100,000, etc. The total values across the inputs doesn't matter, just HOW MANY of the 9 inputs you put a value in (again up to 6 maximum).同样,这个数字可以是大于 0 的任何值。它可以是 10、10,000 或 100,000 等。输入的总值无关紧要,只是您在 9 个输入中输入了多少(再次最多 6最大值)。

I am NOT asking for help with the calculations themselves, nor am I asking for help with the check boxes.我不是寻求计算本身的帮助,也不是寻求复选框的帮助。 I am just wanting some help on the functionality mentioned in the paragraph above.我只是想要一些有关上面段落中提到的功能的帮助。

Also, this must be done in plain vanilla JavaScript, no jQuery.此外,这必须用普通的 JavaScript 来完成,而不是 jQuery。

Any help finding this solution would be much appreciated!任何帮助找到此解决方案将不胜感激! Thanks!谢谢!

Here is the HTML :这是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>

And here is the JavaScript I have so far:这是我目前拥有的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!`);
    }
  });
});

EDIT: I was able to solve this after some slight modifications to my HTML and JS.编辑:在对我的 HTML 和 JS 稍作修改后,我能够解决这个问题。

I gave all 9 inputs the attribute data-changed="false" by default, instead of having it assigned dynamically based on user input.默认情况下,我为所有 9 个输入提供了属性data-changed="false" ,而不是根据用户输入动态分配它。 And similar to @7iiBob's answer, I put everything into blur , and I got the effect I needed:与@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;
          });
        }
      });
    });

You look pretty darn close to having this solved.你看起来非常接近解决这个问题。

Why not put everything into blur ?为什么不把一切都变得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')
      );
    }
  });
});

This is the logic.这就是逻辑。

Implant on checkboxes:植入复选框:

 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>

Implant on inputs:植入输入:

 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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM