Reset form invalid values
If you look at the input
DOM object, there is a property badInput
under validity
object whose value is a boolean
. For numeric entry or empty field, it's false
. However it's true
for non numeric values, which can interestingly be used in your case.
Note: Tested only on firefox
and safari
input
| +-- ...
| +-- validity
| | +-- badInput
| | +-- ...
| +-- ...
Using this knowledge you can modify the function to check for badInput
to achieve what you want with minimal tweaking.
// 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>
Update:
update to cover:
inputs with non-empty default values
One alternative to approach your goal is using a set of standard pseudo-classes
, like :invalid and :valid. Also note, we are going to use some array methods and features, like Array.some() and the 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>
If you are able to use placeholders
on your inputs
, then another possible solution is to use the CSS pseudo-class :placeholder-shown. However, give a check to the browser's support to be sure it will fit your need. Note it is experimental and is not recommended to use on production. Then, you can use the next selector
:
input:not(:placeholder-shown)
to get all inputs where the placeholder
is not shown, i.e, all not-empty inputs, and re-implement your code something like this:
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>