Home > database >  Trying to move completed tasks from one list to another
Trying to move completed tasks from one list to another

Time:02-11

Here we have a tab with incompled tasks and the list is supposed to be attached to the first tab(all-taks). After the task is finished it is supposed to get deleted from first list and move to second one with completed tasks. And after you switch to second tab, all the completed ones should be there. I can't figure out the way to do it. I hope I could get some help or some detailed explanation, 'cause I have been stuck on this for some time.

Here is an image for more clarification: [1]: https://i.stack.imgur.com/Dy0KL.png

HTML code:

<body>
    <div >
        <header>
            <h1>To-Do List</h1>
            <h4>Describe your list...</h4>
        </header>

        <form action="" >
            <div >
                <!-- action is where files will be sent after submitting -->
                <input  type="text" placeholder="Add a task...">
            </div>
            <div >
                <button  type="submit">Add</button>
            </div>
    </form>

    <div >
        <ul>
            <li >
                <span></span>All tasks (<span >0</span>)</span>
            </li>
            <li >
                <span>Completed (<span >0</span>)</span>
            </li>
        </ul>
    </div>

    <div >
        <div  data-tab="1">
            <ol ></ol>
        </div>
        <div  data-tab="2">
            <ol ></ol>
        </div>
    </div>
</body>

JS code:

//Selectors
const todoForm = document.querySelector('.todo-form');
const todoInput = document.querySelector('.todo-input');
const todoButton = document.querySelector('.todo-button');

const tabs = document.querySelectorAll('.todo-tabs ul li');
const tabWrap = document.querySelector('.todo-tabs ul');

const undone = document.querySelector('.undone-tasks');
const done = document.querySelectorAll('.done-tasks');

//Event Listeners
tabWrap.addEventListener('click', tabs)
todoButton.addEventListener('click', addToDo);

//Functions
tabs.forEach(function (tab, tab_index) {
    tab.addEventListener("click", function () {
        tabs.forEach(function (tab) {
            tab.classList.remove("active");
        })
        tabWrap.forEach(function (todoList, todoList_index) {
            if (todoList_index == tab_index) {
                todoList.style.display = "block";
            }
            else[
                todoList.style.display = "none"
            ]
        })
    })
})

function addToDo(event) {
    //Prevent form from submitting
    event.preventDefault();

    if (todoInput.value != "") {
        const todoDiv = document.createElement('div');
        todoDiv.classList.add('todo-div');

        const inputCheckbox = document.createElement('input');
        inputCheckbox.classList.add("checkbox-incompleted");
        inputCheckbox.setAttribute('type', 'checkbox');
        todoDiv.appendChild(inputCheckbox);

        //Create li
        const newToDo = document.createElement('li');
        newToDo.classList.add('todo-item');
        newToDo.insertAdjacentText("beforeend", todoInput.value);
        todoDiv.appendChild(newToDo);
        console.log(newToDo)

        //Append to list
        undone.appendChild(todoDiv);

        //Clear todo input value
        todoInput.value = "";

        //Focusing after 1st input
        todoInput.focus();
    }
}

The commented area is what i tried to do for tabs and lists to switch, but it gives the following error:

Uncaught TypeError: tabWrap.forEach is not a function
    at HTMLLIElement.<anonymous> (script.js:32:17)
(anonymous) @ script.js:32

The error starts at the beggining of the tabWrap.forEach function. But I guess there could be other way to solve this

CodePudding user response:

tabWrap is not useful for what you want: it is a single element. Instead, you'll want to iterate over the tab contents, which are identified by class tabs-content. It is those that you need to iterate and show or hide.

Then, to decide which contents to use, you may need to use that data-tab attribute you have in your HTML (not sure, since it is nowhere referenced).

Anyway, adapt as needed:

const tabContents = document.querySelectorAll('.tabs-content');
tabs.forEach(function (activeTab, activeIndex) {
    activeTab.addEventListener("click", function (e) {
        tabs.forEach(function (tab) {
            tab.classList.toggle("active", tab == activeTab);
        });
        tabContents.forEach(function (tabContent) {
            tabContent.style.display = tabContent.dataset.tab == activeIndex   1 ? "" : "none";
        });
    })
})

CodePudding user response:

As @Anurag Srivastava pointed out on comment, in your code this is how you get tab elements:

const tabs = document.querySelectorAll('.todo-tabs ul li');
const tabWrap = document.querySelector('.todo-tabs ul');

The method querySelector returns a single element, and querySelectorAll returns an iterable collection.

And this is why you're getting the error:

Uncaught TypeError: tabWrap.forEach is not a function

If you don't have to support internet explorer you could take a look at Element.insertAdjacentElement() to move elements from one tab to another.

  • Related