Управление проектами

Делаем свой планировщик задач

Трелло — удобная штука для ведения проектов. Там все задачи представлены в виде колонок, а каждая колонка отвечает за что-то своё. Давайте сделаем нечто подобное, тем более что всё для этого у нас уже есть:

  • Bootstrap, с которым мы познакомились, пока создавали страницы с котиками;
  • список задач, где можно добавлять новые и удалять ненужные пункты.

Если это объединить, получится что-то похожее на Trello. Логика такая:

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

Мы сделаем 4 колонки, но вы для себя можете сделать их столько, сколько нужно. Единственное ограничение — Bootstrap не позволяет делать больше 12 колонок. Надеемся, вам этого хватит.

Готовим колонки и настраиваем стили

За основу возьмём страницу из статьи про котиков и сделаем с ней следующее:

  • перенесём в неё стили из страницы со списком задач;
  • добавим недостающие стили для заголовков колонок и всей страницы;
  • подготовим пустые 4 колонки и настроим их размер под разную ширину экрана.

Если мы всё сделаем правильно, то получится следующее:

             
Управление проектами, делами и собой

Наполняем колонки

У каждой колонки должно быть своё название, поэтому назовём их «Сделать», «Позвонить», «Написать» и «Идеи».

Читайте также:  Деление матриц python numpy

Мы помним, что в каждой колонке должен быть отдельный список задач, поэтому возьмём кусок кода из прошлого материала. Главное, что нам нужно учесть, — что у каждого списка должно быть своё уникальное имя, чтобы мы их не перепутали в процессе. Для этого мы просто добавим цифры от одного до четырёх к названию каждого списка. Например, было «tldDiv», а стало «tld1Div, «tld2Div» и так далее.

В итоге колонки будут выглядеть так:

Переносим и расширяем скрипт

Теперь наша задача — взять прошлый скрипт и адаптировать его под наши цели. Нам нужно, чтобы каждая колонка с задачами работала автономно и не зависела от других, поэтому сейчас скрипт увеличится в 4 раза — для каждого списка будет свой код.

Сразу скажем: это плохое решение. Копипаст кода для расширения функциональности — это путь к долгой мучительной смерти под завалами спагетти-кода. По-хорошему нужно заворачивать это приложение в классы, делать объекты и работать с ними.

Если собрать все изменения, которые нам понадобятся, то получится такой список:

  • В самом начале, когда мы заводим переменные под наши задачи, у нас теперь не просто List и Mask, а List1, Mask1, List2, Mask2 и так далее. Это нужно для того, чтобы не смешивать списки задач.
  • Поменялось и содержимое этих переменных — теперь там есть цифры, которые показывают, к какому списку они относятся. Важный момент — у нас длина префикса «tdl_» увеличилась на один символ и стала, например, «tdl1_». Это нам нужно будет учесть в середине скрипта.
  • Так как списки должны быть автономны, то и индексы, которые мы добавляем к каждому элементу, тоже должны не зависеть друг от друга. Отсюда и переменные вида element_Id_1 и number_Id_1.

Единственное, что осталось прежним, — обработка удаления задачи. В обработчике всё уже изначально организовано так, что скрипт сразу получает все данные, которые ему нужны, независимо от колонки и порядкового номера задачи.

Сам скрипт получается таким:

// Подключаем JQuery // Пишем скрипт, который будет обрабатывать наши задачи и хранить их на нашем устройстве // Заводим переменные под наши задачи var List1 = $('#tdl1App ul'); var Mask1 = 'tdl1_'; var List2 = $('#tdl2App ul'); var Mask2 = 'tdl2_'; var List3 = $('#tdl3App ul'); var Mask3 = 'tdl3_'; var List4 = $('#tdl4App ul'); var Mask4 = 'tdl4_'; // Функция, которая берёт из памяти наши задачи и делает из них список function showTasks() < // Узнаём размер хранилища var Storage_size = localStorage.length; // Если в хранилище что-то есть… if (Storage_size >0) < // то берём и добавляем это в задачи for (var i = 0; i < Storage_size; i++) < var key = localStorage.key(i); // обрабатываем первый список if (key.indexOf(Mask1) == 0) < // и делаем это элементами списка $(' ').addClass('tdItem') .attr('data-itemid', key) .text(localStorage.getItem(key)) .appendTo(List1); >// обрабатываем второй список if (key.indexOf(Mask2) == 0) < // и делаем это элементами списка $(' ').addClass('tdItem') .attr('data-itemid', key) .text(localStorage.getItem(key)) .appendTo(List2); >// обрабатываем третий список if (key.indexOf(Mask3) == 0) < // и делаем это элементами списка $(' ').addClass('tdItem') .attr('data-itemid', key) .text(localStorage.getItem(key)) .appendTo(List3); >// обрабатываем четвёртый список if (key.indexOf(Mask4) == 0) < // и делаем это элементами списка $(' ').addClass('tdItem') .attr('data-itemid', key) .text(localStorage.getItem(key)) .appendTo(List4); >> > > // Сразу вызываем эту функцию, вдруг в памяти уже остались задачи с прошлого раза showTasks(); // Следим, когда пользователь напишет новую задачу в первое поле ввода и нажмёт Enter $('#tdl1App input').on('keydown', function (e) < if (e.keyCode != 13) return; var str = e.target.value; e.target.value = ""; // Если в поле ввода было что-то написано — начинаем обрабатывать if (str.length >0) < var number_Id_1 = 0; List1.children().each(function (index, el) < var element_Id_1 = $(el).attr('data-itemid').slice(5); if (element_Id_1 >number_Id_1) number_Id_1 = element_Id_1; >) number_Id_1++; // Отправляем новую задачу сразу в память localStorage.setItem(Mask1 + number_Id_1, str); // и добавляем её в конец списка $(' ').addClass('tdItem') .attr('data-itemid', Mask1 + number_Id_1) .text(str).appendTo(List1); > >); // Следим, когда пользователь напишет новую задачу во второе поле ввода и нажмёт Enter $('#tdl2App input').on('keydown', function (e) < if (e.keyCode != 13) return; var str = e.target.value; e.target.value = ""; // Если в поле ввода было что-то написано — начинаем обрабатывать if (str.length >0) < var number_Id_2 = 0; List2.children().each(function (index, el) < var element_Id_2 = $(el).attr('data-itemid').slice(5); if (element_Id_2 >number_Id_2) number_Id_2 = element_Id_2; >) number_Id_2++; // Отправляем новую задачу сразу в память localStorage.setItem(Mask2 + number_Id_2, str); // и добавляем её в конец списка $(' ').addClass('tdItem') .attr('data-itemid', Mask2 + number_Id_2) .text(str).appendTo(List2); > >); // Следим, когда пользователь напишет новую задачу в третье поле ввода и нажмёт Enter $('#tdl3App input').on('keydown', function (e) < if (e.keyCode != 13) return; var str = e.target.value; e.target.value = ""; // Если в поле ввода было что-то написано — начинаем обрабатывать if (str.length >0) < var number_Id_3 = 0; List3.children().each(function (index, el) < var element_Id_3 = $(el).attr('data-itemid').slice(5); if (element_Id_3 >number_Id_3) number_Id_3 = element_Id_3; >) number_Id_3++; // Отправляем новую задачу сразу в память localStorage.setItem(Mask3 + number_Id_3, str); // и добавляем её в конец списка $(' ').addClass('tdItem') .attr('data-itemid', Mask3 + number_Id_3) .text(str).appendTo(List3); > >); // Следим, когда пользователь напишет новую задачу в четвёртое поле ввода и нажмёт Enter $('#tdl4App input').on('keydown', function (e) < if (e.keyCode != 13) return; var str = e.target.value; e.target.value = ""; // Если в поле ввода было что-то написано — начинаем обрабатывать if (str.length >0) < var number_Id_4 = 0; List4.children().each(function (index, el) < var element_Id_4 = $(el).attr('data-itemid').slice(5); if (element_Id_4 >number_Id_4) number_Id_4 = element_Id_4; >) number_Id_4++; // Отправляем новую задачу сразу в память localStorage.setItem(Mask4 + number_Id_4, str); // и добавляем её в конец списка $(' ').addClass('tdItem') .attr('data-itemid', Mask4 + number_Id_4) .text(str).appendTo(List4); > >); // По клику на задаче — убираем её из списка $(document).on('click', '.tdItem', function (e) < // Находим задачу, по которой кликнули var jet = $(e.target); // Убираем её из памяти localStorage.removeItem(jet.attr('data-itemid')); // и убираем её из списка jet.remove(); >) // Закончился основной скрипт

Собираем готовую страницу

Нам осталось собрать всё вместе и проверить, как это работает. Если будете добавлять колонки — не забудьте про новые названия для переменных и про имена элементов в самих колонках. На текущем этапе мы добавляем всё вручную, но в будущей версии сделаем генератор нужного числа колонок.

             
Управление проектами, делами и собой

Что дальше

Чтобы этот продукт стал ближе к идеалу, можно сделать так:

Источник

Scheduler

The Scheduler interface of the Prioritized Task Scheduling API provides the Scheduler.postTask() method that can be used for adding prioritized tasks to be scheduled.

A Scheduler can be accessed from the global object Window or WorkerGlobalScope ( this.scheduler ).

Instance properties

Instance methods

Adds a task to the scheduler as a callback, optionally specifying a priority, delay, and/or a signal for aborting the task.

Examples

If the feature is defined, an instance of this object is returned by the global this in both workers and the main thread. The only property of the interface is the postTask() method, which is used to post the task and returns a promise.

The code below shows a simple task that resolves with the text ‘Task executing’. This text is logged on success. The code also shows a catch block, which would be required in more complex code to handle when a task is aborted or throws an error.

if ("scheduler" in this)  // Post task with default priority: 'user-visible' (no other options) // When the task resolves, Promise.then() logs the result. scheduler .postTask(() => "Task executing") .then((taskResult) => console.log(`$taskResult>`)) // Log result .catch((error) => console.error(`Error: $error>`)); // Log errors > 

Specifications

Browser compatibility

BCD tables only load in the browser

Found a content problem with this page?

This page was last modified on Mar 3, 2023 by MDN contributors.

Your blueprint for a better internet.

Источник

Оцените статью