Javascript

This version is essentially a mini productivity tool, fully functional in-browser:

Pro To-Do-App

This version is essentially a mini productivity tool, fully functional in-browser:

  1. Tasks with categories and priorities
  2. Drag-and-drop across categories
  3. Persistent storage with localStorage
  4. Filters, search, and sorting by priority

HTML Structure

<div id="todo-app">
  <h1>Pro To-Do List</h1>

  <input type="text" id="task-input" placeholder="Add a task" />

  <select id="category-select">
    <option value="General">General</option>
    <option value="Work">Work</option>
    <option value="Personal">Personal</option>
  </select>

  <select id="priority-select">
    <option value="High">High</option>
    <option value="Medium" selected>Medium</option>
    <option value="Low">Low</option>
  </select>

  <button id="add-btn">Add Task</button>

  <div id="filters">
    <label>Status:
      <select id="filter-status">
        <option value="all">All</option>
        <option value="completed">Completed</option>
        <option value="pending">Pending</option>
      </select>
    </label>

    <label>Category:
      <select id="filter-category">
        <option value="all">All</option>
        <option value="General">General</option>
        <option value="Work">Work</option>
        <option value="Personal">Personal</option>
      </select>
    </label>

    <label>Search:
      <input type="text" id="search" placeholder="Search tasks" />
    </label>

    <label>Sort by Priority:
      <button id="sort-priority">Sort</button>
    </label>
  </div>

  <ul id="task-list"></ul>
</div>

CSS (Optional for clarity)

<style>
  #task-list li {
    padding: 8px;
    margin-bottom: 4px;
    border: 1px solid #ccc;
    cursor: move;
    list-style: none;
  }

  #task-list li.completed {
    text-decoration: line-through;
    color: gray;
  }

  .category-label {
    font-size: 0.8em;
    color: #555;
    margin-left: 8px;
  }

  .priority-label {
    font-size: 0.8em;
    margin-left: 4px;
    font-weight: bold;
  }

  .High { color: red; }
  .Medium { color: orange; }
  .Low { color: green; }
</style>

JavaScript: Pro To-Do App

<script>
let tasks = [];

// Load and save
function loadTasks() {
  const stored = localStorage.getItem("tasks");
  tasks = stored ? JSON.parse(stored) : [];
}

function saveTasks() {
  localStorage.setItem("tasks", JSON.stringify(tasks));
}

const input = document.getElementById("task-input");
const categorySelect = document.getElementById("category-select");
const prioritySelect = document.getElementById("priority-select");
const addBtn = document.getElementById("add-btn");
const taskList = document.getElementById("task-list");
const filterStatus = document.getElementById("filter-status");
const filterCategory = document.getElementById("filter-category");
const searchInput = document.getElementById("search");
const sortPriorityBtn = document.getElementById("sort-priority");

// Render tasks
function renderTasks() {
  taskList.innerHTML = "";
  let filteredTasks = tasks;

  // Filter by status
  const status = filterStatus.value;
  if (status === "completed") filteredTasks = filteredTasks.filter(t => t.completed);
  else if (status === "pending") filteredTasks = filteredTasks.filter(t => !t.completed);

  // Filter by category
  const category = filterCategory.value;
  if (category !== "all") filteredTasks = filteredTasks.filter(t => t.category === category);

  // Search filter
  const search = searchInput.value.toLowerCase();
  if (search) filteredTasks = filteredTasks.filter(t => t.text.toLowerCase().includes(search));

  filteredTasks.forEach((task, index) => {
    const li = document.createElement("li");
    li.textContent = task.text;
    if (task.completed) li.classList.add("completed");

    // Category and priority labels
    const catSpan = document.createElement("span");
    catSpan.textContent = `[${task.category}]`;
    catSpan.className = "category-label";

    const priSpan = document.createElement("span");
    priSpan.textContent = `[${task.priority}]`;
    priSpan.className = `priority-label ${task.priority}`;

    li.appendChild(catSpan);
    li.appendChild(priSpan);

    li.draggable = true;

    // Toggle completed
    li.addEventListener("click", () => {
      task.completed = !task.completed;
      saveTasks();
      renderTasks();
    });

    // Delete on double click
    li.addEventListener("dblclick", () => {
      const originalIndex = tasks.indexOf(task);
      tasks.splice(originalIndex, 1);
      saveTasks();
      renderTasks();
    });

    // Drag-and-drop
    li.addEventListener("dragstart", (e) => {
      e.dataTransfer.setData("text/plain", tasks.indexOf(task));
    });
    li.addEventListener("dragover", (e) => e.preventDefault());
    li.addEventListener("drop", (e) => {
      e.preventDefault();
      const draggedIndex = e.dataTransfer.getData("text");
      const temp = tasks[draggedIndex];
      tasks.splice(draggedIndex, 1);
      const dropIndex = tasks.indexOf(task);
      tasks.splice(dropIndex, 0, temp);
      saveTasks();
      renderTasks();
    });

    taskList.appendChild(li);
  });
}

// Add task
addBtn.addEventListener("click", () => {
  const text = input.value.trim();
  const category = categorySelect.value;
  const priority = prioritySelect.value;
  if (!text) return;

  tasks.push({ text, completed: false, category, priority });
  saveTasks();
  input.value = "";
  renderTasks();
});

// Filters and search
filterStatus.addEventListener("change", renderTasks);
filterCategory.addEventListener("change", renderTasks);
searchInput.addEventListener("input", renderTasks);

// Sort by priority
sortPriorityBtn.addEventListener("click", () => {
  const priorityOrder = { "High": 1, "Medium": 2, "Low": 3 };
  tasks.sort((a, b) => priorityOrder[a.priority] - priorityOrder[b.priority]);
  saveTasks();
  renderTasks();
});

// Enter key to add task
input.addEventListener("keypress", (e) => {
  if (e.key === "Enter") addBtn.click();
});

// Initialize
loadTasks();
renderTasks();
</script>

Features of the Pro To-Do App

  1. Add tasks → text + category + priority
  2. Mark completed → click task
  3. Delete task → double-click
  4. Drag-and-drop reorder → works across categories
  5. Filter by status → All, Completed, Pending
  6. Filter by category → General, Work, Personal
  7. Search tasks → filter dynamically as you type
  8. Sort by priority → High → Medium → Low
  9. Persistent storage → tasks stay on page reload

This version is essentially a mini productivity tool, fully functional in-browser, combining everything we discussed in the other todo app posts:

  • Array methods: push, splice, filter, sort
  • DOM manipulation: createElement, appendChild, classList
  • Events: click, double-click, drag-and-drop, input
  • Persistent storage: localStorage