Как сделать список задач на js
Реализовать todo-list (план дел на ближайшее время) со следующими простыми возможностями:
1) Добавление новой задачи
2) Удаление задачи
3) Отметка задачи как выполненной/не выполненной
4) Синхронизация состояния задач с удалённым хранилищем (чтобы после перезагрузки страницы данные не пропадали)
Получилось что-то вроде этого:
Особенности реализации читайте под катом.
Собственно начнём с вёрстки, но с учетом использования Vue.
Нам понадобится 2 шаблона:
- шаблон блока с задачами (task-list)
- шаблон задачи (task-item)
JS код же из себя представляет 2 компонента Vue:
- один для работы с записью (task-item)
- второй для работы с списком записей (task-list)
Кроме того нам понадобится сам экземпляр Vue ( см. переменную app)
Компонент task-item управляет наличием класса tasks__item__toggle—completed, который перечеркивает задачу, если она выполнена.
Сохранение состояния задач производится за счёт обработчика метода-наблюдателя (см. watch в экземпляре приложения Vue — app)
Опция deep установлена в true для того, чтобы слежение реагировало на изменения во вложенных объектах — в данном случае поля задачи completed.
Собственно в момент загрузки DOM (см. document.addEventListener(‘DOMContentLoaded’, function() ) производится post обращение к скрипту /files/todo-checklist/ajax.php через action = ‘get-storage’
Он в свою очередь отдаёт нам все задачи в формате JSON и загружает их в экземпляр Vue.
Создание списка задач с Vue.js
Сегодня мы создадим приложение --- список задач с Vue.js, а также рассмотрим и другие удобные инструменты для создания современных веб-приложений.
Убедитесь, что у вас установлена Vue CLI! Если нет, то установите её командой
С Vue CLI идут несколько шаблонов готовых приложений:
Вас спросят название для проекта, описание, автора и сборку Vue. Мы будем работать не устанавливая Vue-router.
Для запуска приложения выполните команду:
Откроется браузер на странице localhost:8080
Для стилизации приложения будем использовать Semantic.
Структура компонента
Каждое приложение Vue имеет компонент верхнего уровня, у нас таким компонентом будет TodoList.
У нас уже есть готовый компонент Hello (сгенерированный Vue CLI) в папке src/App.vue, осталось создать недостающие компоненты нижнего уровня. Создадим простенький компонент TodoList.vue:
Это обычная заготовка, которую мы заполним позднее.
Импортируем наш компонент в главный экземпляр Vue, чтобы можно было с ним работать. Откройте файл src/App.vue и отредактируйте его:
Для обработки компонента необходимо его включить в HTML:
Теперь наше приложение выглядит так: Мы должны передавать данные главному компоненту для вывода списка задач. Задачи будут иметь три свойства: Название, Проект и Выполнено.
Добавим данных в наш компонент:
Нам нужно передать данные из главного компонента в TodoList и для этого мы будем использовать директиву v-bind. Она принимает аргумент (он отделяется двоеточием от имени директивы), в нашем случае это будет todos; это показывает директиве v-bind связать элемент todos с тем, что идёт в нём.
Теперь нужно доработать компонент TodoList для доступа к этим данным. Добавим свойство к классу компонента:
Обработка данных
Пройдёмся в цикле по списку задач в шаблоне TodoList и выведем количество завершённых и незавершённых задач:
Редактирование задач
Разделим шаблон задачи для улучшения читабельности кода. Создайте новый компонент Todo.vue в папке src/components и перенесите в него шаблон задачи:
Переработаем компонент TodoList для работы с компонентом Todo:
Добавим свойство isEditing в класс компонента Todo, это свойство покажет редактируется ли в данный момент задача или нет. Повесим обработчик события на элемент Edit и будем показывать форму редактирования, при этом изменим значение свойства isEditing в true. Осталось добавить форму и установить начальное значение свойства. Наш шаблон теперь выглядит так:
У нас есть метод showForm, открывающий форму правки, теперь добавим метод hideForm для её закрытия при нажатии на кнопку отмены:
Данные в форме уже привязаны к списку задач и их редактирование автоматически сохраняет обновлённые данные. По нажатию кнопки Close увидим обновлённую задачу:
Удаление задачи
Добавим иконку удаления задачи:
Добавим метод в класс компонента, вызываемый по событию delete-todo, и передающий компоненту текущую задачу к удалению.
Теперь нужно добавить обработчик события удаления в родительский компонент (TodoList):
Передаём метод deleteTodo в компонент Todo:
Добавление новой задачи
Для создания новой задачи сделаем новый компонент CreateTodo в папке src/components. Он выведет кнопку со знаком плюс, она при нажатии откроет форму добавления задачи:
Добавим новый компонент в главный компонент:
А также добавим метод для создания новой задачи:
Вызов компонента CreateTodo из шаблона App.vue:
Выполнение задачи
Осталось добавить метод для установки отметки о выполнении задачи.
Обработчик события будет добавлен в TodoList:
И добавим вызов метода в шаблоне:
Готово! Ниже по ссылкам можно увидеть полный код приложения или пощупать демонстрационную версию.
Здравствуйте, коллеги. Чуть ниже представлен алгоритм написания ToDo листа на jQuery с использованием локального хранилища LocalStorage + возможность редактирования и удаления каждой отдельной задачи из списка. В результате получиться должно следующее — демо. За код прошу строго не судить, т.к. в JS я только начинаю. Однако дельным советам я буду только рад.
Для начала создадим разметку. Стоит заметить, что разметка здесь будет минимальной, т.к. основные действия по добавлению, редактированию и удалению элементов ToDo листа будут происходить динамически.
ToDo list
Классам не удивляйтесь. Я считаю, что для шустрой верстки bootstrap — это то, что нужно. Стили я отображать в статье не буду, т.к. они здесь не главное. Если будет желание — посмотрите в демо примере.
-
на странице.
2) Затем при обновлении страницы из LocalStorage достать записанные задачи и через цикл их перезаписать в этот список, т.к. после обновления список будет пустой.
3) Далее мы напишем функционал удаления и редактирования отдельной таски. Здесь как раз может возникнуть затык, т.к. ключи, по которым мы будем добавлять значения в LocalStorage после удаления элемента из середины списка собьются с начнут друг друга перезаписывать, но об этом чуть дальше.
Что такое Todo List?
Todo List – это список дел, которые вам нужно выполнить или того, что вы хотите сделать.
Традиционно их пишут на листке бумаги и организовывают в порядке приоритета. При выполнении задачи, её обычно вычеркивают из списка.
Но такой список можно вести не только на листке бумаги, но и в электронном виде, например, браузере.
Исходные коды SimpleTodoList
SimpleTodoList – это название проекта, который мы создадим в рамках данной статьи для ведения списка задач. Напишем его он на HTML, CSS и чистом JavaScript.
Пошаговый процесс его создания приведён в следующем разделе этой статьи, а в этом его демо и исходные коды.
SimpleTodoList использует localStorage для хранения задач. Это позволяет при повторном открытии этой страницы или её обновлении считывать данные с веб-хранилища и на их основе воссоздавать последнее состояние списка.
Сохранение данных в хранилище происходит всякий раз, когда изменяется состояния этого списка. Это необходимо для того, чтобы в localStorage всегда находились актуальные сведения.
- добавлять новые задачи в список;
- отмечать выполненные задачи (при этом они сразу исключаются из списка активных задач и переводятся в завершённый);
- удалять элементы в корзину;
- удалять окончательно задачи в корзине, а также при необходимости восстанавливать их;
- переключаться между делами (активными, завершёнными и удалёнными);
- автоматически сохранять списки дел в localStorage (необходимо для восстановления последнего состояния списка при повторном открытии страницы).
Описание процесса создания SimpleTodoList
Разработку SimpleTodoList выполним за 5 шагов.
Шаг 1. Создание файловой структуры
Файловая структура проекта:
Шаг 2. Добавление в index.html базовой структуры
Шаг 3. Выполнение разметки самого todo
Разметим блок todo:
- текстовое поле ( с классом todo__text ) для ввода новой задачи;
- кнопку .todo__add для добавления новой задачи в .todo__items ;
- элемент управления с выпадающим список задач для переключения между ними;
- список задач .todo__items , добавлять их в него будем с помощью JavaScript.
Скриншот того, что у нас вышло:
HTML-код самой задачи:
Его формирование и вставку в .todo__items будем осуществлять с помощью JavaScript.
Значение атрибута data-todo-state будет определять состояние задачи:
- active – активная;
- completed – выполненная;
- deleted – удалённая.
.todo__task – это элемент, который содержит текст задачи, а .todo__action – это кнопки для выполнения действий над задачей. С помощью них мы можем восстановить задачу (перевести её в активное состояние), отметить задачу как завершённую и удалить. Действие, которое выполняет кнопка .todo__action определяется значением атрибута data-todo-action .
Шаг 4. Написание стилей
Написать стили можно по-разному. Пример того, что получилось:
Конечный CSS код можно посмотреть на GitHub.
Разберём некоторые интересные моменты в этом коде.
1. Переключение отображение задач в .todo__items будем выполнять в зависимости от выбранной опции . Для этого в вышеприведённом файле прописаны следующие стили:
Устанавливать значение атрибуту data-todo-option элемента .todo__items будем с помощью JavaScript при изменении выбранной опции .
2. Скрытие кнопок для задач, которые не должны показываться для определённых состояний, осуществляется следующим образом:
Шаг 5. Напишем JavaScript
Написание кода начнём с создания объекта todo :
Он нужен только для того, чтобы лучше организовать наш код и не создавать кучу отдельных функций.
Поместим в todo следующие методы:
Начнём с init() . Данный метод будет осуществлять инициализацию Todo List.
Он выполняет следующие вещи:
- получает из localStorage сохранённый список дел и если он есть, то вставляет его в .todo__items ;
- назначает обработчик события change на элемент .todo__options ; в качестве обработчика используется update ;
- назначает обработчик события click на document ; в качестве обработчика выступает action .
Код метода init() :
Когда мы указываем в качестве обработчика функцию или метод объекта, то нужно просто передать ссылку, а не вызов.
При указании this.action мы с помощью bind установили в качестве this текущий контекст. Это нужно чтобы мы могли в action() получить объект todo с помощью this .
Метод create() очень простой, он будет просто возвращать HTML код самой задачи с указанным текстом:
save() получает содержимое .todo__items и устанавливает его в localStorage:
update() используется в качестве обработчика:
При вызове устанавливает атрибуту data-todo-option элемента .todo__items значение выбранной опции , а также значение свойству disabled элемента .todo__text :
add() добавляет при нажатии на кнопку задачу в список .todo__items . Для создания HTML-кода задачи используется create() :
action вызывается, когда происходит событие click на документе:
Параметр e – это объект события event . Его создаёт браузер и передаёт его в качестве первого аргумента action .
В коде e.target – это элемент, по которому кликнули. Так как нам нужны не любые клики, а только по определённым элементам, то используем следующие условия:
Если пользователь кликнул по .todo__add , то выполним следующие действия:
add() добавляет в список .todo__items новую задачу, а save() сохраняет все задачи (содержимое .todo__items ) в localStorage.
Когда пользователь кликнул на .todo__action выполняется следующий код:
Первое – получаем действие, которое нужно выполнить. Оно у нас находится в атрибуте data-todo-action . Далее находим элемент .todo__item и сохраняем его в переменную elemItem . Этот элемент нам понадобится дальше. После этого, если действие delete и состояние задачи delete , то удаляем элемент. В противном случае установим атрибуту data-todo-state элемента .todo__item значение action . В конце сохраним все изменения в localStorage с помощью save() .
Последнее что нужно сделать чтобы Todo работал это вызвать init :
Преобразование JavaScript для запуска в Internet Explorer 11
1. Выполним транспилирование, т.е. преобразуем исходный синтаксис в такой, который понимают старые браузеры, включая Internet Explorer 11.
Для этого воспользуемся онлайн инструментом Babel REPL:
В targets указали: defaults, ie 11 .
Полученный код скопируем и вставим в файл simple-todo-list.es5.js .
Теперь полученный синтаксис понимает Internet Explorer 11. Но этого не достаточно, т.к. в коде у нас остались два метода, который данный браузер не поддерживает. Это closest и remove .
2. Выполним полифилинг, т.е. добавим эти недостающие методы к старым браузерам путем предоставления им собственной версии.
В результате получился следующий код: simple-todo-list.es5.js .
Задачи
1. Добавить возможность создавать задачу при нажатии Enter.
2. Переписать код так, чтобы в localStorage сохранялись задачи не в виде кода HTML, а в формате массива объектов:
3. Внести в код возможность сортировки задач посредством перетаскивания (drag и drop).
5. Для любителей jQuery переписать весь код с использованием функций этой библиотеки.
Создаём приложение To-do List на чистом JavaScript
Вы читаете вольный перевод статьи Building a To-do List App with vanilla JavaScript. В этой статье вы научитесь простыми средствами делать простые вещи, доступные любому новичку.
И так, на данном этапе вы немного изучили HTML, CSS и JavaScript, а теперь думаете, что бы такого написать? Садитесь поудобнее, мы проедем по этапам создания простого приложения To-Do List.
Что мы будем создавать
Я проведу вас по пути создания приложения To-Do List, в котором пользователь может создавать новые списки дел (To-Dos), вычёркивать сделанные пункты или удалять их, сохранять состояние списка дел, чтобы вернуться к нему позже, и удалять список дел целиком.
Перейдём к делу
Прим. переводчика: самое время открыть редактор, создать index.html и переписать пример ниже под свой стиль.
В нашем HTML мы п росто создадим
-
и несколько кнопок. Ещё в примере мы подключили font-awesome, использовали его классы для классных иконок и оставили пару своих классов, с помощью которых чуть позже мы стилизуем приложение.
Вот что у нас вышло:
CSS потребуется для стилизации нашего To-Do List, и тут всё определяет ваше мастерство. Впрочем, вы можете взять готовый пример на github, с которым страница будет выглядеть так:
Задний фон реализован не за счёт изображений, а помощью цветного градиента, для создания которого использован классный инструмент UI Gradients.
Сделаем кое-что посерьёзнее
JavaScript
Мы начнём с реализации механизма создания списка дел, чтобы пользователь мог ввести что-нибудь и нажать Enter для добавления пункта в список.
Прежде всего мы должны выбрать элементы input и ul на странице, используя DOM, и затем написать обработчик событий, который будет обрабатывать события нажатия клавиатуры. Все эти действия будут выполняться в функции onPageLoaded, которая вызывается после полной загрузки DOM, когда возникает событие DOMContentLoaded.
Следует отметить, что каждая клавиша на клавиатуре в JavaScript имеет предопределённый код, а код 13 соответствует клавише Enter. Для определения кода клавиши есть отличный сайт keycode.info.
Далее мы напишем функцию listenDeleteTodo, которая позволит пользователю удалять to-do.
Благодаря этой функции, каждый раз, когда пункт to-do создаётся, его иконка корзины получает способность удалять новый пункт по нажатию.
Далее объявим обработчик события нажатия на пункт to-do, зачёркивающий новый пункт как выполненный.
Теперь мы реализуем возможность сохранять и очищать состояние todo. Мы воспользуемся API LocalStorage, предоставляющим хранилище данных веб-страниц на стороне браузера пользователя.
Как обычно, мы выберем кнопки, с которыми мы будем работать из JavaScript, и добавим им обработчики события click.
В данном примере при нажатии кнопки “Сохранить” мы используем метод setItem() объекта window.localStorage, принимающий два строковых аргумента: ключ и значение. В обработчике нажатия кнопки “Очистить” мы используем метод removeItem() объекта window.localStorage, чтобы удалить данные из хранилища. Кроме того, в примере добавлены обработчики кнопок показа и скрытия элемента overlay, содержащего подсказки.
Читайте также: