Explore the search bar with functional filtering for JSON items

I'm currently working on creating a dynamic filter bar integrated with a search functionality. My data is stored in JSON format, including details such as artist name, title, source, and more. Despite successfully retrieving results through console.log, I am facing challenges in displaying them within the search result box.

const results = document.querySelector(".search-results");
for (let i = 0; i < allMusic.length; i++) {
  let result = `<li li-index="${i + 1}" onclick="clicked(this)">
                <div class="result-box">
                  <div class="result-box-cover">
                  <h1 class="result-name">${allMusic[i].name}</h1>
                  <p class="result-artist">${allMusic[i].artist}</p>
                  </div>
                </div>
                <audio class="${allMusic[i].src}" src="songs/${allMusic[i].src}.mp3"></audio>
              </li>`;
  results.insertAdjacentHTML("beforeend", result);
}

function searchName() {
  input = document.getElementById('search-item');
  filter = input.value.toUpperCase();
  ul = document.getElementsByClassName("search-results");
  li = document.querySelectorAll('.search-results li');

  for (i = 0; i < li.length; i++) {
    nameResult = li[i].getElementsByClassName("result-name")[0];
    artistResult = li[i].getElementsByClassName("result-artist")[0];
    webkitresults = document.getElementsByClassName("search-results")[0];
    nameResult = nameResult.textContent || nameResult.innerText;
    artistResult = artistResult.textContent || artistResult.innerText;
    if (nameResult.toUpperCase().indexOf(filter) > -1) {
      li[i].style.display = "";
      li[i].style.visibility = "visible";
      webkitresults.classList.remove("webkit-hidden");
    }
    else if (artistResult.toUpperCase().indexOf(filter) > -1) {
      li[i].style.display = "";
      li[i].style.visibility = "visible";
      webkitresults.classList.remove("webkit-hidden");
    }
    else {
      li[i].style.display = "none";
      li[i].style.visibility = "hidden";
    }


    if (input.value.length == 0)
    {
      li[i].style.visibility = "hidden";
      webkitresults.classList.add("webkit-hidden");
    }
  }
}

function filterByName() {
  if (filterStatus.classList.contains("Hip-Hop")) {
    var result = allMusic.filter((x)=>x.style === "Hip-Hop");
    console.log(result);
  }
  if (filterStatus.classList.contains("Energic")) {
    var result = allMusic.filter((x)=>x.style === "Energic");
    console.log(result);
  }
}

function filterName(x) {
  filterStatus = document.querySelector(".search-filter");
  if (x==1)
  {
      filterStatus.classList.toggle("Hip-Hop");
      filterByName();
  }
  if (x==2)
  {
      filterStatus.classList.toggle("Energic");
      filterByName();
  }
  if (x==3)
  {
      filterStatus.classList.toggle("Workout");
      filterByName();
  }
  if (x==4)
  {
      filterStatus.classList.toggle("Chill");
      filterByName();
  }
  if (x==5)
  {
      filterStatus.classList.toggle("Sad-Lofi");
      filterByName();
  }
  if (x==6)
  {
      filterStatus.classList.toggle("Rock");
      filterByName();
  }
}

The JSON file serves as a database for the search/filter functionality.


{
      name: "Havana",
      artist: "Camila Cabello",
      src: "CamilaCabelloHavana",
      img: "CamilaCabelloHavana",
      style: "Energic",
      status: "",
  },
  {
      name: "Dj Is Your Second Name",
      artist: "C-Bool , Giang Pham",
      src: "C-BooLDJ",
      img: "C-BooLDJ",
      style: "Energic",
      status: "",
  },
  {
      name: "Never Go Away",
      artist: "C-Bool",
      src: "C-BooL-NeverGoAway",
      img: "C-BooL-NeverGoAway",
      style: "Energic",
      status: "",
  },
  {
      name: "Champions",
      artist: "Kevin Rudolf",
      src: "KevinRudolf-Champions",
      img: "KevinRudolf-Champions",
      style: "Energic",
      status: "",
  },
  {
      name: "Ride It",
      artist: "DJ Regard",
      src: "DJRegard-Rideit",
      img: "DJRegard-Rideit",
      style: "Energic",
      status: "",
  },

  <div class="search-content">

    <h1>What are you looking for?</h1>
    <div class="search-bar">
      <input type="text" id="search-item" placeholder="Artists, Tracks" onkeyup="searchName()">
        <div class="clear-btn">
        <button type="button" id="clear-input-btn" onclick="ClearFields();searchName();"><i class="fa-solid fa-xmark"></i></button>
        </div>
   </div>

  </div>

  <div class="search-filter" id="filterBox">

      <div class="search-item" onclick="filterName(1)">
        <p>Hip-Hop</p>
      </div>
      <div class="search-item" onclick="filterName(2)">
        <p>Energetic</p>
      </div>
      <div class="search-item" onclick="filterName(3)">
        <p>Workout</p>
      </div>
      <div class="search-item" onclick="filterName(4)">
        <p>Chill</p>
      </div>
      <div class="search-item" onclick="filterName(5)">
        <p>Sad-Lofi</p>
      </div>
      <div class="search-item" onclick="filterName(6)">
        <p>Rock</p>
      </div>

  </div>

  <div class="search-results">



  </div>


</div>

Answer №1

It appears that there are opportunities for improvement in your code, even without seeing the HTML. For instance, the filterName(x) function can be refactored as follows:

function filterName(x) {
 if(x>0&&x<7){
  document.querySelector(".search-filter").classList.toggle(
   ["Hip-Hop","Energic","Workout","Chill","Sad-Lofi","Rock"][x-1]);
  filterByName();
 }
}

There may also be ways to simplify the rest of the code, but understanding your HTML structure is crucial.

The filterByName() function currently displays results for "Hip-Hop" and "Energic" separately, which might not be your intended behavior. If you want to filter based on any selected criteria, you could use this updated version:

function filterByName() {
  const classList=[...document.querySelector(".search-filter").classList];
  console.log(allMusic.filter(t=>classList.contains(t.style))
}

Let's combine all the pieces of your code into a cohesive snippet:

// Your revised array of music objects
const allMusic = [
      {name: "Havana",artist: "Camila Cabello",src: "CamilaCabelloHavana",img: "CamilaCabelloHavana",style: "Energic",status: ""},
      // Add more music objects here
];

// Other JavaScript functions and event listeners
.active {
  background-color: #cec;
}
<!-- External CSS stylesheet -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css">

<!-- Search bar and filter buttons in HTML -->

I've taken the liberty of streamlining some parts of your script to make it more concise and maintainable. I switched the <audio> tags to <a> for better visibility.

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

How can we incorporate Django template tags into our jQuery/JavaScript code?

Is it possible to incorporate Django's template tags within JavaScript code? For example, utilizing {% form.as_p %} in jQuery to dynamically inject forms onto the webpage. ...

observing the value of the parent controller from the UI router state's resolve function

I am facing an issue in my AngularJS application while using ui-router. There are three states set up - the parent state controller resolves a promise upon a successful request, and then executes the necessary code. In the child state portfolio.modal.pate ...

When I adjust the height to 100%, Google Maps fails to show up on the screen

When I try to set the height of the gmaps div to 100%, nothing appears on the screen. I am able to set the width to 100%, but for some reason, setting the height to 100% does not work. If I set a specific height like 400px, it works fine. Below is the cod ...

Encountering a ModuleBuildError while setting up Tailwind CSS in Laravel 8

I am currently learning Laravel version 8 and encountered an issue while trying to install Tailwind CSS using the npm command. npm install tailwindcss@npm:@tailwindcss/postcss7-compat @tailwindcss/postcss7-compat postcss@^7 autoprefixer@^9 Here is a detai ...

Employing conditional statements in conjunction with styled components

Is there a way to style my PaymentBtn with the main styled Button but only apply the hover effect when the isLoading prop is activated, without changing anything else? I want the styling to remain the same except for the hover effect. Basic button export ...

How to retrieve multiple checked values from checkboxes in Semantic UI React

Trying to enable users to select multiple checkboxes in react using semantic-ui-react. I am new to react. Here is my code: class ListHandOver extends React.Component { state = { data: {} } handleChange = (e, data) => { console.log( ...

Modify the base URL with JavaScript

Is it possible to dynamically change the href using JavaScript? I attempted to make this change with the code below in my HTML file, but unfortunately, it didn't work: <base href="/" /> <script type="text/javascript"> function setbasehr ...

Using mongoose to differentiate whether an update-upsert operation is performing an insert or an update

Is the "upsert" option for updating working correctly? I attempted to upsert an object into mongodb twice with the same key, but did not receive an inserted message. Am I overlooking something? (mongodb : v2.6.3; mongoose : 3.8.15) Member.findOneAndRemov ...

Tips for repairing a button on an image backdrop and ensuring its position remains unchanged during resizing

My goal is to add tags to people's faces on my website. While I am aware of the image map property, I am facing an issue where the background of the main Div needs to be set to 'cover'. However, when the window is resized, the coordinates of ...

Check a field for validation only when it is visible on the screen

One challenge I'm facing is with an asp.net webform. I have a hidden field that is only displayed when a user selects a radio button. The catch is, this hidden field needs to be mandatory only when it's visible; otherwise, I don't want it to ...

Issue: The function (0, react__WEBPACK_IMPORTED_MODULE_1__.useActionState) is not recognized as a valid function or its output is not iterable

I found a great example of using useActionState at this source. Currently, I am implementing it in my project with Next.js and TypeScript. app/page.tsx: "use client"; import { useActionState } from "react"; import { createUser } from ...

Error: Unable to execute workouts.map as a function in "React" due to a TypeError

This is the JSON data retrieved from the server: {workouts: Array(3)} workouts: Array(3) 0: {_id: 'idnumber1', title: 'pullup', reps: 40, load: '20', createdAt: '2022-07-20T18:06:39.642Z', …} 1: {_id: 'idnumb ...

Customizing colors in React Material UI

Can colors in Material UI be overridden without the use of JS? Is it possible to override colors using CSS alone? ...

Is there a way to deactivate the toggle button in my code?

<label class="switch switch-yes-no" id="disable_'+id+'" style="margin: 0;font-weight: bold;"> <input class="switch-input" type="checkbox" id="disable_'+id+'" /> <span class="switch-label" data-on="Enabled" data-off="Disab ...

Include additional data in the FormData object before sending it over AJAX requests

Currently, I am utilizing AJAX to store some data. The primary concern I have is figuring out how to incorporate additional information into the FormData object along with what I already have. Below is the function that I'm using. Could you assist me ...

Exploring the possibilities of integrating JSONP with Framework7

I've been attempting to retrieve images from the Instagram public API using ajax and JSONP: var target = https://www.instagram.com/p/BP3Wu_EDXsjdT5Llz13jFv2UeS0Vw0OTxrztmo0/?__a=1?callback=?'; $$.ajax({ ty ...

Using Ajax.ActionLink to pass a parameter in JavaScript

When I call a controller in this manner: @Ajax.ActionLink("Clients", "ClientAccountsPartialView", new { entityCode = -1, taxNumber = -1, country = 1, ...

Why isn't this setState function activating?

I am working on creating a versatile notification React component for my application that can be accessed from any part of the code. I have written the following code, where I am attempting to find a workaround for exporting the showNotif function: func ...

What is the most effective method for sharing a form across various components in Angular 5?

I have a primary form within a service named "MainService" (the actual form is much lengthier). Here is an overview- export class MainService { this.mainForm = this.formBuilder.group({ A: ['', Validators.required], B: & ...

cusel.js encountered an error due to attempting to use the 'in' operator to search for 'using' within the specified error

I attempted to implement the cusel.js (styled selects) library on my select elements, but unfortunately it's not functioning as expected. The selects change visually, however when I try to scroll through the options using jscrollpane, an error that I ...