Как сделать список задач на js

Добавил пользователь Валентин П.
Обновлено: 05.10.2024

Реализовать 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

Создание списка задач с Vue.js

Для сти­ли­за­ции при­ло­же­ния бу­дем ис­поль­зо­вать Semantic.

Струк­ту­ра ком­по­нен­та

Каж­дое при­ло­же­ние Vue име­ет ком­по­нент верх­не­го уров­ня, у нас та­ким ком­по­нен­том бу­дет TodoList.

У нас уже есть го­то­вый ком­по­нент Hello (сге­не­ри­ро­ван­ный Vue CLI) в пап­ке src/App.​vue, оста­лось со­здать недо­ста­ю­щие ком­по­нен­ты ниж­не­го уров­ня. Со­зда­дим про­стень­кий ком­по­нент TodoList.vue:

Это обыч­ная за­го­тов­ка, ко­то­рую мы за­пол­ним позд­нее.

Им­пор­ти­ру­ем наш ком­по­нент в глав­ный эк­зем­пляр Vue, что­бы мож­но бы­ло с ним ра­бо­тать. От­крой­те файл src/App.​vue и от­ре­дак­ти­руй­те его:

Для об­ра­бот­ки ком­по­нен­та необ­хо­ди­мо его вклю­чить в HTML:

Создание списка задач с Vue.js

Те­перь на­ше при­ло­же­ние вы­гля­дит так: Мы долж­ны пе­ре­да­вать дан­ные глав­но­му ком­по­нен­ту для вы­во­да спис­ка за­дач. За­да­чи бу­дут иметь три свой­ства: На­зва­ние, Про­ект и Вы­пол­не­но.

До­ба­вим дан­ных в наш ком­по­нент:

Нам нуж­но пе­ре­дать дан­ные из глав­но­го ком­по­нен­та в TodoList и для это­го мы бу­дем ис­поль­зо­вать ди­рек­ти­ву v-bind. Она при­ни­ма­ет ар­гу­мент (он от­де­ля­ет­ся двое­то­чи­ем от име­ни ди­рек­ти­вы), в на­шем слу­чае это бу­дет todos; это по­ка­зы­ва­ет ди­рек­ти­ве v-bind свя­зать эле­мент todos с тем, что идёт в нём.

Те­перь нуж­но до­ра­бо­тать ком­по­нент TodoList для до­сту­па к этим дан­ным. До­ба­вим свой­ство к клас­су ком­по­нен­та:

Об­ра­бот­ка дан­ных

Прой­дём­ся в цик­ле по спис­ку за­дач в шаб­лоне TodoList и вы­ве­дем ко­ли­че­ство за­вер­шён­ных и неза­вер­шён­ных за­дач:

Ре­дак­ти­ро­ва­ние за­дач

Раз­де­лим шаб­лон за­да­чи для улуч­ше­ния чи­та­бель­но­сти ко­да. Со­здай­те но­вый ком­по­нент Todo.vue в пап­ке src/components и пе­ре­не­си­те в него шаб­лон за­да­чи:

Пе­ре­ра­бо­та­ем ком­по­нент TodoList для ра­бо­ты с ком­по­нен­том Todo:

До­ба­вим свой­ство isEditing в класс ком­по­нен­та Todo, это свой­ство по­ка­жет ре­дак­ти­ру­ет­ся ли в дан­ный мо­мент за­да­ча или нет. По­ве­сим об­ра­бот­чик со­бы­тия на эле­мент Edit и бу­дем по­ка­зы­вать фор­му ре­дак­ти­ро­ва­ния, при этом из­ме­ним зна­че­ние свой­ства isEditing в true. Оста­лось до­ба­вить фор­му и уста­но­вить на­чаль­ное зна­че­ние свой­ства. Наш шаб­лон те­перь вы­гля­дит так:

У нас есть ме­тод showForm, от­кры­ва­ю­щий фор­му прав­ки, те­перь до­ба­вим ме­тод hideForm для её за­кры­тия при на­жа­тии на кноп­ку от­ме­ны:

Создание списка задач с Vue.js

Дан­ные в фор­ме уже при­вя­за­ны к спис­ку за­дач и их ре­дак­ти­ро­ва­ние ав­то­ма­ти­че­ски со­хра­ня­ет об­нов­лён­ные дан­ные. По на­жа­тию кноп­ки Close уви­дим об­нов­лён­ную за­да­чу:

Уда­ле­ние за­да­чи

До­ба­вим икон­ку уда­ле­ния за­да­чи:

До­ба­вим ме­тод в класс ком­по­нен­та, вы­зы­ва­е­мый по со­бы­тию delete-todo, и пе­ре­да­ю­щий ком­по­нен­ту те­ку­щую за­да­чу к уда­ле­нию.

Те­перь нуж­но до­ба­вить об­ра­бот­чик со­бы­тия уда­ле­ния в ро­ди­тель­ский ком­по­нент (TodoList):

Пе­ре­да­ём ме­тод deleteTodo в ком­по­нент Todo:

До­бав­ле­ние но­вой за­да­чи

Для со­зда­ния но­вой за­да­чи сде­ла­ем но­вый ком­по­нент CreateTodo в пап­ке src/components. Он вы­ве­дет кноп­ку со зна­ком плюс, она при на­жа­тии от­кро­ет фор­му до­бав­ле­ния за­да­чи:

До­ба­вим но­вый ком­по­нент в глав­ный ком­по­нент:

А та­к­же до­ба­вим ме­тод для со­зда­ния но­вой за­да­чи:

Вы­зов ком­по­нен­та CreateTodo из шаб­ло­на App.​vue:

Создание списка задач с Vue.js

Вы­пол­не­ние за­да­чи

Оста­лось до­ба­вить ме­тод для уста­нов­ки от­мет­ки о вы­пол­не­нии за­да­чи.

Об­ра­бот­чик со­бы­тия бу­дет до­бав­лен в TodoList:

И до­ба­вим вы­зов ме­то­да в шаб­лоне:

Го­то­во! Ни­же по ссыл­кам мож­но уви­деть пол­ный код при­ло­же­ния или по­щу­пать де­мон­стра­ци­он­ную вер­сию.

Здравствуйте, коллеги. Чуть ниже представлен алгоритм написания ToDo листа на jQuery с использованием локального хранилища LocalStorage + возможность редактирования и удаления каждой отдельной задачи из списка. В результате получиться должно следующее — демо. За код прошу строго не судить, т.к. в JS я только начинаю. Однако дельным советам я буду только рад.

Для начала создадим разметку. Стоит заметить, что разметка здесь будет минимальной, т.к. основные действия по добавлению, редактированию и удалению элементов ToDo листа будут происходить динамически.

ToDo list

Классам не удивляйтесь. Я считаю, что для шустрой верстки bootstrap — это то, что нужно. Стили я отображать в статье не буду, т.к. они здесь не главное. Если будет желание — посмотрите в демо примере.

    на странице.
    2) Затем при обновлении страницы из LocalStorage достать записанные задачи и через цикл их перезаписать в этот список, т.к. после обновления список будет пустой.
    3) Далее мы напишем функционал удаления и редактирования отдельной таски. Здесь как раз может возникнуть затык, т.к. ключи, по которым мы будем добавлять значения в LocalStorage после удаления элемента из середины списка собьются с начнут друг друга перезаписывать, но об этом чуть дальше.

Что такое Todo List?

Todo List – это список дел, которые вам нужно выполнить или того, что вы хотите сделать.

Традиционно их пишут на листке бумаги и организовывают в порядке приоритета. При выполнении задачи, её обычно вычеркивают из списка.

Но такой список можно вести не только на листке бумаги, но и в электронном виде, например, браузере.

Исходные коды SimpleTodoList

SimpleTodoList – это название проекта, который мы создадим в рамках данной статьи для ведения списка задач. Напишем его он на HTML, CSS и чистом JavaScript.

Пошаговый процесс его создания приведён в следующем разделе этой статьи, а в этом его демо и исходные коды.

Todo List на чистом JavaScript

SimpleTodoList использует localStorage для хранения задач. Это позволяет при повторном открытии этой страницы или её обновлении считывать данные с веб-хранилища и на их основе воссоздавать последнее состояние списка.

Сохранение данных в хранилище происходит всякий раз, когда изменяется состояния этого списка. Это необходимо для того, чтобы в localStorage всегда находились актуальные сведения.

  • добавлять новые задачи в список;
  • отмечать выполненные задачи (при этом они сразу исключаются из списка активных задач и переводятся в завершённый);
  • удалять элементы в корзину;
  • удалять окончательно задачи в корзине, а также при необходимости восстанавливать их;
  • переключаться между делами (активными, завершёнными и удалёнными);
  • автоматически сохранять списки дел в localStorage (необходимо для восстановления последнего состояния списка при повторном открытии страницы).

Описание процесса создания SimpleTodoList

Разработку SimpleTodoList выполним за 5 шагов.

Шаг 1. Создание файловой структуры

Файловая структура проекта:

Файловая структура Todo List

Шаг 2. Добавление в index.html базовой структуры

Шаг 3. Выполнение разметки самого todo

Разметим блок todo:

  • текстовое поле ( с классом todo__text ) для ввода новой задачи;
  • кнопку .todo__add для добавления новой задачи в .todo__items ;
  • элемент управления с выпадающим список задач для переключения между ними;
  • список задач .todo__items , добавлять их в него будем с помощью JavaScript.

Скриншот того, что у нас вышло:

Скриншот Todo List после выполнения разметки

HTML-код самой задачи:

Его формирование и вставку в .todo__items будем осуществлять с помощью JavaScript.

Значение атрибута data-todo-state будет определять состояние задачи:

  • active – активная;
  • completed – выполненная;
  • deleted – удалённая.

.todo__task – это элемент, который содержит текст задачи, а .todo__action – это кнопки для выполнения действий над задачей. С помощью них мы можем восстановить задачу (перевести её в активное состояние), отметить задачу как завершённую и удалить. Действие, которое выполняет кнопка .todo__action определяется значением атрибута data-todo-action .

Шаг 4. Написание стилей

Написать стили можно по-разному. Пример того, что получилось:

Скриншот Todo List после выполнения разметки

Конечный 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:

Преобразование исходного синтаксиса в такой, который поддерживает Internet Explorer 11

В 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, содержащего подсказки.

Читайте также: