skip to Main Content

I work on the Kanban board app, it contains three columns for not started, In progress, and Completed tasks, I can add a new task, edit it, delete it, and drag and drop it from column to column. I save all data to local storage, and now I want to retrieve it back when loading the page and add the functionality of the app as it is.

** if any advice to enhance styling when dragging the task to another column as well?

And please if there is any advice to make the code better.

I really appreciate any help you can provide.

I try to set the localStorage.getItem() method but it doesn’t work as I expected

Here’s my code`

HTML

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700&display=swap" rel="stylesheet">
  <link rel="stylesheet" href="style.css">
  <title>Kanban Board</title>
  <script src="script.js" defer></script>
</head>

<body>
  <h1>Kanban Board</h1>
  <div class="container" id="container">
  </div>

  <script type="module" src="https://unpkg.com/[email protected]/dist/ionicons/ionicons.esm.js"></script>
  <script nomodule src="https://unpkg.com/[email protected]/dist/ionicons/ionicons.js"></script>
</body>

</html>

CSS

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html {
    font-size: 62.5%;
}

body {
    font-family: "Roboto", sans-serif;
    background-color: #009578;
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    min-height: 100vh;
    gap: 6rem;
}

h1 {
    font-size: 5rem;
}

h3 {
    font-size: 3.5rem;
    font-weight: normal;
    user-select: none;
}

.container {
    display: flex;
    align-items: center;
    justify-content: space-evenly;
    flex-wrap: wrap;
    gap: 5rem;
    width: 80%;
}

.column,
.tasks {
    padding: 1rem 1rem 1rem 0;
    display: flex;
    flex-direction: column;
    gap: 1rem;
    width: 30rem;
}

.input-container {
    padding: 1rem;
    background-color: #fff;
    border-radius: 4px;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 1rem;
    box-shadow: 0 2px 4px rgb(0 0 0 / 20%);
}

.field {
    font-size: 1.8rem;
    border-radius: 0.4rem;
    outline: 0;
    border: 0;
}

.icon {
    font-size: 2rem;
    color: black;
    cursor: pointer;
}

.edit {
    color: #002d24;
}

.remove {
    color: red;
}

.btn {
    width: 100%;
    padding: 1rem;
    font-size: 1.8rem;
    background-color: #00866d;
    color: #fff;
    border: 0;
    border-radius: 4px;
    cursor: pointer;
    box-shadow: 0 2px 4px rgb(0 0 0 / 20%);
}

.btn:hover {
    background-color: #006854;
}

JavaScript

const board = document.getElementById("container");
const columns = [
    {
        id: 1,
        title: "Not Started",
    },
    {
        id: 2,
        title: "In Progress",
    },
    {
        id: 3,
        title: "Completed",
    },
];
let drag = null;

// Create Columns and render in page
columns.forEach((column) => {
    // Create main column
    const columnDiv = document.createElement("div");
    columnDiv.className = "column";
    columnDiv.id = column.id;

    // Create column title
    const columnTitle = document.createElement("h3");
    columnTitle.textContent = column.title;
    columnDiv.appendChild(columnTitle);

    // Create tasks lists
    const tasksList = document.createElement("ul");
    tasksList.className = "tasks";
    columnDiv.appendChild(tasksList);

    // create add buttons
    const addTaskBtn = document.createElement("button");
    addTaskBtn.className = "btn";
    addTaskBtn.textContent = "+ Add";
    columnDiv.appendChild(addTaskBtn);

    // evevt listener for buttons to Add A new task
    addTaskBtn.addEventListener("click", () => {
        const inputContainer = document.createElement("li");
        inputContainer.className = "input-container";
        inputContainer.draggable = true;
        inputContainer.innerHTML = `
            <input type='text' class='field' id='${column.title}-task' placeholder='Task'/>
            <ion-icon name="pencil-outline" class='icon edit'></ion-icon>
            <ion-icon name="trash-outline" class="icon remove"></ion-icon>
            `;
        tasksList.appendChild(inputContainer);
        taskHandlers();
    });

    board.appendChild(columnDiv);
});

// Update localStorage with html structure
const updateLocalStorage = () => {
    localStorage.setItem(
        "pageStructure",
        document.querySelector(".container").innerHTML,
    );
};

// Handle added tasks and control events on it
function taskHandlers() {
    const tasks = [...document.querySelectorAll("li")];
    tasks.forEach((task) => {
        const input = task.querySelector("input");
        const editBtn = task.querySelector(".edit");
        const deleteBtn = task.querySelector(".remove");

        // Save the task
        const saveTask = () => {
            input.setAttribute("disabled", "");
            input.setAttribute("value", input.value);
            input.style.cursor = "move";
            task.setAttribute("dragable", "true");

            updateLocalStorage();
        };

        // Edit task
        const editTask = () => {
            input.disabled = false;
            input.focus();
            input.style.cursor = "auto";
            task.removeAttribute("draggable");

            updateLocalStorage();
        };

        // Delete task
        const deleteTask = () => {
            task.remove();

            updateLocalStorage();
        };

        // Event listneres
        input.addEventListener("focusout", () => {
            saveTask();
        });

        input.addEventListener("keypress", (e) => {
            if (e.key === "enter") {
                saveTask();
            }
        });

        editBtn.addEventListener("click", editTask);

        deleteBtn.addEventListener("click", deleteTask);

        /*
        *****************
        // Drag and Drop
        *****************
        */
        const dragStart = () => {
            drag = task;
            task.style.opacity = "0.5";
        };

        const dragEnd = () => {
            drag = null;
            task.style.opacity = "1";

            updateLocalStorage();
        };

        task.addEventListener("dragstart", dragStart);
        task.addEventListener("dragend", dragEnd);

        const lists = document.querySelectorAll("ul");
        lists.forEach((list) => {
            list.addEventListener("dragover", (e) => {
                e.preventDefault();
            });

            list.addEventListener("drop", () => {
                list.appendChild(drag);
            });
        });
    });
}

taskHandlers();

2

Answers


  1. You can use

    localStorage.getItem("pageStructure");
    

    Here is more about localStorage

    Login or Signup to reply.
  2. if you want to get from localStorage and insert inside page use this code:

    let a = localStorage.getItem("pageStructure")
    document.getElementById("container").insertAdjacentHTML( 'beforeend', a );
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search