Фильтровать активные задачи, выполненные задачи и все задачи в списке дел с помощью javascript

#javascript #html #dom-events

Вопрос:

У меня возникли некоторые трудности с фильтрацией по списку задач в проекте списка дел. Я использую объект для хранения основных свойств каждой созданной задачи, таких как идентификатор, содержимое, выполненное и дата. Фильтр должен выполняться после выбора пользователем опции в выпадающем меню. Я использую прослушиватель событий, чтобы перехватить идентификатор выбранной опции, но я не знаю, что делать с этим идентификатором. Например, когда пользователь выбирает опцию «завершено», приложение должно отображать только завершенную задачу или задачи, которые имеют свойство «завершено: true». Я также хочу отфильтровать список необычным способом, например, сделать так, чтобы задачи исчезали при фильтрации.

URL: https://alonzocarlos95.github.io/WDD-330 /

 //html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!--ClockPicker libraries-->
    <link rel="stylesheet" href="https://weareoutman.github.io/clockpicker/dist/jquery-clockpicker.min.css"></link>
    <!-- <script src="http://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <!-- Moment JS library CDN -->
    <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.25.1/moment.min.js"></script> -->
    <!--Material Icons and Fonts-->
    <link href="https://fonts.googleapis.com/icon?family=Material Icons" rel="stylesheet">
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,200;1,100amp;display=swap" rel="stylesheet">
    <!--Small view-->
    <link rel="stylesheet" href="css/small.css" media="screen">

    <title>Document</title>
  
</head>
<body>
    <header>
        <nav>
            <ul>
                <li><span class="material-icons">done</span></li>
                <li class="drop-down" ><div class="dropdown"><button class="dropbtn" onclick="showModal()">All Lists<span class="material-icons" style="vertical-align: middle;">arrow_drop_down</span></button><div id="myDropdown" class="dropdown-content"><span id="select1">All Lists</span><span  id="select2">Active</span><span  id="select3">Completed</span></div></div></li>
                <li><span class="label_list">BYU-Idaho To do List</span></li>
                <li><span class="material-icons">search</span></li>
                <li><img src="images/b2-removebg-preview.png" alt="logo"></li>
            </ul>
        </nav>
    </header>
    <main>
        <div class="notes">
        <img id="no_tasks" src="images/palms-300x220.png" alt="No tasks">
    </div>
    <div class="main_list" id="main_list">
        <ul id="parentList">

        </ul>
    </div>
    <div class="new_task_container" id="container_schedule">
    <div class="new_task" id="new_todo">
        <label>What is to be done?</label>
        <div class="new_input">
        <input type="text" name="todo" id="todo" placeholder="Enter task here">
        <span class="material-icons">keyboard_voice</span>
        </div>
        <label>Due Date</label>
        <input type="date" id="date" name="date" placeholder="Date not set">
    </div>
    <div class="new_task_group2">
        <div class="new_time" id="new_time_container">
        <input type="text" name="time" id="time" placeholder="Time not set(all day)">
        <span class="material-icons">schedule</span>
        <!-- <input type="checkbox" style="display: none;"> -->
        </div>
    </div>
    </div>
    </main>
    <div class="add_task">
        <button id="add" class="bounce"> </button>
        </div>
        <script src="https://weareoutman.github.io/clockpicker/dist/jquery-clockpicker.min.js"></script>
        <script src="js/todo.js"></script>
</body>
</html>

 
 //Javacript

let toDoList = [];

let options = {weekday:'long', year:'numeric', month:'long', day:'numeric'};
let indicador = 0;
let list_container = document.getElementById('main_list');
document.getElementById('container_schedule').style.display = 'none';
const chosenDate = document.getElementById("date");
const time = document.getElementById('new_time_container');
let ulTasks = document.getElementById('parentList');
time.style.display = 'none';

document.getElementById('add').addEventListener('click', () => {
    document.getElementById('container_schedule').style.display = 'block';
    document.getElementById('add').innerHTML = '<span class="material-icons">done</span>';  
    let inputNewTask = document.getElementById("todo");
    let valInputNewTask = inputNewTask.value;
    let valInputNewTask2 = inputNewTask.value;
    let dateSet = document.getElementById('date').value;

    if(indicador === 0){
        indicador = 1;
        list_container.style.display = "none";
        
    }else {
           if(!isBlank(valInputNewTask)){ //Valida si el valor del input no es null o undefined o whitespace
            indicador = 0;
            inputNewTask.value = "";
            inputNewTask.focus();
            let newDateSet = valDate(dateSet);
            taskCreated();
            manageTask(valInputNewTask2,newDateSet);
            
            }
            else {
                alert("Enter task at first.");
            }
        
    }
} );
document.getElementById('date').addEventListener('change',() => {
    // alert("New date");
    time.style.display = 'flex';
});




 function taskCreated(){
    document.getElementById('container_schedule').style.display = 'none';
    // debugger;
    if(document.getElementsByClassName('notes').length >= 1){
        document.getElementsByClassName('notes')[0].remove();
    }
    document.getElementById('add').textContent = ' ';
 }




/*Clock picker functionality*/
$("input[name=time]").clockpicker({       
    placement: 'bottom',
    align: 'left',
    autoclose: true,
    default: 'now',
    donetext: "Select",
    init: function() { 
                              console.log("colorpicker initiated");
                          },
                          beforeShow: function() {
                              console.log("before show");
                          },
                          afterShow: function() {
                              console.log("after show");
                          },
                          beforeHide: function() {
                              console.log("before hide");
                          },
                          afterHide: function() {
                              console.log("after hide");
                          },
                          beforeHourSelect: function() {
                              console.log("before hour selected");
                          },
                          afterHourSelect: function() {
                              console.log("after hour selected");
                          },
                          beforeDone: function() {
                              console.log("before done");
                          },
                          afterDone: function() {
                              console.log("after done");
                          }
  });
  

  function isBlank(str) {
    //debugger;
    return (!str || /^s*$/.test(str));
}

function valDate(dateToDo){
    // debugger;
    if(dateToDo === null || dateToDo === ''){
        dateToDo = "No date";
        return dateToDo;
    }
    else {
        dateToDo = new Date(dateToDo);
        dateToDo.setDate(dateToDo.getDate() 1);
        // testDate = new Date(Date.UTC(dateToDo));
        dateToDo = dateToDo.toLocaleString('en-US',options);
        return dateToDo;
    }
}

function manageTask(getTask,dateSet){
    const todo = {
        id: Date.now(),
        content: getTask,
        completed: false,
        date: dateSet
    }
    toDoList.push(todo);
    addToLocalStorage(toDoList);
    // storeData(todo);
}


function addToLocalStorage(toDoList){
    // debugger;
    localStorage.setItem('toDoList',JSON.stringify(toDoList));

    renderTodos(toDoList);
}



function renderTodos(toDoList){
    // debugger;
    ulTasks.innerHTML = '';
    toDoList.forEach(function(valInputNewTask2,index){
        console.log(index);
        const checked = toDoList.completed ? 'checked': null;
        let currentTasks = document.createElement('li');
        currentTasks.id = valInputNewTask2.id;
        currentTasks.setAttribute('style','display:flex;background-color:#519872;width:100%;border-radius:7px;margin:0 0 10px 0;padding:6px 4px 6px 4px;min-height:3em;box-shadow: rgba(14, 30, 37, 0.12) 0px 2px 4px 0px, rgba(14, 30, 37, 0.32) 0px 2px 16px 0px;');
        
      

        currentTasks.innerHTML = '<input id=' index ' type = "checkbox"  class="checkInactive"><div style="display:flex;flex-direction:column;flex-grow:2;"><span style="margin-left:2em;">' valInputNewTask2.content '</span><span style="margin-left:2em;color:#17301C;">' valInputNewTask2.date '</span></div><div class="clear"><span class="material-icons">clear</span></div>';
        
        if(valInputNewTask2.completed === true){
            currentTasks.classList.add('checkActive');
            currentTasks.firstChild.checked = true;
        }  
        
        document.getElementById('parentList').appendChild(currentTasks);
        });
    list_container.style.display = "block";
}

function getFromLocalStorage(){
    const getReference = localStorage.getItem('toDoList');
    if(getReference){
        document.querySelector('.notes').style.display = 'none';
        toDoList = JSON.parse(getReference);
        renderTodos(toDoList);
    }
}


function showModal(){
    document.getElementById('myDropdown').classList.toggle('show');
}


getFromLocalStorage();


function toggle(id){
    toDoList.forEach(function(item){
        if(item.id == id){
            item.completed = !item.completed;
        }
    });
    addToLocalStorage(toDoList);
}

function deleteToDo(id){
    debugger
    // alert(id);
    toDoList = toDoList.filter(function(getTask){
        return getTask.id != id;
    });
    addToLocalStorage(toDoList);
}
debugger;
ulTasks.addEventListener('click',function(event){
    debugger;
    if(event.target.type === 'checkbox'){
        toggle(event.target.parentElement.getAttribute('id'));
    }
    if(event.target.parentElement.classList.contains('clear')){
        debugger;
        deleteToDo(event.target.parentElement.parentElement.getAttribute('id'));
    }
});





//Close the dropdown if the user clicks outside it
window.onclick = function(e) {
    if (!e.target.matches('.dropbtn')) {
    var myDropdown = document.getElementById("myDropdown");
      if (myDropdown.classList.contains('show')) {
        myDropdown.classList.remove('show');
      }
    }
  } 




//Drop down Events
document.getElementById("myDropdown").addEventListener('click',function(event){
    debugger;
    if(event.target.localName === 'span'){
        alert(event.target.id);
    }
});


 

Ответ №1:

Я не знаю об анимации, но, по крайней мере, для фильтрации:

  1. В идеале вы должны использовать элемент select html для создания выпадающего меню и использовать атрибут value элементов option для выполнения действий при выборе опции. Подробнее читайте здесь: https://www.w3schools.com/tags/tag_select.asp
  2. В вашем случае мы можем использовать текст внутри тега span вместо идентификатора, чтобы увидеть, какой вариант был выбран, и отобразить задачи на основе выбранного параметра.
  3. Затем мы можем использовать функцию массива JS ES6 .filter(item => condition) , которая перебирает элементы в массиве и возвращает новый массив со всеми элементами, которые соответствуют заданному условию.
 document.getElementById('myDropdown').addEventListener('click', function(event) {
    if (e.target.localName === 'span'){
        let selectedOption = e.target.innerText;

        if(selectedOption === 'All Tasks')
            renderToDos(toDoList); // render everything
 
        else if(selectedOption === 'Active'){
            let activeToDos = toDoList.filter(todo => todo.completed === false);
            renderToDos(activeToDos); // only render the todos which have not been completed
        }

        else if(selectedOption === 'Completed'){
            let completedToDos = toDoList.filter(todo => todo.completed === true);
            renderToDos(completedToDos); // only render the todos which have not been completed
        }
    }
});