Discover real-time results of accordions and their information as you search

I am looking to add a search functionality to filter through a list of accordions and their contents on my HTML page. I want the search box to be able to search both the accordion titles and the content within each accordion. This is my first time posting a question on Stackoverflow, so I apologize if it's not clear.

Below is the code showing how I create and display the accordions when a user clicks on a title. (I have a single accordion in the HTML that I clone using a JavaScript file.)

// HTML code:

<input type="search" id="accordion_search_bar" placeholder="Search"/>

<div id="accordions">
  <div id="accID1" class="AccordionContainer">
    <button id="accID" class="accordion"></button>
  <div class="panel" id="panel1">  
</div>

// JavaScript code:

for (a = 0; a < acc.length; a++) {
  acc[a].addEventListener("click", function() {
    this.classList.toggle("active");
    var panel = this.nextElementSibling;
    if (panel.style.maxHeight){
      panel.style.maxHeight = null;
    } else {
      panel.style.maxHeight = panel.scrollHeight + "px";
    } 
  });
}

// Additional JavaScript for the search feature:

$(function() {
   var searchTerm, panelContainerId;
   // Create a new case-insensitive 'contains' selector
   $.expr[":"].containsCaseInsensitive = function(n, i, m) {
   return (
  jQuery(n)
    .text()
    .toUpperCase()
    .indexOf(m[3].toUpperCase()) >= 0
    );
    };

   $("#accordion_search_bar").on("change keyup paste click", function()     {
   searchTerm = $(this).val();
   $("#accordions > .AccordionContainer").each(function() {
    panelContainerId = "#" + $(this).attr("id");
   $(
    panelContainerId + ":not(:containsCaseInsensitive(" + searchTerm +       "))"
   ).hide();
   $(
    panelContainerId + ":containsCaseInsensitive(" + searchTerm + ")"
   ).show();
   });
   });
   });

In essence, I am trying to implement a search bar that can search through the buttons of all accordions and also look within every panel created for each accordion.

Answer №1

By utilizing the HTML property innerText, we have the ability to extract the text content of each accordion and determine if it contains the desired search text. If a match is found, the accordion is displayed, otherwise it is hidden. An informative article on innerText can be found on MDN here. According to MDN,

"It approximates the text the user would get if they highlighted the contents of the element with the cursor and then copied it to the clipboard"

In your case, you may use innerText for searching through accordions with the following approach (using vanilla JavaScript for compatibility):

Retrieve a list of accordions:

accordions = document.querySelectorAll('.AccordionContainer');

If the search term is stored in a variable named searchText, iterate through each accordion and assess its text content:

Array.prototype.forEach.call(accordions, function(accordion) {
    if (accordion.innerText.toLowerCase().indexOf(searchText) >= 0) {
        // Display the accordion if searchText is found
        accordion.style.display = 'block';
    } else {
        // Hide the accordion if searchText is not present
        accordion.style.display = 'none';
    }
});

To ensure case insensitivity, both the search term and accordion text content were converted to lowercase.

An example showcasing an input event listener linked to the search bar could look like the following:

var search = document.getElementById('accordion_search_bar'),
    accordions = document.querySelectorAll('.AccordionContainer');

// Show content when clicked
Array.prototype.forEach.call(accordions, function(accordion) {
    accordion.querySelector('button').addEventListener('click', function() {
        this.nextElementSibling.classList.add('active');
    });
});

// Implement search functionality
search.addEventListener('input', function() {
    var searchText = search.value.toLowerCase();
    Array.prototype.forEach.call(accordions, function(accordion) {
        if (accordion.innerText.toLowerCase().indexOf(searchText) >= 0) {
            accordion.style.display = 'block';
        } else {
            accordion.style.display = 'none';
        }
    });
});
.panel {
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.3s;
}
.panel.active {
    max-height: 300px;
}
<input type="text" id="accordion_search_bar">
<div id="accordions">
  <div class="AccordionContainer">
    <button class="accordion">Show Content</button>
    <div class="panel" id="panel1"> This is accordion text</div>
  </div>
    <div class="AccordionContainer">
    <button class="accordion">Show Content</button>
    <div class="panel" id="panel1"> This is another lot of accordion text</div>
  </div>
</div>

Note that using innerText will search all text content within the accordion, including the button text. To specifically search the panel text, target that element and apply innerText.

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

Troubleshooting module not being found with rekuire, requirish, or rfr in resolving relative require problem in nodejs

Looking to steer clear of the complicated relative path problem detailed here by opting for one of the suggested solutions. I've found three similar libraries that could help: rekuire node-rfr aka Require from Root requirish I've experimented ...

Responsive design with Bootstrap 4's column grid system

Currently, we are striving to create a layout that resembles this design. However, I am facing difficulties in making it responsive. Can anyone offer some guidance? Should we solely incorporate col-* classes? Additionally, we are restricted from setting s ...

Array of materials for ThreeJS GLTFLoader

Attempting to load a model using GLTFLoader and apply different colors for each face of the object (cube) using a material array is not functioning as expected. var materials = [ new THREE.MeshPhongMaterial( {color: 0x552811,specular: 0x222222,shininess: ...

Trouble retrieving an array within a nested immutable object

Can you do this? render() { var items = this.props.items.course_list; console.log(items); return ( <div> </div> ) } Outcome: https://i.sstatic.net/ugSsN.png Attempt to access course ...

Encountering an issue when attempting to execute a sample test using Selenium WebDriver (WebdriverJS)

I attempted to execute a sample test in the file google_search_test.js found at \node_modules\selenium-webdriver\example. I am utilizing WebdriverJS and have only installed the selenium-webdriver NPM package on my system. Navigating to that ...

Counting Characters in a Text Area and Adding Tabs Using JavaScript

As users visit my website to update their profile bio, a character counter written in JavaScript displays the number of characters remaining. When they create a new bio or make changes to their existing one, their current bio is fetched from the database ...

Is it possible to implement CSS code from a server request into a React application?

With a single React app that hosts numerous customer websites which can be customized in various ways, I want to enable users to apply their own CSS code to their respective sites. Since users typically don't switch directly between websites, applying ...

Using HTML to position multiple lines of text alongside an image

I have multiple lines of content and hyperlinks. Additionally, there is an image included. I am looking to have the text aligned on the left with the image on the far right, positioned next to the text. While I attempted to use flexblocks to center everyt ...

Jquery : The initial call to Ajax is not being made

I need help with a Jquery code I am working on. Here is the code: function fetch_data(){ var dataObj; $.ajax({ url: "XXX.soesite.XXX", success: function(result) { dataObj = ['Hi']; console.log("Ins ...

Tips on adjusting section height as window size changes?

Working on a website that is structured into sections. Initially, all links are aligned perfectly upon load. However, resizing the window causes misalignment issues. Check out my progress at: karenrubkiewicz.com/karenportfolio1 Appreciate any help! CSS: ...

What is the best way to record and share a video with jquery and laravel?

Is there a way to grant users access to record videos within an application and then upload them after previewing? I've been able to successfully record and download a video, but now I'm unsure of how to proceed with uploading it to the server. ...

Using jQuery to select the child element of the parent that came before

Recently, I've been experimenting with creating animations using CSS and jQuery. While it has been successful so far, I'm now looking to take it a step further. Specifically, I want information to appear on top of an image when the user clicks on ...

Issue encountered in React Native Expo: Attempting to access an object that is undefined while evaluating item.basicData.criminalName

const SearchContext = React.createContext(); class SearchProvider extends Component { state = { tfG: false, aboutToSearch: "criminals", }; render() { return ( <SearchContext.Provider value={{ state: t ...

Having trouble finding the ./.env file in Gatsby. Encountering an env-cmd error

Having trouble with a file named .env.development in the root folder. I installed env-cmd as a dev dependency and when trying to start the server > npm run develop it gives me an error > <a href="/cdn-cgi/l/email-protection" class="__cf_email__ ...

Is it possible to customize the Toolbar in react-data-grid by adding your own components?

I have been working with the react-data-grid and I'm almost done with it. The filters button is already displaying in the Toolbar, but now I need to add another button that will affect all selected items in the table. I want to place this new button o ...

When working on a small screen, Bootstrap generates divs one by one

Hey there! I've been working with bootstrap CSS library version 5.1.3 and I'm trying to create a simple card layout where there's an image on the left side and text on the right side. Everything looks great on a large screen, but I'm st ...

Fetching text box value that has already been assigned dynamically using JavaScript

I created a PHP form that looks like this: <?php $txtVal1 = "value1"; ?> <script type="text/javascript"> function post_data(){ alert(document.getElementById("text1").value); } </script> <form method="post" action=""> <in ...

The Vue template is not able to recognize the Pug language syntax within the .vue file

According to the Vue documentation: Template processing differs from other webpack loaders, as pug-loader and similar template loaders return a function instead of compiled HTML. Instead of using pug-loader, opting for original pug is recommended. Test ...

Is there a glitch with the External Style Sheet in the CodeIgniter PHP framework?

I inserted the following code into my search.php view page, which had an external style sheet. To include the style sheet in this file, I used: <head> <link rel="stylesheet" type="text/css" href="mystyle.css" /> </head> However, it doe ...

Images failing to appear

I am currently working on a basic webpage. All the text is showing up correctly, but for some reason, the icon I'm trying to display is not appearing. The icon is supposed to be from the ionicons framework. I've double-checked the path to the io ...