Skip to content
Advertisement

Select filter hides all the items in the list

I am trying to create a select dropdown filter which dynamically gets its values and data from rest api.

Here is my code

HTML

<div class="container">
    <select data-filter="season" class="filter_category_name filter form-control"></select>
    <div class="listContent" id="listitem"></div>
</div>

JS

var data = [{
        "category_name": "1",
        "title": "One One",
        "more": [{
            "details": "some details"
        }]
    },
    {
        "category_name": "1",
        "title": "One Two",
        "more": [{
            "details": "some details"
        }]
    },
    {
        "category_name": "2",
        "title": "Two One",
        "more": [{
            "details": "some details"
        }]
    },
    {
        "category_name": "3",
        "title": "Three One",
        "more": [{
            "details": "some details"
        }]
}];


let listItems = "",
    categoryAll = "";

for(var i = 0;i < data.length; i++) {

    var title = data[i].title,
        category_name = data[i].category_name;

    listItems += "<a onclick='createAVideoContainer(" + i + ")'><div class='listItem'><p>" + title + "</p></div></div></a>";

    if (categoryAll.indexOf("<option value='" + category_name + "'>" + category_name + "</option>") == -1) {
        categoryAll += "<option value='" + category_name + "'>" + category_name + "</option>";
    }
}

$("#listitem").html(listItems);
$(".filter_category_name").append(categoryAll);

var filtersObject = {};

$(".filter").on("change",function() {
    var filterName = $(this).data("filter"),
        filterVal = $(this).val();
    
    if (filterVal == "") {
        delete filtersObject[filterName];
    } else {
        filtersObject[filterName] = filterVal;
    }
    
    var filters = "";
    
    for (var key in filtersObject) {
          if (filtersObject.hasOwnProperty(key)) {
            filters += "[data-"+key+"='"+filtersObject[key]+"']";
          }
    }
    
    if (filters == "") {
        $(".listItem").show();
    } else {
        $(".listItem").hide();
        $(".listItem").hide().filter(filters).show();
    }
});

But for some reason it hides all the items and nothing change after changing the options

I want to initially load all the items and then filter based on the option

I want the select element to dynamically create the options with the values of the category names like the first option should have the value of cars1 and display all the other objects with the same category_name.

Note: The entire code is wrapped inside an async function which renders on page load.

Here is a proper working js fiddle with the above problem

Advertisement

Answer

Based on your fiddle code, it would be better to filter the <a> items within the listItem area based on season, as that is the filter that is built, instead of trying to show/hide the entire listItem area.

The two minor code changes to achieve the desired result, is at these two code points:

  1. Add a data-season reference here, to the <a> tags, with the category_name value:

    listItems += '<a data-season="' + category_name + '" ' 
              + "onclick='createAVideoContainer(" + i + ")'><div class='listItem'><p>" 
              + title + "</p></div></a>";
    
  2. Change the filtering to filter on the <a> tags for the data-season that you build:

    if (filters == "") {
        $("a").show();
    } else {
        $("a").hide();
        $("a").filter(filters).show();
    }
    

Integrating those two changes into your fiddle example code, try the runnable example below:

var data = [
    {
        "category_name": "1",
        "title": "One One",
        "more": [
            {
                "details": "some details"
            }
        ]
    },
    {
        "category_name": "1",
        "title": "One Two",
        "more": [
            {
                "details": "some details"
            }
        ]
    },
    {
        "category_name": "2",
        "title": "Two One",
        "more": [
            {
                "details": "some details"
            }
        ]
    },
    {
        "category_name": "3",
        "title": "Three One",
        "more": [
            {
                "details": "some details"
            }
        ]
    },
];


let listItems = "",
  categoryAll = "";

for(var i = 0; i < data.length; i++) {

  var title = data[i].title,
      category_name = data[i].category_name;

  listItems += '<a data-season="' + category_name + '"'
            + "onclick='createAVideoContainer(" + i + ")'><div class='listItem'><p>" 
            + title + "</p></div></a>";

  if (categoryAll.indexOf("<option value='" + category_name + "'>" + category_name + "</option>") == -1) {
      categoryAll += "<option value='" + category_name + "'>" + category_name + "</option>";
  }
}

$("#listitem").html(listItems);
$(".filter_category_name").append(categoryAll);

var filtersObject = {};

//on filter change
$(".filter").on("change",function() {
  var filterName = $(this).data("filter"),
      filterVal = $(this).val();

  if (filterVal == "") {
      delete filtersObject[filterName];
  } else {
      filtersObject[filterName] = filterVal;
  }

  var filters = "";

  for (var key in filtersObject) {
        if (filtersObject.hasOwnProperty(key)) {
          filters += "[data-"+key+"='"+filtersObject[key]+"']";
       }
  }

  if (filters == "") {
      $("a").show();
  } else {
      $("a").hide();
      $("a").filter(filters).show();
  }
});
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-KyZXEAg3QhqLMpG8r+8fhAXLRk2vvoC2f3B09zVXn8CA5QIVfZOJ3BCsw2P0p/We" crossorigin="anonymous">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

    <div class="container">
        <select data-filter="season" class="filter_category_name filter form-control"></select>
        <div class="listContent" id="listitem">
        </div>
    </div>
    
    <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.3/dist/umd/popper.min.js" integrity="sha384-eMNCOe7tC1doHpGoWe/6oMVemdAVTMs2xqW4mwXrXsW0L84Iytr2wi5v2QjrP/xp" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/js/bootstrap.min.js" integrity="sha384-cn7l7gDp0eyniUwwAZgrzD06kc/tftFf19TOAs2zVinnD/C7E91j9yyk5//jjpt/" crossorigin="anonymous"></script>

Here’s the updated fiddle with the same change applied.

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement