Issue with filtering tasks in a Task Tracker application

Hey there! I'm new to JavaScript and I've been working on a todo app. Everything seems to be running smoothly except for the filter function, which I just can't seem to get working no matter what I try. I previously had a similar app with materialize that worked perfectly fine.

I've attempted using task.style.display and task.className, but unfortunately, it didn't work out as expected.

CHECK OUT THE DEMO HERE: https://codepen.io/salma-py97/pen/mdOdLvo?editors=1010

Here's a glimpse of the HTML included in my project:

  <body class="bg-secondary">
      <div class="container">
          <div class="row">
              ...

And here's some of the JavaScript code in action:

// Define UI Variables
const form = document.querySelector('#task-form');
const taskInput = document.querySelector('#task-input');
...

Answer №1

The concept of utilizing a single data source
resonates deeply with me as well as the principle of DRY (Don't Repeat Yourself)

const form = document.querySelector('#task-form');
const taskInput = document.querySelector('#task-input');
const filter = document.querySelector('#filter-tasks')
const taskList = document.querySelector("#task-list");
const clearBtn= document.querySelector("#clear-tasks");

class Tasks {
  constructor(taskList) {
    this.taskList = taskList;
    this.tasks=[];
    this.loadTasks();
    this.drawTasks();
  }

  loadTasks(){
    const stored = (localStorage.getItem("tasks"));
    this.tasks = stored ? JSON.parse(stored) : [];
  }   

  createTaskLI(task){
    const li = document.createElement('li');
    li.className = 'list-group-item d-flex justify-content-between'
    li.appendChild(document.createTextNode(task));
    const link = document.createElement('a');
    link.className='delete-item';
    link.innerHTML = '<i class= "fa fa-remove"></i>';
    li.appendChild(link);
    this.taskList.appendChild(li);
  }

  drawTasks() {
    this.tasks.forEach((task) => {
      this.createTaskLI(task)
    })       
  }
  
  clearTasks = () =>{
    this.taskList.innerHTML="";
    this.tasks=[];
    localStorage.clear();
  }
  
  addTask = (e) => {
    e.preventDefault()
    if(taskInput.value === ""){
      alert("Add task");
    } else {
      this.createTaskLI(taskInput.value)
      this.tasks.push(taskInput.value);
      this.UpdateLocalStorage();
      taskInput.value='';
    }        
  }
  
  removeTask = (e) => {
    if (e.target.parentElement.classList.contains('delete-item')){
      const item = e.target.parentElement.parentElement;
      const parent = item.parentElement;
      const index = [...parent.children].indexOf(item);
      item.remove();
      this.tasks.splice(index, 1);
      this.UpdateLocalStorage();
    }
  }

  UpdateLocalStorage(){
    localStorage.setItem("tasks", JSON.stringify(this.tasks));
  }

  filterTasks = (e) => {
    const text = e.target.value.toLowerCase();
    
    document.querySelectorAll('.list-group-item')
      .forEach((task, index) => {
        const condition = (text === "" || this.tasks[index].includes(text)) 
        task.classList.add(condition ? "d-flex" : "d-none");
        task.classList.remove(condition ? 'd-none': "d-flex");  
    })
  }
}

const tasks = new Tasks(taskList);
loadEventListeners();

function loadEventListeners(){
  form.addEventListener('submit', tasks.addTask);
  taskList.addEventListener('click', tasks.removeTask );
  filter.addEventListener('keyup', tasks.filterTasks);
  clearBtn.addEventListener('click', tasks.clearTasks)
}

Answer №2

Utilizing the filterTasks function effectively adds classes, however, neglects to remove them when necessary. It is crucial to address the removal of these classes in order to maintain proper functionality.

if(item.toLowerCase().indexOf(text) != -1){
    task.classList.remove("d-none");
    task.classList.add("d-block");
// else hide task
} else {
    task.classList.remove("d-block");
    task.classList.add("d-none");
}

Consider utilizing classList.toggle as a more efficient alternative in this scenario.

Answer №3

Success at last!

function siftThroughTasks(event){
    // Compare the tasks in the list and the input in the filter
    const searchTerm = event.target.value.toLowerCase();
    
    // Loop through all the list items
    document.querySelectorAll('.list-group-item').forEach(function(taskItem){
        const taskText = taskItem.firstChild.textContent;
        
        // If the filter matches a task, display it
        if(taskText.toLowerCase().indexOf(searchTerm) != -1){
            taskItem.className = "list-group-item d-flex justify-content-between";
        } else {
            // Otherwise, hide the task
            taskItem.classList.remove("d-flex");
            taskItem.classList.add("d-none");
        }
    })

    event.preventDefault();

}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for testing parallel, mocked data requests in JEST by simulating cached responses with a 500ms limit

In order to simulate parallel requests fetching data from different sources, I have implemented tests that introduce artificial latency for each request. The goal is to return a simple string with an identifying digit to determine whether the data has been ...

Issues with navigation drawer not functioning

function adjustMenu() { var navigation = document.getElementById("myTopnav"); if (navigation.className === "topnav") { navigation.className += " responsive"; } else { navigation.className = "topnav"; } } body {margin:0;} ul ...

Interval function not initiating properly post bullet navigation activation

Currently, I am experiencing an issue with my custom slider where the auto sliding set interval function is not working after using the bullet navigation. Despite trying to implement "setTimeout(autoSlide, 1000);", it doesn't seem to be resolving the ...

Stopping npm private organization from releasing public packages

Is there a method to restrict the publication of public packages within an npm organization? It appears that this scenario would often arise (ensuring that no member of an organization accidentally publishes a package as public when it should be private b ...

Troubleshooting Problems with Adjusting Left Margin Using JQuery

function adjust_width() { $('#cont').toggle(function(){ $('#cont').animate({marginLeft:'0%'}); },function(){ $('#cont').animate({marginLeft:'18.4%'}); }); } The code above is in ...

Refresh your HTML by reloading the JavaScript source

In my Ubuntu setup, I've been using chart.js to generate a graph displaying the values from a pressure sensor on an HTML document. Most of the project is complete, but I've encountered a challenge for which I haven't found a satisfactory sol ...

What is the best method for storing a JavaScript widget with analytics - should it be done dynamically or statically?

My widget comes with a customizable boot loader that is used on websites. The boot loader file retrieves the settings for the widget and generates it accordingly. Normally, the content of the bootloader file remains static unless there are modifications ma ...

Concurrent Accordion and Color Transformation Animations

I am currently utilizing jQuery version 2.0.3 and jQuery UI version 1.10.3, specifically using the accordion feature. I am attempting to modify the color of the accordion panels as they open and close by implementing the following code: $(".main-content") ...

Error: When executing the npm run build command, I encountered a TypeError stating that Ajv is not a

I keep encountering an issue whenever I try to execute npm run build error: /node_modules/mini-css-extract-plugin/node_modules/schema-utils/dist/validate.js:66 const ajv = new Ajv({ ^ TypeError: Ajv is not a constructor at Object.<anon ...

Changing a table cell's value when a button is clicked using Angular

I'm working with a bootstrap table that includes a button and a textbox above it. After entering a number in the textbox and clicking the generate button, I need to update the "Bill Amount" column for each row with the value from the textbox. How can ...

How can I transfer information or a variable between React components?

My current challenge involves accessing the CmpnyCode variable from the companymstlist in editcompany.js. Once I have access to this variable, I can utilize it to retrieve data based on that code and populate a form for editing purposes. Initially, I was w ...

The Bootstrap DateTime Picker is not displaying correctly; it appears to be hidden behind the screen

Need assistance with displaying the full datetime picker on the screen. I attempted using position:relative but it's not working as expected. Can someone please help me with this issue? HTML code : <div style="position:relative"> <div class ...

Activate the Giphy search feature in the Slack Nestor bot's response

How can the nestor bot be configured to use a giphy search when replying in a Slack channel where the giphy plugin is active? Can something like msg.reply('/giphy ' + text, done); be used for this purpose? ...

Is there a way to use CSS to generate a disappearing triangle-shaped div that will only vanish when clicked directly on the triangle and not when clicked on the surrounding overflow area?

In a different discussion, it was mentioned that the method used to create a CSS triangle allows for triggering the hover state or click event only when the cursor is inside the triangle. There is a demo provided to demonstrate this with the hover state. ...

Is it possible to integrate a JavaScript library into the Vue prototype?

I've recently integrated ProgressBar.js library into my app, which is built using vue and laravel with laravel mix. After installing ProgressBar.js via npm install, I am unsure how to incorporate it into my .vue files. I'm considering adding it t ...

When the property "a" is set to true, it must also require the properties "b" and "c" to be included

I'm looking for a way to modify the following type structure: type Foo = { a: boolean; b: string; c: string; } I want to change it so that if a is true, then both b and c fields are required. However, if a is false or undefined, then neither b ...

What is the best way to integrate node.js with HTML?

I am currently utilizing node.js to interact with an API on the IBM Cloud platform. I have successfully accessed the response in my code, but now I need to pass this data to an HTML page using "res.send". How can I achieve this? Below is the Node.js code ...

Navigation bar with a divider line along with an accompanying image

How can I position the image behind the navbar without any white line in between them? I've tried adjusting the positioning, z-index, and margin, but nothing seems to work. The website is built with Angular 6 and Bootstrap, and I know it's not th ...

How to set up a function to detect column resizing within the Angular UI-

Is there a way to detect when a column is resized in ui-grid? I need to perform an operation after the column has been resized but cannot find any events related to column resizing. Any suggestions on how to achieve this? ...

The error "TypeError: ollama.chat is not a function" has occurred when trying to use the ollama module in

Currently, I am grappling with a Node.js project that requires me to utilize the ollama module (ollama-js). The problem arises when I invoke the async function chatWithLlama() which contains ollama.chat(), resulting in the following error being thrown: Ty ...