Как с помощью JS создать менеджер задач?
Имеется простая форма для создания новых задач, хотелось бы понять, как с помощью JS добавлять и удалять задачи динамически.
В форме имеются два поля и кнопка: название, описание.
Необходимо ввести данные в поля и добавить задачу по нажатию на кнопку в левый блок. По нажатию на крестик нужно удалять блок с задачей полностью.
Примечания: я новичок в JS, хотелось бы видеть подробные объяснения тех или иных действий, верстка не столь важна, мне главное понять принцип и основы в JS. Сохранять задачи в localStorage не обязательно!
html,
body {
margin: 0;
padding: 0;
min-width: 1000px;
font-family: Arial;
background: #f5f5f5;
}
.fixed-container {
width: 960px;
margin: 0 auto;
position: relative;
}
#column-left {
background-color: #f5f5f5;
width: 470px;
float: left;
height: 515px;
}
#Spisok-del {
/**display: none;*/
color: #8993ad;
font-size: 14px;
margin: 30px 0px 35px 0px;
}
.Spiski-container {
/**display: none;*/
background-color: #FFFFFF;
width: 470px;
float: left;
height: 135px;
margin-bottom: 20px;
}
#column-right {
background-color: #FFFFFF;
width: 470px;
float: right;
height: 525px;
}
#Spisok {
margin-top: 65px;
font-size: 21px;
width: 470px;
float: left;
height: 35px;
}
#Delo {
margin-top: 65px;
font-size: 21px;
width: 470px;
float: right;
height: 35px;
}
.zagolovok {
color: #8993ad;
font-size: 14px;
margin-bottom: 10px;
}
.pole-nazvanie {
width: 390px;
height: 45px;
background: #fcfcfc;
border: 1px solid #ebebeb;
margin-bottom: 30px;
padding: 5px;
}
.delo-settins {
margin: 30px 0px 35px 40px;
}
.pole-opisanie {
padding: 5px;
width: 390px;
height: 230px;
background: #fcfcfc;
border: 1px solid #ebebeb;
margin-bottom: 30px;
}
.button-delo {
background: #2174fd;
border: 0px solid #000;
color: #ffffff;
width: 225px;
height: 55px;
}
<!DOCTYPE html>
<html>
<head>
<title>Список дел</title>
<link rel="stylesheet" href="styles.css">
<script src="jquery-3.5.0.min.js"></script>
<script src="script.js"></script>
</head>
<body>
<div class="fixed-container">
<div id="Spiski">
<h2 id="Spisok">Список дел</h2>
<h2 id="Delo">Добавить новое дело</h2>
</div>
<div id="column-left">
<div class="Spiski-container" id="Spiski">
<h2 id="Spisok-del">Список пуст...</h2>
<ul class="list">
</ul>
</div>
</div>
<div id="column-right">
<div class="delo-settins">
<div class="zagolovok">*Название</div>
<input class="pole-nazvanie" type="nazvanie-form" name="Название">
<div class="zagolovok">*Описание</div>
<input class="pole-opisanie" type="opisanie-form" name="Название">
<button class="button-delo" disabled="disabled">Добавить дело</button>
</div>
</div>
</div>
</body>
</html>
Ответы (2 шт):
Я использовал bootstrap 4 и jQuery
$("#taskAddButton").click(function() {// нахожу кнопку и добавляю к нему эвент на клик
$("#taskList").append(`<div class="card mt-2"><div class="card-header d-flex"><div class="card-title"><span>${$("#taskTitle").val()}</span></div><button type="button" class="close d-flex ml-auto" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button></div><div class="card-body"><span>${$("#taskDescription").val()}</span></div></div>`);
//append = вставляет в элемент, над которым он вызван другой эл-нт (скобках)
//$("#..") - поиск элемента по id
//$("#..").val - получения значения для input
});
$("#taskList").on("click", ".close", function() {// нахожу крестик и навешиваю на него событие по клику. Такой способ потому что он динамический.
$(this).closest(".card").remove(); // remove - удаляет выбранный эл-нт
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
<div class="container-fluid">
<div class="row">
<div class="col-6" id="taskList">
</div>
<div class="col-6" id="addForm">
<form onsubmit="return false;">
<div class="form-group">
<label for="taskTitle">Название</label>
<input type="text" class="form-control" id="taskTitle" aria-describedby="taskTitleHelp">
<small id="taskTitleHelp" class="form-text text-muted">Введите название задания.</small>
</div>
<div class="form-group">
<label for="taskDescription">Описание</label>
<textarea rows="5" cols="45" id="taskDescription" name="text" class="form-control"></textarea>
</div>
<button class="btn btn-primary btn-block" id="taskAddButton">Добавить</button>
</form>
</div>
</div>
</div>
Взял готовую разметку у Виталия Шебаниц.
Я захотел оставить более подробный ответ без использования сторонних библиотек для JS.
Используемые методы:
- document.querySelector()
- document.addEventListener(event, callback)
- document.createElement(tagName)
- element.classList.add()
- element.innerHTML
- element.appendChild(element)
Объясняю последовательность действий:
- Я обозначил все необходимые элементы в начале кода, взял их с помощью
querySelector() - Повесил событие
clickна кнопку c помощью методаaddEventListener() - Создал
callbackфункцию, в которой сделал проверку на поля: название и описание - Создал пустой DIV элемент с помощью
createElement() - Установил для пустого элемента два класса:
card,mt-2 - Вставил в элемент строку состоящую из HTML кода с помощью appendChild()
- Обнулил значение полей: название, описание
- Добавил слушатель на контейнер с задачами
- Проверяю не был нажат крестик внутри контейнера с помощью
event.target.closest('.close') - Если нажат крестик, возвращаюсь до самого элемента с классом
.cardи удаляю его с помощью методаremove()
// Контейнер в который мы будем помещать задачи.
const container = document.querySelector('#taskList');
// Поле - ввод, название задачи
const name = document.querySelector('#taskTitle');
// Поле - ввод, описание задачи
const description = document.querySelector('#taskDescription');
// Кнопка
const button = document.querySelector('#taskAddButton');
// Добавляем слушатель на кнопку, в качестве первого аргумента передаем событие, нам необходимо нажатие - click. В качестве второго аргумента мы передаем функцию (callback), по нажатию на кнопку мы будем возвращены в эту функцию.
button.addEventListener('click', function() {
// Проверяем заполенны ли поля название и описание, если не заполнено хотя-бы одно поле - прерываем дальнейшее выполнение функции возвратив пустое значение.
if (!name.value || !description.value) return;
// Создаем элемент DIV
const task = document.createElement('div');
// Добавляем элементу DIV два класса: card и mt-2
task.classList.add('card', 'mt-2');
// Вставляем HTML код прямо в созданный элемент
task.innerHTML = `
<div class="card-header d-flex">
<div class="card-title">
<span>${name.value}</span>
</div>
<button type="button" class="close d-flex ml-auto" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="card-body">
<span>${description.value}</span>
</div>
`;
// Добавляем в контейнер созданный элемент
container.appendChild(task);
// Обнуляем значения полей названия и описания
name.value = '';
description.value = '';
});
// Так как мы динамически добавляем элементы на страницу, нам необходимо за пределами самого элемента прослушать не было ли нажато крестика, который будет удалять задачу
container.addEventListener('click', function(e) {
// Проверяем на какой элемент мы кликнули, если мы кликнули на элемент который содержит в себе класс .close то удаляем весь родительский блок
if (e.target.closest('.close'))
// Поднимаемся до родительского контейнера и удаляем его полностью
e.target.closest('.card').remove();
});
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container-fluid">
<div class="row">
<div class="col-6" id="taskList">
</div>
<div class="col-6" id="addForm">
<form onsubmit="return false;">
<div class="form-group">
<label for="taskTitle">Название</label>
<input type="text" class="form-control" id="taskTitle" aria-describedby="taskTitleHelp">
<small id="taskTitleHelp" class="form-text text-muted">Введите название задания.</small>
</div>
<div class="form-group">
<label for="taskDescription">Описание</label>
<textarea rows="5" cols="45" id="taskDescription" name="text" class="form-control"></textarea>
</div>
<button class="btn btn-primary btn-block" id="taskAddButton">Добавить</button>
</form>
</div>
</div>
</div>
