Сбросить неверные значения - PullRequest
6 голосов
/ 10 апреля 2019

Вот пример формы:

var form = document.querySelector('form');

function detectChange() {
  var inputs = form.querySelectorAll('input');
  for (var input of inputs) {
    if (input.value != input.defaultValue) {
      return true;
    }
  }
}

form.querySelector('button').addEventListener('click', function() {
  if (detectChange() && confirm('Are you sure you want to reset?')) {
    form.reset();
  }
});
<form>
  <input type="number">
  <input type="number" value="7">
  <button type="button">Reset</button>
</form>

Мне бы хотелось, чтобы кнопка сброса работала, даже если пользователь вводит нечисловые значения.

Ответы [ 8 ]

9 голосов
/ 12 апреля 2019

Если вы посмотрите на объект input DOM, в объекте validity есть свойство badInput, значение которого равно boolean. Для числового ввода или пустого поля это false. Однако это true для нечисловых значений, которые могут интересно использоваться в вашем случае.

Примечание: проверено только на firefox и safari

input
|  +-- ...
|  +-- validity
|  |   +-- badInput
|  |   +-- ...
|  +-- ...

Используя эти знания, вы можете изменить функцию для проверки на badInput, чтобы достичь того, что вы хотите, с минимальной настройкой.

// non-empty and non default
if ((input.value && input.value != input.defaultValue) || input.validity.badInput)

var form = document.querySelector('form');

function detectChange() {
  var inputs = form.querySelectorAll('input');
  for (var input of inputs) {
    if ((input.value && input.value != input.defaultValue) || input.validity.badInput) {
      return true;
    }
  }
}

form.querySelector('button').addEventListener('click', function() {
  if (detectChange() && confirm('Are you sure you want to reset?')) {
    form.reset();
  }
});
<form>
  <input type="number">
  <input type="number" value="11">
  <button type="button">Reset</button>
</form>

Обновление:

обновление для покрытия:

входы с непустыми значениями по умолчанию

3 голосов
/ 13 апреля 2019

Одной альтернативой для достижения вашей цели является использование набора стандартных pseudo-classes, таких как : недействительные и : действительные .Также обратите внимание, что мы собираемся использовать некоторые методы и функции массива, такие как Array.some () и Spread Syntax :

var form = document.querySelector('form');

function detectChange()
{
    var invalids = form.querySelectorAll('input:invalid');
    var valids = form.querySelectorAll('input:valid');
    return (invalids.length > 0) || [...valids].some(i => i.defaultValue !== i.value);
}

form.querySelector('button').addEventListener('click', function()
{
    if (detectChange() && confirm('Are you sure you want to reset?'))
        form.reset();
});
<form>
  <input type="number">
  <input type="number">
  <input type="number" value="7">
  <button type="button">Reset</button>
</form>

Если вы можете использовать placeholders на своем inputs, то другим возможным решением является использование псевдокласса CSS : указывается заполнитель .Тем не менее, проверьте поддержку браузера , чтобы убедиться, что он будет соответствовать вашим потребностям.Обратите внимание, что экспериментальный и не рекомендуется для использования на производстве.Затем вы можете использовать следующие selector:

input:not(:placeholder-shown)

, чтобы получить все входы, где placeholder не отображается, т. Е. Все непустые входы, и повторнореализовать свой код примерно так:

var form = document.querySelector('form');

function detectChange()
{
    var inputs = form.querySelectorAll(
        'input:not([value]):not(:placeholder-shown), input[value]'
    );
    return [...inputs].some(i => !i.defaultValue || i.defaultValue !== i.value);
}

form.querySelector('button').addEventListener('click', function()
{
    if (detectChange() && confirm('Are you sure you want to reset?'))
        form.reset();
});
<form>
  <input type="number" placeholder="Insert a number">
  <input type="number" placeholder="Insert a number">
  <input type="number" value="7" placeholder="Insert a number">
  <button type="button">Reset</button>
</form>
1 голос
/ 10 апреля 2019

Изменить это:

<button type="button">Reset</button>

TO

<input type="reset" value="Reset"/>
0 голосов
/ 16 апреля 2019
<form>
  <input type="number">
  <input type="number">
  <button type="button" onclick="resetData()">Reset</button>
</form>


function resetData(){
    var y = document.querySelectorAll('input,textarea');
        for (var i= 0; i < y.length; i++) {
        var id =y[i].id;
        if(y[i].value !=''&&y[i].value!= 'undefined'){
        document.getElementById(id).value="";
        }
        } 
}
0 голосов
/ 13 апреля 2019

Просто используйте button type="reset" и подключите прослушиватель событий к form, который прослушивает reset события.

Основная проблема с вашим кодом состоит в том, что ваша функция detectChange() никогда не будет работатьдля неверного ввода, потому что браузеры всегда будут возвращать пустую строку для любого нечислового ввода, если вы запрашиваете значение.Это по спецификации.Отметьте https://stackoverflow.com/a/18853513/3744304

Решение этой проблемы было предложено изначально в ответе @naga - elixir - jar.Отредактировал мой ответ: а) чтобы он работал, и б) чтобы собрать все это в сжатой форме, ES6.

const form = document.querySelector('form');

form.addEventListener('reset', (event) => {
  if (detectChange() && !confirm('Are you sure you want to reset?')) {
    event.preventDefault();
  }
});

function detectChange() { 
  return [...form.querySelectorAll('input')].some(el => el.validity.badInput || el.value !== el.defaultValue); 
};
<form>
  <input type="number" value="87">
  <input type="number">
  <button type="reset">Reset</button>
</form>
0 голосов
/ 13 апреля 2019

Просто установите прослушиватель событий для onkeydown, onpaste элемента ввода:

const inputs = document.querySelectorAll('input[type=number]')
inputs.forEach((el) => el.onkeydown = el.onpaste = (event) => event.target.dataset.receivedEntry = 1)

Затем проверьте input.dataset.receivedEntry in detectChange :

function detectChange () {
  const inputs = form.querySelectorAll('input');
  for (var input of inputs) {
    if (input.dataset.receivedEntry) {
      return true;
    }
  }
}
0 голосов
/ 12 апреля 2019

var form = document.querySelector('form');
var btn = form.querySelector('button');
var inputs = form.querySelectorAll('input');
btn.disabled = true;
btn.addEventListener('click', function() {
  if (confirm('Are you sure you want to reset?')) {
    form.reset();
    btn.disabled = true;
  }
});

for (var input of inputs) {
  input.addEventListener('keypress', detectSpace)
  input.addEventListener('input', handleChange);
}

function handleChange(e) {
  var disabled = true;
  for (var input of inputs) {
    input.value = input.value.trim()
    if (input.value) {
      disabled = false
    }
  }
  btn.disabled = disabled
}

function detectSpace(e) {
  if (e.keyCode == 32) {
    e.preventDefault();
    return false
  }
}
<form>
  <input type="number">
  <input type="number">
  <button type="button">Reset</button>
</form>

это будет работать?он предотвращает вставку пользователем номера, обрезая значение внутри input type="number".

detectSpace есть, потому что в Firefox пробел удалит число, потому что оно недопустимо.

0 голосов
/ 11 апреля 2019

Зацикливание полей ввода и установка значений вручную = "";

var form = document.querySelector('form');

function detectChange() {
  var inputs = form.querySelectorAll('input');
  for (var input of inputs) {
    input.value = "";
  }
}

form.querySelector('button').addEventListener('click', function() {
  if (confirm('Are you sure you want to reset?')) {
    detectChange(); 
  }
});
<form>
  <input type="number">
  <input type="number">
  <button type="button">Reset</button>
</form>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...