Home > Software design >  using sort() on todo list items. Sorting them by alphabet or any other custom code
using sort() on todo list items. Sorting them by alphabet or any other custom code

Time:08-11

I am busy making a todo list app in Typescript. Right now the app reacts to user input and generates list items when the user submits. There is a counter that keeps track of how many list items are present and its possible to delete said list items.

I want to add a sorting function that allows the user to sort the list items on alphabetical order, or even on custom code down the line.

The problem is, i am getting confused by thesort() function, as it only seems to work on arrays. Do i need to redesign the way the input is generated? or can i make a new function to add to my existing code?

What would be the easiest way of implementing a sort() function into the code i have now.

Thank you!

"use strict";
const todoListElement = document.getElementById('ordered-todo-list');
const form = document.getElementById('todo-form');
const listTarget = document.getElementById('listo');
//adds an event listener to the <ol>.
//looks if the html element has a classname that includes delete.
//if it does, it removes the parent element.
todoListElement === null || todoListElement === void 0 ? void 0 : todoListElement.addEventListener("click", (event) => {
    var _a;
    const target = event.target;
    if (target.className.includes('delete')) {
        /*(event.target as HTMLElement).parentElement?.remove();*/
        (_a = target.closest('li')) === null || _a === void 0 ? void 0 : _a.remove();
        updateTheListoCounter();
    }
});
function todoListCreator() {
    var _a;
    // turn the input text into variable:
    const item = document.getElementById('todo-input').value;
    /*-------------------------------------------------template*/
    const templateOfList = document.getElementById('list-item-template').content;
    const copyHTML = document.importNode(templateOfList, true);
    /*Give <span> element the textcontent of item (user input)*/
    copyHTML.querySelector('.task-text').textContent = item;
    /*Add the template content to ordered list*/
    todoListElement === null || todoListElement === void 0 ? void 0 : todoListElement.appendChild(copyHTML);
    // code to show the amount of child elements in the ordered to do list on creation.
    // whenever a new list item is created the counter gets updated
    let counter = (_a = document.getElementById('ordered-todo-list')) === null || _a === void 0 ? void 0 : _a.childElementCount;
    updateTheListoCounter();
}
//this function creates a counter that shows the amount of list items in the 'ordered-todo-list"
//it gets updated everytime a new list item gets created or deleted.
//if the counter hits 0, the counter dissapears.
function updateTheListoCounter() {
    var _a;
    let counter = (_a = document.getElementById('ordered-todo-list')) === null || _a === void 0 ? void 0 : _a.childElementCount;
    if (counter === 0) {
        listTarget.style.display = 'none';
    }
    else {
        listTarget.textContent = String(counter   ':Todo left');
        listTarget.style.display = 'initial';
    }
}
/* prevents page from reloading on submit, and resets user input field to blank after
submit.*/
form === null || form === void 0 ? void 0 : form.addEventListener("submit", (e) => {
    e.preventDefault();
    // resets input field to blank after user submits task
    const resetInput = document.getElementById('todo-input');
    resetInput.value = '';
});
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="styles.css">
    <title>To do list</title>
    <link rel="icon" type="image/jpg" href="/images/favicon-pineapple.jpg">
</head>
<body>


<h1 >todos</h1>
<form id="todo-form" onsubmit="todoListCreator()">
    <button id="scrolldown-menu-toggle">˅</button>
    <input type="text" id="todo-input" placeholder="Fill in your plan">
</form>

<template id="list-item-template">
    <li >
        <input type="checkbox"  name="form-checkbox">
        <span ></span>
        <button >X</button>
    </li>

</template>

<ol id="ordered-todo-list">
</ol>


<span id="listo"></span>




<footer >
    <p>Double click to edit a todo.</p>
    <p>Created by Thomas Brom.</p>
</footer>


<script src="main.js"></script>
</body>
</html>

CodePudding user response:

You are indeed correct that Array.sort() only works on arrays.

It's possible to select all the children of ordered-todo-list with document.querySelectorAll

You could the loop over those elements with for...of and push the items into an array for sorting.

let elements = document.querySelectorAll("#ordered-todo-list > li")

const arr = []
for (let element of elements) {
   arr.push(element.innerHTML)
}

arr.sort(MyAwesomeSortingAlgo)

You'd then have to put everything back into the DOM.

I'd suggest that an easier approach would be to store the todo-items in an array to begin with, and then render those items to the DOM. You could for example use react for rendering. Here is a Typescript React example of this: https://todomvc.com/examples/typescript-react/#/

CodePudding user response:

As you correctly said, sort is a method that only exists in Arrays. Meaning you can only call it on Arrays. Please check sort documentation.

But answering your question. Given that you store the items in the DOM, you would need to extract the list from the DOM into an array, sort it with your custom function, and finally re-render the list.

  • Related