Запретить пользователю вводить число в поле ввода, если определенное число из них уже имеет значение - PullRequest
0 голосов
/ 13 января 2020

Я сейчас работаю над калькулятором комиссии. Вот правила для той части, над которой я работаю:

  • Есть 9 числовых полей ввода, от A до I
  • Поля ввода D, E и F являются обязательными , Пользователь ДОЛЖЕН ввести число (больше 0) в ПО МЕНЬШЕ 1 из этих 3 полей ввода (я уже позаботился об этом аспекте)
  • Пользователь могу только ввести число (больше 0, без ограничений) в 6 из 9 входов, максимум

Что-то, чего я уже достиг с этим приложением, у меня есть несколько флажков на странице и пользователь должен выбрать как минимум 1, максимум 5. Как только пользователь проверяет 5 из этих полей, он не может установить 6-ую. Если они отменяют выбор одного из 5, они могут повторно проверить другой.

Итак, я рассчитываю добиться аналогичного эффекта с этими числовыми входами.

Как только пользователь ввел число (опять же, больше 0) в до 6 из 9 полей ввода, он не может что-то ввести в одно из 3 оставшихся вводов. Но если они удалят свои данные из одного из 6 полей, они должны иметь возможность ввести число в одном из 4 других входов, так как теперь только 5 из них что-то вводили. Опять же, это число может быть любым значением больше 0. Это может быть 10, 10000 или 100000 и т. Д. c. Суммарные значения по всем входам не имеют значения, просто СКОЛЬКО из 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;
          });
        }
      });
    });

Ответы [ 2 ]

1 голос
/ 13 января 2020

Ты выглядишь чертовски близко к решению этой проблемы.

Почему бы не положить все в 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')
      );
    }
  });
});
0 голосов
/ 13 января 2020

Это логика c.

Имплантат на флажках:

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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...