# Step 10: adding filters and bulk actions

## Adding filters and bulk actions

Now we want to add some filters to show all, only active or only completed tasks.

The first thing we need to do is adding some markup for our filter buttons. Let’s add the following HTML under `<ul id="task-list" class="list-group"></ul>`:

*10.1 – the filters markup*

```markup
<div class="panel-footer text-center small">
  <span>Show:</span>
  <button onclick="filterItems()" class="filter filter-all">All</button>
  <button onclick="filterItems('active')" class="filter filter-active">Active</button>
  <button onclick="filterItems('completed')" class="filter filter-completed">Completed</button>
</div>
```

We added a button with an `onclick` handler that will execute a `filterItems()` function. Let’s create that function:

*10.2 – the new `filterItems()` function*

```javascript
const filterItems = (status) => {
  let itemsToShow = [];

  if (status == 'completed') {
    itemsToShow = listItems.filter((item) => item.completed);
  } else if (status == 'active') {
    itemsToShow = listItems.filter((item) => !item.completed);
  } else {
    itemsToShow = listItems;
  }

  updateList(itemsToShow);
}
```

This function will call `updateList()` by passing a list of `itemsToShow` that we create using the array `filter()` function.

But there’s a catch, `updateList()` will also save our tasks each time we call it! We want this to happen when we *modify* our task list (for example adding, deleting, and marking items as done), but we don’t want this if we are simply applying a filter.

What can we do to avoid this? The solution is to modify our `updateList()` function for accepting a second parameter, that we will call `save`.

*10.3 – the updated `updateList()` function*

```javascript
const updateList = (items, save) => {
  let listElement = document.querySelector('#task-list');
  while (listElement.firstChild) listElement.removeChild(listElement.firstChild);
  
  items.forEach((item) => {
    listElement.appendChild(renderItem(item));
  });

  if (save) localStorage.listItems = JSON.stringify(items);
}
```

When we will call the `updateList()` function by passing `true` as second parameter, the last line will be executed, otherwise our tasks will not be saved.

```javascript
updateList(listItems, true) // this will save our tasks.
updateList(listItems) // this will not.
```

Now we can use `updateList()` with the second parameter set to `true` when we want to save (in our `createNew()`, `removeItem()` and `toggleStatus()`), and without the second parameter when we want to filter. This will make our filters work as we want.

Go ahead and modify the `createNew()`, `removeItem()` and `toggleStatus()` functions by passing `true` as second parameter to the `updateList()` function call!

## Adding a “Clear completed” button

We also want to add a button that cleans up all completed tasks. Let’s add the markup to our panel footer:

```markup
<hr>
<button onclick="clearCompleted()" class="btn btn-default btn-xs">Clear completed</button>
```

The `onclick` handler will call a `clearCompleted()` function. Let’s create it:

*10.4 – the new `clearCompleted()` function*

```javascript
const clearCompleted = () => {
  listItems = listItems.filter((item) => !item.completed);

  updateList(listItems, true);
}
```

Once again we will use the `filter()` function available on arrays for obtaining a copy of our `listItems` containing only elements that are not completed. After, we will call `updateList()` as usual, saving our tasks to `localStorage`.

**What we just did:**

* we added filter support by implementing a `filterItems()` function
* we modified our `updateList()` function by making it accept a new `save` parameter
* we added a “Clear completed” button that clears completed tasks


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://bootcamp.shetechitaly.org/day1/01-10.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
