I've got a form and a submit button that needs to be disabled until all required inputs are filled in. Some inputs are text, and some are dropdowns. I've read through lots of threads on how to handle this, and I think I'm doing it correctly, but for some reason the submit button gets enabled as soon as the user fills out the text input, even though the dropdown inputs are still empty.
For the text input, I'm checking whether the string length is 0. For the dropdowns, I'm checking whether the value is "select". Why does the submit button get enabled once the text input string is > 0, even when the dropdown values are still "select"? Here's a working codepen and see code below as well.
// Input Variables
let createDigestModal = $("#create-digest-modal");
let createDigestFormContainer = $("#create-digest-modal-form-container");
let createDigestModalSubmitBtn = $("#create-digest-modal-btn");
// ========================================================================
// Toggle the submit button to disabled / enabled based on required inputs
// ========================================================================
const enableSubmitBtn = () => {
// Create digest form
$(createDigestFormContainer).on("keyup click", () => {
let createDigestInputs = createDigestFormContainer.find(".required");
let requiredCreateDigestInputs = true;
for (let i = 0; i < createDigestInputs.length; i++) {
console.log(createDigestInputs[i].value);
if (createDigestInputs[i].value == "") {
requiredCreateDigestInputs = false;
}
}
createDigestModalSubmitBtn.prop("disabled", !requiredCreateDigestInputs);
});
};
// Invoke Function to toggle submit button
enableSubmitBtn();
.row {
margin-bottom: 1rem;
}
/* Required Fields */
.required-field::after {
content: "*";
color: red;
margin-left: 2px;
}
.required-field-margin-left::after {
content: "*";
color: red;
margin-left: -2px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<!-- Create Digest Modal -->
<div class="modal fade" id="create-digest-modal" tabindex="-1" aria-labelledby="create-digest-modal-label">
<form id="create-digest-modal-form-container">
<!-- Project Input -->
<div class="row">
<div class="col-40">
<label class="required-field" for="create-digest-modal-project-input">Project</label>
</div>
<div>
<select class="form-select required" id="create-digest-modal-project-input" type="select">
<option value="select">Select</option>
<option value="1">Project 1</option>
<option value="2">Project 2</option>
</select>
</div>
</div>
<!-- /Project Input -->
<!-- name input -->
<div class="row">
<div id="create-digest-name-input">
<label id="create-digest-modal-name-input-label" for="create-digest-modal-name-input" class="required-field">Digest Name</label>
</div>
<div>
<input name="create-digest-modal-name-input" type="text" id="create-digest-modal-name-input" class="required" />
</div>
</div>
<!-- /name input -->
<!-- Type input -->
<div class="row">
<div class="col-40">
<label class="required-field" for="create-digest-modal-type-input">Type</label>
</div>
<div class="col-75 flex">
<select class="form-select required" aria-label="create-digest-modal-type-input" id="create-digest-modal-type-input" type="select">
<option value="select">Select</option>
<option value="D">Daily</option>
<option value="W">Weekly</option>
</select>
</div>
</div>
<!-- /Type input -->
<!-- include summary input -->
<div id="create-digest-modal-summary-input-container" class="row">
<div class="col-40">
<label class="form-check-label" for="create-digest-modal-summary-input">
Include Summary
</label>
</div>
<div class="col-75 flex">
<input checked class="form-check-input" type="checkbox" id="create-digest-modal-summary-input" />
</div>
</div>
<!-- /include summary input -->
</form>
<!-- Close/Update Buttons -->
<div class="modal-footer">
<button type="button" class="btn btn-secondary modal-close-btn" data-bs-dismiss="modal" id="create-modal-close-btn">
Close
</button>
<button type="button" id="create-digest-modal-btn" class="btn btn-success" disabled>
Add Digest
</button>
</div>
</div>
<!-- Create Digest Modal -->
When the value is select
, the condition createDigestInputs[i].value.length == ""
fails. Since you're combining the
conditions with &&
, they both have to be true to disable the button, but that can't happen.
The usual solution is to use an empty value for the unselected option, so it's consistent with text inputs.
Rather than using the click
event, use change
to detect changes in a dropdown.
Checking for an empty input value should be done with .value == ""
, not .value.length == ""
. The only reason the latter works is because comparing a number to a string automatically converts the string to a number, and the empty string converts to 0
.
You can break out of the for
loop once you find an unset input.
You don't need to put createDigestFormContainer
and createDigestModalSubmitBtn
inside $()
. They're already jQuery objects.
// Input Variables
let createDigestModal = $("#create-digest-modal");
let createDigestFormContainer = $("#create-digest-modal-form-container");
let createDigestModalSubmitBtn = $("#create-digest-modal-btn");
// ========================================================================
// Toggle the submit button to disabled / enabled based on required inputs
// ========================================================================
const enableSubmitBtn = () => {
// Create digest form
createDigestFormContainer.on("keyup change", () => {
let createDigestInputs = createDigestFormContainer.find(".required");
let requiredCreateDigestInputs = true;
for (let i = 0; i < createDigestInputs.length; i++) {
console.log(createDigestInputs[i].value);
if (
createDigestInputs[i].value == ""
) {
requiredCreateDigestInputs = false;
break;
}
}
createDigestModalSubmitBtn.attr("disabled", !requiredCreateDigestInputs);
});
};
// Invoke Function to toggle submit button
enableSubmitBtn();
.row {
margin-bottom: 1rem;
}
/* Required Fields */
.required-field::after {
content: "*";
color: red;
margin-left: 2px;
}
.required-field-margin-left::after {
content: "*";
color: red;
margin-left: -2px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<!-- Create Digest Modal -->
<div class="modal fade" id="create-digest-modal" tabindex="-1" aria-labelledby="create-digest-modal-label">
<form id="create-digest-modal-form-container">
<!-- Project Input -->
<div class="row">
<div class="col-40">
<label class="required-field" for="create-digest-modal-project-input">Project</label>
</div>
<div>
<select class="form-select required" id="create-digest-modal-project-input" type="select">
<option value="">Select</option>
<option value="1">Project 1</option>
<option value="2">Project 2</option>
</select>
</div>
</div>
<!-- /Project Input -->
<!-- name input -->
<div class="row">
<div id="create-digest-name-input">
<label id="create-digest-modal-name-input-label" for="create-digest-modal-name-input" class="required-field">Digest Name</label>
</div>
<div>
<input name="create-digest-modal-name-input" type="text" id="create-digest-modal-name-input" class="required" />
</div>
</div>
<!-- /name input -->
<!-- Type input -->
<div class="row">
<div class="col-40">
<label class="required-field" for="create-digest-modal-type-input">Type</label>
</div>
<div class="col-75 flex">
<select class="form-select required" aria-label="create-digest-modal-type-input" id="create-digest-modal-type-input" type="select">
<option value="">Select</option>
<option value="D">Daily</option>
<option value="W">Weekly</option>
</select>
</div>
</div>
<!-- /Type input -->
<!-- include summary input -->
<div id="create-digest-modal-summary-input-container" class="row">
<div class="col-40">
<label class="form-check-label" for="create-digest-modal-summary-input">
Include Summary
</label>
</div>
<div class="col-75 flex">
<input checked class="form-check-input" type="checkbox" id="create-digest-modal-summary-input" />
</div>
</div>
<!-- /include summary input -->
</form>
<!-- Close/Update Buttons -->
<div class="modal-footer">
<button type="button" class="btn btn-secondary modal-close-btn" data-bs-dismiss="modal" id="create-modal-close-btn">
Close
</button>
<button type="button" id="create-digest-modal-btn" class="btn btn-success" disabled>
Add Digest
</button>
</div>
</div>
<!-- Create Digest Modal -->