Found lots of answers for this in jQuery, but I want to do it in pure Javascript. This code doesn't work. It enabled when all the fields are filled, but enables again when I remove the text in one of them. What is wrong with this?
<form action='' method='post'>
<input type='text' class='req' id='required_0' onkeydown='enableSubmit()' required>
<input type='text' class='req' id='required_1' onkeydown='enableSubmit()' required>
<input type='text' class='req' id='required_2' onkeydown='enableSubmit()' required>
<input type='submit' value='Submit' disabled>
</form>
<script>
function enableSubmit(){
let inputs = document.getElementsByClassName('req');
let btn = document.querySelector('input[type="submit"]');
let disabled = false;
for (var i = 0; i < inputs.length; i++){
let changedInput = document.querySelector('#required_' + i);
if (changedInput.value.trim() == "" || changedInput.value == null){
btn.disabled = true;
console.log("Button disabled");
} else {
btn.disabled = false;
console.log("Button enabled")
}
}
}
</script>
EDIT: Thank you for all the answers, I didn't think I would get that many - so I don't really know who I should choose as "answer" for the cred. Please ment below with your pick (and why) to help me choose.
Found lots of answers for this in jQuery, but I want to do it in pure Javascript. This code doesn't work. It enabled when all the fields are filled, but enables again when I remove the text in one of them. What is wrong with this?
<form action='' method='post'>
<input type='text' class='req' id='required_0' onkeydown='enableSubmit()' required>
<input type='text' class='req' id='required_1' onkeydown='enableSubmit()' required>
<input type='text' class='req' id='required_2' onkeydown='enableSubmit()' required>
<input type='submit' value='Submit' disabled>
</form>
<script>
function enableSubmit(){
let inputs = document.getElementsByClassName('req');
let btn = document.querySelector('input[type="submit"]');
let disabled = false;
for (var i = 0; i < inputs.length; i++){
let changedInput = document.querySelector('#required_' + i);
if (changedInput.value.trim() == "" || changedInput.value == null){
btn.disabled = true;
console.log("Button disabled");
} else {
btn.disabled = false;
console.log("Button enabled")
}
}
}
</script>
EDIT: Thank you for all the answers, I didn't think I would get that many - so I don't really know who I should choose as "answer" for the cred. Please ment below with your pick (and why) to help me choose.
Share edited Jul 7, 2020 at 10:29 maggiato asked Jul 7, 2020 at 9:04 maggiatomaggiato 277 bronze badges 2- “What is wrong with this?” - you are disabling the button inside your loop, so of course that will happen after the first input field you encounter, that satisfies your conditions. You need to use a flag, toggle that based on the checks of your input fields, and then set the button state after the loop, based on that flag. – C3roe Commented Jul 7, 2020 at 9:06
- fun fact: because you marked all the text fields as "required", the native HTML5 validation will prevent form submission unless all fields are filled. You need a "novalidate" attribute on the form. – Touffy Commented Jul 7, 2020 at 9:24
8 Answers
Reset to default 3You cannot fix this with a onkeydown, cause it will not correctly trigger the event. onkeyup does the job. Look to a working variant.
I've a bit optimised your code.
- You already filtered out the inputs with let inputs = document.getElementsByClassName('req');
- on first empty field we break the loop with break;
function enableSubmit(){
let inputs = document.getElementsByClassName('req');
let btn = document.querySelector('input[type="submit"]');
let isValid = true;
for (var i = 0; i < inputs.length; i++){
let changedInput = inputs[i];
if (changedInput.value.trim() === "" || changedInput.value === null){
isValid = false;
break;
}
}
btn.disabled = !isValid;
}
<form action='' method='post'>
<input type='text' class='req' id='required_0' onkeyup='enableSubmit()' required>
<input type='text' class='req' id='required_1' onkeyup='enableSubmit()' required>
<input type='text' class='req' id='required_2' onkeyup='enableSubmit()' required>
<input type='submit' value='Submit' disabled>
</form>
Good answers @Max Kaps 4bis.nl! What I can add is that the code would not response on mouse events. I can cut or insert with a mouse.
My updated version
function enableSubmit(){
let inputs = document.getElementsByClassName('req');
let btn = document.querySelector('input[type="submit"]');
let isValid = true;
for (var i = 0; i < inputs.length; i++){
let changedInput = inputs[i];
if (changedInput.value.trim() === "" || changedInput.value === null){
isValid = false;
break;
}
}
btn.disabled = !isValid;
}
<form action='' method='post'>
<input type='text' class='req' id='required_0' onkeyup='enableSubmit()' onmousedown='enableSubmit()' oninput='enableSubmit()' required>
<input type='text' class='req' id='required_1' onkeyup='enableSubmit()' onmousedown='enableSubmit()' oninput='enableSubmit()' required>
<input type='text' class='req' id='required_2' onkeyup='enableSubmit()' onmousedown='enableSubmit()' oninput='enableSubmit()' required>
<input type='submit' value='Submit' disabled>
</form>
In your loop, you are enabling the button as soon as you find one input which isn't null or empty. You need to change your code to check that all fields are pleted.
You could do this several ways. But easiest would be to invert your logic. Set the button to be enabled. Then only disable it if any field is inplete.
function enableSubmit(){
let inputs = document.getElementsByClassName('req');
let btn = document.querySelector('input[type="submit"]');
btn.disabled = false;
for (var i = 0; i < inputs.length; i++){
let changedInput = document.querySelector('#required_' + i);
if (changedInput.value.trim() == "" || changedInput.value == null){
btn.disabled = true;
console.log("Found an inplete field, set disabled to true");
}
}
}
This might seem a bit ugly, because you are setting the button state twice. So another mon approach is to use a flag instead.
function enableSubmit(){
let inputs = document.getElementsByClassName('req');
let btn = document.querySelector('input[type="submit"]');
let disabled = false;
for (var i = 0; i < inputs.length; i++){
let changedInput = document.querySelector('#required_' + i);
if (changedInput.value.trim() == "" || changedInput.value == null){
disabled = true;
console.log("Found an inplete field, set disabled to true");
}
}
btn.disabled = disabled;
}
However, this will still not work perfectly, because you are calling the check on key down. When the key is pressed, the value of the field is not yet updated, and so the first time you type in the final input, the button will still be disabled. Better to use on key up. I've updated this in the fiddler below.
Fiddler link here - https://jsfiddle/8yaenwx7/
My input - while we are checking let's disable the button until we are sure about.
function enableSubmit(){
let inputs = document.getElementsByClassName('req');
let btn = document.querySelector('input[type="submit"]');
let isValid = true;
btn.disabled = true;
for (var i = 0; i < inputs.length; i++){
let changedInput = inputs[i];
if (changedInput.value.trim() === "" || changedInput.value === null){
isValid = false;
break;
}
}
btn.disabled = !isValid;
}
<form action='' method='post'>
<input type='text' class='req' id='required_0' onkeyup='enableSubmit()' onmousedown='enableSubmit()' oninput='enableSubmit()' required>
<input type='text' class='req' id='required_1' onkeyup='enableSubmit()' onmousedown='enableSubmit()' oninput='enableSubmit()' required>
<input type='text' class='req' id='required_2' onkeyup='enableSubmit()' onmousedown='enableSubmit()' oninput='enableSubmit()' required>
<input type='submit' value='Submit' disabled>
</form>
This should fix your problem:
function enableSubmit(){
let inputs = document.getElementsByClassName('req');
let btn = document.querySelector('input[type="submit"]');
let isValid = true;
for (var i = 0; i < inputs.length; i++){
let changedInput = document.querySelector('#required_' + i);
if (changedInput.value.trim() === "" || changedInput.value === null){
isValid = false;
}
}
btn.disabled = !isValid;
}
<form action='' method='post'>
<input type='text' class='req' id='required_0' onkeydown='enableSubmit()' required>
<input type='text' class='req' id='required_1' onkeydown='enableSubmit()' required>
<input type='text' class='req' id='required_2' onkeydown='enableSubmit()' required>
<input type='submit' value='Submit' disabled>
</form>
In the above approach there is a loophole. Because as you loop from first field to last and even if I find only the last field filled it will enable the button. I modified the script and got it working.
function enable(){
let inputs = document.getElementsByClassName('req');
let btn = document.querySelector('input[type="submit"]');
let i;
for(i = 0;i < inputs.length;i++){
let change = document.querySelector('#required_'+i);
if(change.value.trim() == "" || change.value == null){
break;
}
}
if(i == inputs.length)
btn.disabled = false;
}
I have just modified the loop by breaking if the input is null or empty.
First, let's tweak your HTML a bit. Most importantly, novalidate
will prevent native constraint validation from blocking form submission unless all fields are filled (because they are required
. Also, don't forget to name your fields, especially for direct HTTP submission.
<form name='myForm' novalidate action='' method='post'>
<input name='field0' required>
<input name='field1' required>
<input name='field2' required>
<input type='submit' value='Submit' disabled>
</form>
Now for the JavaScript, we can actually use native validation to count how many fields are valid. We want less than 3 and, I assume, at least one ?
const myForm = document.forms.myForm
// this is more efficient than adding a listener on each field separately
myForm.addEventListener('input', enableSubmit)
function enableSubmit() {
const button = myForm[3]
// get all the fields in an array
const validInputCount = [...myForm.elements].slice(0, 3)
// then count how many are valid
.reduce((sum, input) => sum + input.checkValidity(), 0)
// finally apply your custom rule
button.disabled = validInputCount > 0 && validInputCount < 3
}
Here is a non-javascript solution with pure CSS. Less code to handle.
I added a onsubmit false
on the form just as an example, just as I added input:invalid
as a style. I also added some default text to show case the validation.
The pattern
is validated through regex:
.*
means any number of characters, including no characters.
\S
is catching non-whitespaces
form:invalid > input[type="submit"] {
opacity: 0.5;
pointer-events: none;
}
input:invalid {
background-color: red;
}
<form onsubmit='return false' action='' method='post'>
<input type='text' required pattern=".*\S.*" value="text"><br/>
<input type='text' required pattern=".*\S.*" value=" text text "><br/>
<input type='text' required pattern=".*\S.*"><br/>
<input type='submit' value='Submit'>
</form>
You could remove form:invalid > input[type="submit"] {
and let the browser handle any errors. It wont submit unless all the requirements are fulfilled for all inputs.
input:invalid {
background-color: red;
}
<form onsubmit='return false' action='' method='post'>
<input type='text' required pattern=".*\S.*" value="text"><br/>
<input type='text' required pattern=".*\S.*" value=" text text "><br/>
<input type='text' required pattern=".*\S.*"><br/>
<input type='submit' value='Submit'>
</form>
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1742406302a4437915.html
评论列表(0条)