Edit: Thank you! This problem is resolved. This was my first StackExchange question and you’ve all been very kind in responding so quickly, insightfully and thoroughly.
I’m building a page that has an “add another task” button. Each time it’s pressed, one hidden element is supposed to change CSS properties from “hidden” to “visible”, adding one more row of inputs to the page. I’ve managed to get them all to reveal at once, but I’m trying to get the rows to show one at a time.
Here’s what I’ve written so far. Else if statements made the most sense to me, based on the SE posts I read about them, but with the first press of the button, both hidden rows (“task2” and “task3”) reveal simultaneously. Am I using the wrong kind of conditional statement? Or do the statements need to be inside their own functions within the showNextTask function? I’d appreciate any help!
function showNextTask() {
let task2 = document.querySelector("#task-2-row");
let task3 = document.querySelector("#task-3-row");
if ((task2.style.visibility === "hidden")) {
task2.style.visibility = "visible";
task2.style.maxHeight = "80px";
} else if (
(task2.style.visibility === "visible") &&
(task3.style.visibility === "hidden")
) {
task3.style.visibility = "visible";
task3.style.maxHeight = "80px";
}
}
let nextInputTask = document.querySelector("#add-another-task-button");
nextInputTask.addEventListener("click", showNextTask);
As requested below, here is the HTML of Task 2 (Task 3 is identical):
<div id="task-2-row">
<form id="add-task-2">
<span class="add-task-2-description">
<input
type="text"
placeholder="Task 2"
autocomplete="off"
id="task-input-bar-2"
class="task-input-field"
/>
</span>
<span class="add-task-2-time">
<input
type="time"
id="timer-field-2"
class="task2 timer-field"
name="appt"
/>
<input
type="submit"
id="submit-task-2-button"
class="button add-timer-button"
value="Add Task"
/>
</span>
</form>
</div>
And the CSS:
#task-2-row {
visibility: hidden;
max-height: 0;
}
J Park is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
9
You are using Assignment operator = instead of equality operator == or ===
Instead I suggest you can try to make a more generic function to add N number of task with the button
Try
<style>
.task-row {
visibility: hidden;
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease-out, visibility 0.3s ease-out;
margin-bottom: 10px;
}
</style>
<body>
<button id="add-another-task-button">Add Task</button>
<div id="task-container">
<!-- Tasks will be created dynamically -->
</div>
<script>
let taskCount = 0;
function addNewTask() {
taskCount++;
const taskContainer = document.querySelector("#task-container");
const newTask = document.createElement("div");
newTask.id = `task-${taskCount}-row`;
newTask.className = "task-row";
newTask.innerHTML = `Task ${taskCount}: <input type="text">`;
taskContainer.appendChild(newTask);
// Make new task visible
setTimeout(() => {
newTask.style.visibility = "visible";
newTask.style.maxHeight = "80px";
}, 0);
}
document.addEventListener("DOMContentLoaded", (event) => {
let nextInputTask = document.querySelector("#add-another-task-button");
nextInputTask.addEventListener("click", addNewTask);
});
</script>
This approach will help to create any number of task with ‘Add Task’ CTA.
1
Just to pinpoint why your if..else
doesn’t work:
You’re checking task2.style.visibility
, but that style was never set. Instead you have a CSS class that applies to that element, but that is not the same thing. To know how all applicable CSS styles affect the visibility of task2
you could use getComputedStyle
. Then it will work.
Another remark: in the else
case you already know that task2
is visible, so there is no need to explicitly check for that again.
So change this:
if ((task2.style.visibility === "hidden")) {
task2.style.visibility = "visible";
task2.style.maxHeight = "80px";
} else if (
(task2.style.visibility === "visible") &&
(task3.style.visibility === "hidden")
) {
task3.style.visibility = "visible";
task3.style.maxHeight = "80px";
}
to this:
if ((getComputedStyle(task2).visibility === "hidden")) {
task2.style.visibility = "visible";
task2.style.maxHeight = "80px";
} else if (getComputedStyle(task3).visibility === "hidden") {
task3.style.visibility = "visible";
task3.style.maxHeight = "80px";
}
But as noted, this is not really a scalable approach. Also, playing with maxHeight
like that really shows you want to use the display
property and not visibility
. Note that display
takes different values, so make sure to look it up.
1