Reputation: 6780
Here's a sample form:
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>
I'd like the reset button to work even if the user enters non-numeric values.
Upvotes: 6
Views: 2780
Reputation: 374
<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="";
}
}
}
Upvotes: -1
Reputation: 17190
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>
Upvotes: 2
Reputation: 56753
Simply use a button type="reset"
, and attach an event listener on the form
that listens for reset
events.
The main problem with your code is that your detectChange()
function will never work for invalid input because browsers will always return the empty string for any non-numeric input if you ask for the value. This is by the specification. Check https://stackoverflow.com/a/18853513/3744304
The solution to fix this has been suggested originally in @naga - elixir - jar's answer. Edited my answer a) to make it working answer and b) to put it all together in a concise, ES6 way.
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>
Upvotes: 0
Reputation: 6718
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
Upvotes: 10
Reputation: 81
Just set an event listener for onkeydown
, onpaste
of the input element:
const inputs = document.querySelectorAll('input[type=number]')
inputs.forEach((el) => el.onkeydown = el.onpaste = (event) => event.target.dataset.receivedEntry = 1)
Then check for the input.dataset.receivedEntry
in detectChange:
function detectChange () {
const inputs = form.querySelectorAll('input');
for (var input of inputs) {
if (input.dataset.receivedEntry) {
return true;
}
}
}
Upvotes: 0
Reputation: 1459
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>
will this work? it prevents user from pasting into number by trimming the value inside input type="number"
.
detectSpace
is there because in firefox hitting space will delete the number because is not a valid one.
Upvotes: -1
Reputation: 1337
Loop over the input fields and manually set values = "";
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>
Upvotes: 0
Reputation: 4032
Change this:
<button type="button">Reset</button>
TO
<input type="reset" value="Reset"/>
Upvotes: 1