#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:
Я не знаю об анимации, но, по крайней мере, для фильтрации:
- В идеале вы должны использовать элемент select html для создания выпадающего меню и использовать атрибут value элементов option для выполнения действий при выборе опции. Подробнее читайте здесь: https://www.w3schools.com/tags/tag_select.asp
- В вашем случае мы можем использовать текст внутри тега span вместо идентификатора, чтобы увидеть, какой вариант был выбран, и отобразить задачи на основе выбранного параметра.
- Затем мы можем использовать функцию массива 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
}
}
});