Создание приложения TODO — это очень простой, но тщательный способ понять концепции программного инструмента.

В этом руководстве мы создадим приложение TODO, используя JavaScript для логики и Bootstrap для стилей.

Попробуйте приложение here.

Мы выполним следующие шаги:

Создание пользовательского интерфейса (UI) с помощью Bootstrap

  1. Начните с Bootstrap’s Starter Template
  2. Создайте form для входа пользователя в элемент TODO.
  3. Создайте ненумерованный список для hold all todos.
  4. Создайте list element с флажком для задачи.
  5. Создайте пользовательский интерфейс responsive, используя систему сетки Bootstrap.

Обработка функциональности с помощью JavaScript

  1. Определить структуру наших данных — способ представления всех TODO в формате JSON (JavaScript Object Notation).
  2. renderTodos для отображения TODO в пользовательском интерфейсе.
  3. renderTodo вспомогательная функция для рендеринга отдельного TODO.
  4. addTodo для добавления TODO.
  5. Настройте прослушиватель событий для отправки задачи из пользовательского интерфейса.
  6. completeTodo, чтобы пометить TODO как завершенное.

Строительный интерфейс

Скопируйте стартовый шаблон Bootstrap и добавьте собственный тег скрипта.

<!DOCTYPE html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
<!-- Bootstrap CSS -->
    <link
      href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
      rel="stylesheet"
      integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
      crossorigin="anonymous"
    />
<title>TODO App</title>
  </head>
  <body>
    <!-- CONTENT -->
    <div></div>
<!-- custom JS -->
    <script src="./script.js"></script>
<!-- Bootstrap JS -->
    <script
      src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
      integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
      crossorigin="anonymous"
    ></script>
  </body>
</html>

Создайте форму для ввода пользователем элемента TODO

Назначьте уникальные id для text field и form, чтобы ссылаться на них позже в нашем JavaScript.

<form id="todo-form">
  <!-- input field -->
  <input
    id="todo-text"
    class="form-control form-control-lg"
    type="text"
    placeholder="Your TODO"
    required
  />
  <!-- submit button -->
  <input type="submit" class="btn btn-primary my-3 w-100" />
</form>

Создайте неупорядоченный список для хранения всех задач

<ul id="todo-list" class="list-unstyled"></ul>

Создайте элемент списка с checkbox для элемента списка дел.

<li>
  <div class="form-check">
    <input class="form-check-input" type="checkbox" />
    <label class="form-check-label" for="flexCheckDefault"> TODO Text </label>
  </div>
</li>

Сделайте пользовательский интерфейс отзывчивым, используя сетку Bootstrap.

<div class="container">
  <div class="row row-cols-1 row-cols-sm-1 row-cols-md-2">
    <div class="col">
      <!-- todo form goes here -->
    </div>
    <div class="col">
      <!-- todo list goes here -->
    </div>
  </div>
</div>

Обработка функциональности с помощью JavaScript

Начнем с создания массива объектов для наших задач.

var todos = [
  {
    id: 0,
    text: "subscribe to KJSCE codecell",
    complete: false,
  },
  {
    id: 1,
    text: "Star https://github.com/pettiboy/react-ui-scrollspy on GitHub",
    complete: false,
  },
];

Выберите все необходимые элементы из DOM

const list = document.getElementById("todo-list");
const form = document.getElementById("todo-form");
const todoText = document.getElementById("todo-text");

Давайте попробуем отобразить эти задачи в DOM из нашего JS.

/*
loops over each todo in todos and if the task is not completed yet
calls the renderTodo function to render it to the DOM
*/
function renderTodos() {
  emptyTodos();
  todos.forEach((todo) => {
    if (todo.complete === false) {
      renderTodo(todo);
    }
  });
}
/*
takes a todo object as input and appends the innerHTML 
of the unordered list with that todo
*/
function renderTodo(todo) {
  list.innerHTML += `
        <li>
          <div class="form-check">
            <input onclick="completeTodo(${todo.id});" class="form-check-input" type="checkbox" />
            <label class="form-check-label" for="flexCheckDefault">
              ${todo.text}
            </label>
          </div>
        </li>
      `;
}

Давайте напишем функцию, которая добавляет задачу к нашему массиву объектов с именем todos.

function addTodo(todo) {
  todos.push({
    id: todo.id,
    text: todo.text,
    complete: todo.complete,
  });
  // render that todo to the DOM
  renderTodo(todo);
}

Настройте прослушиватель событий для отправки задачи

// listen for form to be submitted
form.addEventListener("submit", (e) => {
  e.preventDefault();
  addTodo({
    id: todos.length + 1,
    text: todoText.value,
    complete: false,
  });
  // reset value of input field
  todoText.value = "";
});

Давайте напишем функцию, чтобы пометить задачу как завершенную.

function completeTodo(removeId) {
  // Find index of specific object using findIndex method.
  todoIndex = todos.findIndex((todo) => todo.id == removeId);
  // Update object's name property.
  todos[todoIndex].complete = true;
  // Just to wait for a sec before re rendering
  setTimeout(function () {
    saveTodosInMemory();
    renderTodos();
  }, 1000);
}

Храните задачи в localStorage

// on page load - the following functions will run
todos = JSON.parse(localStorage.getItem("todosInMemory")) || [];
renderTodos();

Теперь, когда мы можем создать приложение TODO с помощью JavaScript, мы будем использовать популярный фреймворк под названием React, чтобы создать это приложение и посмотреть, как оно сравнивает и решает различные проблемы с написанием кода с использованием ванильного JavaScript.

Чтобы посмотреть видеоверсию этого руководства, ознакомьтесь с этой лекцией, которую я прочитал на Месяце MERN KJSCE Codecell.

Вы также можете найти код на GitHub.