簡體   English   中英

嘗試為 Javascript 中的待辦事項列表應用程序進行過濾但苦苦掙扎

[英]Trying to do a filter for a to-do list app in Javascript but struggling

我有一個待辦事項列表,它工作得很好,但我正在嘗試過濾它,但我有點掙扎。 基本上,每個任務都是一個 object 每個 object 都有文本、id 和檢查屬性。 例如,我想僅顯示按 Active 時未檢查的任務。

我希望你能幫忙。 這是一張圖片以進行更多說明:

用戶界面圖片


/*  Selectors  */
const switcher = document.querySelector(' input[Type="checkbox"]');
const body = document.body;
const formT = document.querySelector(`[data-new-todo-form]`)
const inputT = document.querySelector(`[data-new-todo-input]`)
const todoList = document.getElementById('todo-list');
const filterList = document.querySelector('.controls-list')

/* array that holds tasks */
let tasks = [];


/*  EVENT LISTENERS */
switcher.addEventListener('change', (e) => {
    if(e.target.checked) {
        body.classList.replace('light', 'dark')
    } else {
        body.classList.replace('dark', 'light')
    }

})


formT.addEventListener('submit', e => {
    e.preventDefault()
    
    let text = inputT.value.trim();
    if(text !== '') {
       addTask(text);
       inputT.value = '';
       inputT.focus();

    } 
 
})


todoList.addEventListener('click', e => {
    if (e.target.classList.contains('js-tick')) {
        const itemKey = e.target.parentElement.dataset.key;
        toggleDone(itemKey);
        
    }

    if (e.target.classList.contains('delete')) {
        const itemKey = e.target.parentElement.dataset.key;
        deleteTodo(itemKey);
        counter();
      }

      
    
});


document.addEventListener('DOMContentLoaded', () => {
    const ref = localStorage.getItem('tasksRef');
    if (ref) {
      tasks = JSON.parse(ref);
      tasks.forEach(task => {
        renderTodo(task);
        counter();
      });
    }
  });



  /* FUNCTIONS */

/* create a todo object */
const addTask = (text) => {
    const todoTask = {
        text,
        checked: false,
        id: Date.now(),
    }
    tasks.push(todoTask);
    renderTodo(todoTask);

};


const renderTodo = (todoTask)=> {

    localStorage.setItem('tasksRef', JSON.stringify(tasks));

    
    const item = document.querySelector(`[data-key='${todoTask.id}']`);

    if (todoTask.deleted) {
        // remove the item from the DOM
        item.remove();
        return
      }

    const isChecked = todoTask.checked ? 'done': '';

    const node = document.createElement('li')
    node.setAttribute('class', `todo-item ${isChecked}`);
    node.setAttribute('data-key', todoTask.id);
    node.innerHTML = `
    
    <input class="js-tick" id="${todoTask.id}" type="checkbox" ${isChecked ? "checked" : ""}/>
    <span>${todoTask.text}</span>
    <img class="delete" width="15px" height='15px' src="/images/icon-cross.svg" alt="cross">`
    ;
    todoList.append(node);

    if (item) {
        node.replaceWith(item)
    } else {
        todoList.append(node)
    }
    counter();

}


const toggleDone = (key) => {
    
    const index = tasks.findIndex(task=> task.id === Number(key));

    tasks[index].checked = !tasks[index].checked;
    renderTodo(tasks[index]);
}

const deleteTodo = (key) => {
    const index = tasks.findIndex(item => item.id === Number(key));


    const todoTask = {
        deleted: true,
        ...tasks[index]
      };
      tasks = tasks.filter(item => item.id !== Number(key));
  renderTodo(todoTask);
}


const counter = () => {
    const itemsCounter =  tasks.filter(task=> !task.checked)
    const count = document.getElementById('todosLeft');

    const counterString = itemsCounter.length === 1 ? 'item' : 'items'

 count.innerText = `${itemsCounter.length} ${counterString} left`

}

這是 HTML:

<body class="light">
  <section class="header">
    
  </section>
  <div class="container">

  <div class="title-theme">
    <h1>Todo</h1>
    <input type="checkbox" id="switch-l" class="themeSwitch">
    <label for="switch-l" id="switch" class="themeSwitch-label"></label>
  </div>
  <div class="todosInput">
    <div id="mark"></div>
    <form class="form" action="" data-new-todo-form>
      <input id="todos" data-new-todo-input type="text" placeholder="Create a new todo..." >
    </form>
  </div>
    <div class="myTodos">
      <ul id="todo-list">
    <--! THE TASKS GOES HERE !-->
      </ul>
    </div>
 <div class="controls">
    <p id="todosLeft">items left</p><!-- Add dynamic number --> 
    <div class="controls-list-div">
      <ul class="controls-list" data-lists>
        <li>All</li> 
        <li>Active</li> 
        <li>Completed</li> 
        </ul>
    </div>
   Clear Completed
   
  </div> 
</div>
  <div class="instruc">
    <p>Drag and drop to reorder list</p>
  </div>   

首先,您的 TodoList 需要是不可變的,因為在您單擊所有 TodoList 后應該顯示所有 Todos。

const renderActiveTodos = () => {
    const ref = localStorage.getItem('tasksRef');
    if (ref) {
      tasks = JSON.parse(ref);
      tasks.filter(item => !item.check).forEach(task => {
        renderTodo(task, true);
        counter();
      });
    }
}

const renderAllTodos = () => {
    const ref = localStorage.getItem('tasksRef');
    if (ref) {
      tasks = JSON.parse(ref);
      tasks.forEach(task => {
        renderTodo(task, true);
        counter();
      });
    }
}

const renderCompletedTodos = () => {
    const ref = localStorage.getItem('tasksRef');
    if (ref) {
      tasks = JSON.parse(ref);
      tasks.filter(item => item.check).forEach(task => {
        renderTodo(task, true);
        counter();
      });
    }
}

但是您應該在您的 renderTodo function 中添加 preventMutableStorage 以防止本地存儲中的數據。 然后,如果您單擊全部,則可以返回完整的待辦事項列表

const renderTodo = (todoTask, preventMutableStorage)=> {
    if(!preventMutableStorage){
        localStorage.setItem('tasksRef', JSON.stringify(tasks));
    }
    .....
}

為什么我要更改 renderTodo:

首先假設我們有 todoList = [{id:1, check:false}, {id:2, check:true}, {id:3, check:true}]

當我單擊活動時,將調用 renderActiveTodos:

It get data from localstorage
Filter data with check=false => [{id:1, check:false}]
Then we loop through it then call renderTodo
In renderTodo it first set the localstorage again then now the Todo in Localstorage is [{id:1, check:false}]

然后下次我們點擊全部:

It can't show [{id:2, check:true}, {id:3, check:true}] cause we already update the todoList in localstorage

這就是我添加 preventMutableStorage 參數以防止本地存儲 TodoList 更新的原因

我剛剛在您的代碼中發現了一些東西。 但所有將修復這是工作代碼。

https://codepen.io/nguyennghi3489/pen/gOwvNga?editors=1111

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM