0

I am trying to create filterable content as described on w3schools. I have copied the entire code from there, put the content I wanted to be filtered and changed a few classes. But it doesn't work as in the example. It filters just fine, but when opening the page, it doesn't show all elements as it should. Clicking on buttons displays the correct filter but the buttons are not marked as active.

In the browser's console it says:

Uncaught TypeError: Cannot read property 'getElementsByClassName' of null at vx6.html:57

And the line it refers to is:

var btns = btnContainer.getElementsByClassName("btn");

Script:

filterSelection("all")
function filterSelection(c) {
  var x, i;
  x = document.getElementsByClassName("filtered");
  if (c == "all") c = "";
  for (i = 0; i < x.length; i++) {
    w3RemoveClass(x[i], "show");
    if (x[i].className.indexOf(c) > -1) w3AddClass(x[i], "show");
  }
}

function w3AddClass(element, name) {
  var i, arr1, arr2;
  arr1 = element.className.split(" ");
  arr2 = name.split(" ");
  for (i = 0; i < arr2.length; i++) {
    if (arr1.indexOf(arr2[i]) == -1) {element.className += " " + arr2[i];}
  }
}

function w3RemoveClass(element, name) {
  var i, arr1, arr2;
  arr1 = element.className.split(" ");
  arr2 = name.split(" ");
  for (i = 0; i < arr2.length; i++) {
    while (arr1.indexOf(arr2[i]) > -1) {
      arr1.splice(arr1.indexOf(arr2[i]), 1);     
    }
  }
  element.className = arr1.join(" ");
}

// Add active class to the current button (highlight it)
var btnContainer = document.getElementById("controls");
var btns = btnContainer.getElementsByClassName("btn");
for (var i = 0; i < btns.length; i++) {
  btns[i].addEventListener("click", function(){
    var current = document.getElementsByClassName("active");
    current[0].className = current[0].className.replace(" active", "");
    this.className += " active";
  });
}

Buttons:

<div id="controls" class="-sh8x-menu">
  <button class="btn active" onclick="filterSelection('all')"> Pokaż wszystkie</button>
  <button class="btn" onclick="filterSelection('-filter-restaurants')"> Restauracje i bary</button>
  <button class="btn" onclick="filterSelection('-filter-caffee')"> Kawiarnie i lodziarnie</button>
  <button class="btn" onclick="filterSelection('-filter-mikolajki')"> Lokale w mieście</button>
  <button class="btn" onclick="filterSelection('-filter-outside')"> Lokale poza miastem</button>
  <button class="btn" onclick="filterSelection('-filter-music')"> Lokale z muzyką na żywo</button>
  <button class="btn" onclick="filterSelection('-filter-allyear')"> Lokale całoroczne</button>
  <button class="btn" onclick="filterSelection('-filter-delivery')"> Jedzenie z dowozem</button>
</div>

The elements are displayed as flex. Could you help me with this? I have no idea what is wrong. Even if I don't change the class names and ids, it doesn't work as it should.

Here is he live preview: vx6.html.

SH8X
  • 1

0 Answers0