Searchable list modal component in vanilla js.
Tags: javascript, tutorial, html, css
Published: 2022-06-28 01:54:41

**Peace be upon you - السلام عليكم**

#### The Why

I was using a dropdown to search data of about 22k to 52k of size, dropdown was hanging as it rendered 22k list items at once.

So, I wanted to create my custom searchable list like [Trading View's Search](https://www.tradingview.com/), on clicking the input a modal appears and we can search the data, then click on the searched value and it appears on our initial input.

#### The Steps

1. Create input.
2. Create modal.
3. Bind modal show event to input.
4. Create search input.
5. Create list element.
6. Populate list.
7. Bind listeners to list's element.
8. Bind search functionality to search input and list.


**Technologies used**

* Bootstrap 4
* Vanilla JS
* jQuery


#### Implementation

*First: Create a simple input element and give it a unique id.*

This input is used for opening up the selector modal and showing the selected value from the modal.

```html
<input type="text" class="form-control" placeholder="Select Item From List" id="searchModalOpener">
```


*Second: Create a modal, give it a unique id.*

```html
<div class="modal " id="searchModalOpener-modal" data-backdrop="static">
	<div class="modal-dialog modal-lg" style="height: 600px">
		<div class="modal-content h-100 rounded-4">
			<div class="modal-header">
				<button type="button" class="close" data-dismiss="modal">×</button>
			</div>
			<div class="modal-body"> </div>
		</div>
	</div>
</div>

          
```

Note: Add the modal as direct child to body or inside a div which is direct child to body.


*Third: Bind show event to open modal when clicked on input.*

```js
document.getElementById("searchModalOpener").onclick = () => { 
    $(`searchModalOpener-modal`).modal("show"); 
}
```

*Fourth and Fifth: Adding search input and list (with unique id's) in modal body*

```html
<div class="modal-body">
	<input type="text" class="form-control" style="text-align: center" placeholder="Search Symbol" id="searchModalOpener-search">
	<div id="searchModalOpener-list" style="height: 400px" class="overflow-auto pb-5"></div>
</div>
```

*Sixth: Populate the list with your data*

There can be dozens of ways to achieve it and mine may not be the best so you can be creative in here, I am iterating over the data array and on each iteration I create a p element, style it, add its text value and attach event listener to it so that on click its value gets set on our initial input element, and at last I append it to our list element.


```js

//data: string[] = ["1", "2", "3"];

let list = document.querySelector(`#searchModalOpener-list`);

const addItemToList = (val) => {

    let tag = document.createElement("p");
    tag.id = "p-symbol"
    tag.classList.add(...["my-2", "border-bottom", "py-1"])
    let text = document.createTextNode(val);
    tag.appendChild(text);
    list.appendChild(tag);

}

function populateList() {

    data.forEach((val, index) => {
        addItemToList(val);
    });
}


//Call populateList Method when you are opening the modal, i.e bind it to the shown event of modal

//Above code becomes

$(`searchModalOpener-modal`).on('show.bs.modal', function() {
    listPopulate();
}).modal("show");

```

*Seven: Add listener to list item*

```js
// Create a function and bind it to p tag before appending it to the list

let firstInput = document.querySelector("#searchModalOpener");

cost itemOnClick = (val) => {
    firstInput.setAttribute("value", val);

}

// Add this next line in addItemToList Function just before appending it

tag.onclick = () => itemOnClick(val);

``` 

*Eight: Bind search functionality to search bar.*

```js
const searchBar = document.querySelector(`#searchModalOpener-search`);

searchBar.addEventListener('input', function(e) {
  const query = e.target.value;
  if (query.length > 0) {
    list.innerHTML = ``;

    const filteredList = data.filter(val => val.trim().startsWith(query.toUpperCase()));

    filteredList.forEach((val, index) => {
      addItemToList(val);
    });

}
```

Puff! All done, Feel free to ask anything. Thanks.

PS: After's Joel's comment, it is highly recommended now to just use Vanilla JS, my reason to use jquery was only for modal events, they were not running with document method.

Happy Coding 👋🏻