skip to Main Content

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;
            }

2

Answers


  1. 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.

    Login or Signup to reply.
  2. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search