在选中至少三个输入复选框(每组六个中的一个)之前,如何隐藏按钮?
How can I hide a button until at least three input checkboxes (one from each separate set of six) are checked?
我有三个列表(HTML Fieldset 元素),每个列表中有六种食物(HTML 输入元素 - 从未选中开始)。我想在这三个列表下方隐藏一个按钮元素,直到检查了三个列表中的每一个列表中的至少一种食物。当至少检查了每个列表中的一种食物时,我希望取消隐藏按钮。
这将在单击第一个字段集中的输入之一时取消隐藏按钮...但我需要扩展功能,以便按钮仅在每个 3x 字段集中的至少一个(蛋白质、碳水化合物和脂肪)被选中。
// Add variable for the DOM element button with id "generate-meals"
let generateMealButton = document.getElementById("generate-meals");
generateMealButton.classList.add("hide");
// Add an eventlistener to generate meal button to listen for a "click" event and run the
// function "runMealGenerator when the event occurs"
generateMealButton.addEventListener("click", runMealGenerator);
// find all input fields
const proteinInputs = document.querySelectorAll("input[class='protein-input']");
console.log(proteinInputs[0].checked)
const carbInputs = document.querySelectorAll("input[class='carb-input']");
console.log(carbInputs)
const fatInputs = document.querySelectorAll("input[class='fat-input']");
console.log(fatInputs)
// add click event-listener for all input buttons
proteinInputs.forEach((input) => {
input.addEventListener("click", checkProteinInput);
});
// check if any input buttons are 'checked'
function checkProteinInput() {
// if the macroChoice button is 'not' hidden, then unhide it
console.log(proteinInputs[0].checked)
if (generateMealButton.classList.contains("hide")) {
generateMealButton.classList.remove("hide");
}
}
function runMealGenerator() {
console.log("Dummy Function Added")
}
<!-- This section contains the 3x menus of sample foods the user can select for inclusion in their meal plan ideas -->
<section id="foodListContainer">
<!-- Small section for direction to the user - instructions on how to proceed -->
<section class="food-groups" id="generator_instructions">
<h3 id="food-heading">Instructions</h3>
<p>Please select at least one food from each group for inclusion in meal plans:</p>
</section>
<!-- Fieldset to contain checkboxes for each Protein food option for selection by user -->
<fieldset class="food-groups" id="proteinFieldset">
<legend>Protein:</legend>
<!-- Each Protein input is housed in a div to enable dematcation & styling -->
<div>
<label for="chicken">Chicken</label>
<input class="protein-input" type="checkbox" id="chicken" name="chicken">
</div>
<div>
<label for="turkey">Turkey</label>
<input class="protein-input" type="checkbox" id="turkey" name="turkey">
</div>
<div>
<label for="fish">Fish</label>
<input class="protein-input" type="checkbox" id="fish" name="fish">
</div>
<div>
<label for="beef">beef</label>
<input class="protein-input" type="checkbox" id="beef" name="beef">
</div>
<div>
<label for="eggs">eggs</label>
<input class="protein-input" type="checkbox" id="eggs" name="eggs">
</div>
<div>
<label for="pork">pork</label>
<input class="protein-input" type="checkbox" id="pork" name="pork">
</div>
</fieldset>
<!-- Fieldset to contain checkboxes for each Carbohydrate food option -->
<fieldset class="food-groups">
<legend>Carbohydrate:</legend>
<!-- Each Carbohydrate input is housed in a div to enable dematcation & styling -->
<div>
<label for="bread">Bread</label>
<input class="carb-input" type="checkbox" id="bread" name="bread">
</div>
<div>
<label for="pasta">Pasta</label>
<input class="carb-input" type="checkbox" id="pasta" name="pasta">
</div>
<div>
<label for="rice">Rice</label>
<input class="carb-input" type="checkbox" id="rice" name="rice">
</div>
<div>
<label for="oats">Oats</label>
<input class="carb-input" type="checkbox" id="oats" name="oats">
</div>
<div>
<label for="cereal">Cereal</label>
<input class="carb-input" type="checkbox" id="cereal" name="cereal">
</div>
<div>
<label for="quinoa">Quinoa</label>
<input class="carb-input" type="checkbox" id="quinoa" name="quinoa">
</div>
</fieldset>
<!-- Fieldset to contain checkboxes for each Fat food option -->
<fieldset class="food-groups">
<legend>Fat:</legend>
<!-- Each Fat input is housed in a div to enable dematcation & styling -->
<div>
<label for="butter">Butter</label>
<input class="fat-input" type="checkbox" id="butter" name="butter">
</div>
<div>
<label for="cheese">Cheese</label>
<input class="fat-input" type="checkbox" id="cheese" name="cheese">
</div>
<div>
<label for="cream">Cream</label>
<input class="fat-input" type="checkbox" id="cream" name="cream">
</div>
<div>
<label for="nuts">Nuts</label>
<input class="fat-input" type="checkbox" id="nuts" name="nuts">
</div>
<div>
<label for="bacon">Bacon</label>
<input class="fat-input" type="checkbox" id="bacon" name="bacon">
</div>
<div>
<label for="olive-oil">Olive Oil</label>
<input class="fat-input" type="checkbox" id="olive-oil" name="olive-oil">
</div>
</fieldset>
<!-- End of foodListContainer section -->
<!-- Button to allow the user proceed to generate meal plan ideas when they have selected
All foods they wish to include/exclude -->
<section id="generate-container">
<button id="generate-meals">Generate A Meal Plan</button>
</section>
</section>
您将需要遍历所有复选框,以确定每个部分是否至少有一个被选中。你也需要这样做,当一个复选框被取消选中时,因为你可能想再次隐藏按钮,当条件不再满足时...
直接的方法如下
function checkInputs() {
let p = false, f = false, c = false; //protein, carbon, fat
for (let i = 0; i < proteinInputs.length; i++) {
if (proteinInputs[i].checked) { p = true; break;} //we found at least one
}
for (let i = 0; i < fatInputs.length; i++) {
if (fatInputs[i].checked) { f = true; break;} //we found at least one
}
for (let i = 0; i < carbonInputs.length; i++) {
if (carbonInputs[i].checked) { c = true; break;} //we found at least one
}
if (p && f && c) { //found at least one in each section
//show the button
generateMealButton.classList.remove("hide");
} else { //at least one is missing
//hide the button
generateMealButton.classList.add("hide");
}
}
并将此 checkInputs
添加到所有复选框(即不仅用于蛋白质,还用于脂肪和碳)
顺便说一句。如果您使用 classList.add
或 classList.remove
,则无需明确检查 classList.contains
。这些功能将解决这个问题。也就是说,如果 class 已经包含,它不会添加两次,并且如果您尝试删除不包含在 classList
中的 class,也不会出现错误)
当然你可以优化这段代码。例如,只需评估刚刚更改的复选框并为每个部分保留一个计数器。当所有计数器都 > 0
取消隐藏按钮,并在一个变为零时隐藏按钮 ...
let cb = document.querySelectorAll("input[type='checkbox']")
for (let i = 0; i < cb.length; i++) cb[i].addEventListener("change", check);
let c = 0, f= 0, p= 0
function check(event) {
let addval = event.currentTarget.checked ? 1 : -1
switch(event.currentTarget.getAttribute("data-tag")) {
case "f": f += addval; break;
case "c": c += addval; break;
case "p": p += addval; break;
}
console.log(f,c,p);
if (f && c && p)
document.getElementById("thebutton").classList.remove("hide")
else
document.getElementById("thebutton").classList.add("hide")
}
.hide {
display: none;
}
<input type="checkbox" data-tag="f"/>fat
<input type="checkbox" data-tag="c"/>carbon
<input type="checkbox" data-tag="p"/>protein
<input type="checkbox" data-tag="f"/>fat2
<input type="checkbox" data-tag="c"/>carbon2
<input type="checkbox" data-tag="p"/>protein2
<input id="thebutton" type="button" value="create meal" class="hide">
我有三个列表(HTML Fieldset 元素),每个列表中有六种食物(HTML 输入元素 - 从未选中开始)。我想在这三个列表下方隐藏一个按钮元素,直到检查了三个列表中的每一个列表中的至少一种食物。当至少检查了每个列表中的一种食物时,我希望取消隐藏按钮。
这将在单击第一个字段集中的输入之一时取消隐藏按钮...但我需要扩展功能,以便按钮仅在每个 3x 字段集中的至少一个(蛋白质、碳水化合物和脂肪)被选中。
// Add variable for the DOM element button with id "generate-meals"
let generateMealButton = document.getElementById("generate-meals");
generateMealButton.classList.add("hide");
// Add an eventlistener to generate meal button to listen for a "click" event and run the
// function "runMealGenerator when the event occurs"
generateMealButton.addEventListener("click", runMealGenerator);
// find all input fields
const proteinInputs = document.querySelectorAll("input[class='protein-input']");
console.log(proteinInputs[0].checked)
const carbInputs = document.querySelectorAll("input[class='carb-input']");
console.log(carbInputs)
const fatInputs = document.querySelectorAll("input[class='fat-input']");
console.log(fatInputs)
// add click event-listener for all input buttons
proteinInputs.forEach((input) => {
input.addEventListener("click", checkProteinInput);
});
// check if any input buttons are 'checked'
function checkProteinInput() {
// if the macroChoice button is 'not' hidden, then unhide it
console.log(proteinInputs[0].checked)
if (generateMealButton.classList.contains("hide")) {
generateMealButton.classList.remove("hide");
}
}
function runMealGenerator() {
console.log("Dummy Function Added")
}
<!-- This section contains the 3x menus of sample foods the user can select for inclusion in their meal plan ideas -->
<section id="foodListContainer">
<!-- Small section for direction to the user - instructions on how to proceed -->
<section class="food-groups" id="generator_instructions">
<h3 id="food-heading">Instructions</h3>
<p>Please select at least one food from each group for inclusion in meal plans:</p>
</section>
<!-- Fieldset to contain checkboxes for each Protein food option for selection by user -->
<fieldset class="food-groups" id="proteinFieldset">
<legend>Protein:</legend>
<!-- Each Protein input is housed in a div to enable dematcation & styling -->
<div>
<label for="chicken">Chicken</label>
<input class="protein-input" type="checkbox" id="chicken" name="chicken">
</div>
<div>
<label for="turkey">Turkey</label>
<input class="protein-input" type="checkbox" id="turkey" name="turkey">
</div>
<div>
<label for="fish">Fish</label>
<input class="protein-input" type="checkbox" id="fish" name="fish">
</div>
<div>
<label for="beef">beef</label>
<input class="protein-input" type="checkbox" id="beef" name="beef">
</div>
<div>
<label for="eggs">eggs</label>
<input class="protein-input" type="checkbox" id="eggs" name="eggs">
</div>
<div>
<label for="pork">pork</label>
<input class="protein-input" type="checkbox" id="pork" name="pork">
</div>
</fieldset>
<!-- Fieldset to contain checkboxes for each Carbohydrate food option -->
<fieldset class="food-groups">
<legend>Carbohydrate:</legend>
<!-- Each Carbohydrate input is housed in a div to enable dematcation & styling -->
<div>
<label for="bread">Bread</label>
<input class="carb-input" type="checkbox" id="bread" name="bread">
</div>
<div>
<label for="pasta">Pasta</label>
<input class="carb-input" type="checkbox" id="pasta" name="pasta">
</div>
<div>
<label for="rice">Rice</label>
<input class="carb-input" type="checkbox" id="rice" name="rice">
</div>
<div>
<label for="oats">Oats</label>
<input class="carb-input" type="checkbox" id="oats" name="oats">
</div>
<div>
<label for="cereal">Cereal</label>
<input class="carb-input" type="checkbox" id="cereal" name="cereal">
</div>
<div>
<label for="quinoa">Quinoa</label>
<input class="carb-input" type="checkbox" id="quinoa" name="quinoa">
</div>
</fieldset>
<!-- Fieldset to contain checkboxes for each Fat food option -->
<fieldset class="food-groups">
<legend>Fat:</legend>
<!-- Each Fat input is housed in a div to enable dematcation & styling -->
<div>
<label for="butter">Butter</label>
<input class="fat-input" type="checkbox" id="butter" name="butter">
</div>
<div>
<label for="cheese">Cheese</label>
<input class="fat-input" type="checkbox" id="cheese" name="cheese">
</div>
<div>
<label for="cream">Cream</label>
<input class="fat-input" type="checkbox" id="cream" name="cream">
</div>
<div>
<label for="nuts">Nuts</label>
<input class="fat-input" type="checkbox" id="nuts" name="nuts">
</div>
<div>
<label for="bacon">Bacon</label>
<input class="fat-input" type="checkbox" id="bacon" name="bacon">
</div>
<div>
<label for="olive-oil">Olive Oil</label>
<input class="fat-input" type="checkbox" id="olive-oil" name="olive-oil">
</div>
</fieldset>
<!-- End of foodListContainer section -->
<!-- Button to allow the user proceed to generate meal plan ideas when they have selected
All foods they wish to include/exclude -->
<section id="generate-container">
<button id="generate-meals">Generate A Meal Plan</button>
</section>
</section>
您将需要遍历所有复选框,以确定每个部分是否至少有一个被选中。你也需要这样做,当一个复选框被取消选中时,因为你可能想再次隐藏按钮,当条件不再满足时...
直接的方法如下
function checkInputs() {
let p = false, f = false, c = false; //protein, carbon, fat
for (let i = 0; i < proteinInputs.length; i++) {
if (proteinInputs[i].checked) { p = true; break;} //we found at least one
}
for (let i = 0; i < fatInputs.length; i++) {
if (fatInputs[i].checked) { f = true; break;} //we found at least one
}
for (let i = 0; i < carbonInputs.length; i++) {
if (carbonInputs[i].checked) { c = true; break;} //we found at least one
}
if (p && f && c) { //found at least one in each section
//show the button
generateMealButton.classList.remove("hide");
} else { //at least one is missing
//hide the button
generateMealButton.classList.add("hide");
}
}
并将此 checkInputs
添加到所有复选框(即不仅用于蛋白质,还用于脂肪和碳)
顺便说一句。如果您使用 classList.add
或 classList.remove
,则无需明确检查 classList.contains
。这些功能将解决这个问题。也就是说,如果 class 已经包含,它不会添加两次,并且如果您尝试删除不包含在 classList
中的 class,也不会出现错误)
当然你可以优化这段代码。例如,只需评估刚刚更改的复选框并为每个部分保留一个计数器。当所有计数器都 > 0
取消隐藏按钮,并在一个变为零时隐藏按钮 ...
let cb = document.querySelectorAll("input[type='checkbox']")
for (let i = 0; i < cb.length; i++) cb[i].addEventListener("change", check);
let c = 0, f= 0, p= 0
function check(event) {
let addval = event.currentTarget.checked ? 1 : -1
switch(event.currentTarget.getAttribute("data-tag")) {
case "f": f += addval; break;
case "c": c += addval; break;
case "p": p += addval; break;
}
console.log(f,c,p);
if (f && c && p)
document.getElementById("thebutton").classList.remove("hide")
else
document.getElementById("thebutton").classList.add("hide")
}
.hide {
display: none;
}
<input type="checkbox" data-tag="f"/>fat
<input type="checkbox" data-tag="c"/>carbon
<input type="checkbox" data-tag="p"/>protein
<input type="checkbox" data-tag="f"/>fat2
<input type="checkbox" data-tag="c"/>carbon2
<input type="checkbox" data-tag="p"/>protein2
<input id="thebutton" type="button" value="create meal" class="hide">