Searchable list modal component in vanilla js.

danishkhanzaada

Danish

Posted on June 28, 2022

Searchable list modal component in vanilla js.

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, 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.

<input type="text" class="form-control" placeholder="Select Item From List" id="searchModalOpener">
Enter fullscreen mode Exit fullscreen mode

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

<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>


Enter fullscreen mode Exit fullscreen mode

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.

document.getElementById("searchModalOpener").onclick = () => { 
    $(`searchModalOpener-modal`).modal("show"); 
}
Enter fullscreen mode Exit fullscreen mode

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

<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>
Enter fullscreen mode Exit fullscreen mode

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.


//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");

Enter fullscreen mode Exit fullscreen mode

Seven: Add listener to list item

// 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);

Enter fullscreen mode Exit fullscreen mode

Eight: Bind search functionality to search bar.

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);
    });

}
Enter fullscreen mode Exit fullscreen mode

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 👋🏻

💖 💪 🙅 🚩
danishkhanzaada
Danish

Posted on June 28, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related