2

So I've been trying to do a JavaScript filtering system, where it hides and shows DIVs based on what button/link is clicked. My buttons use my JavaScript functions filterAll(), filter1(), filter2() and filter3(). I've done some testing in another HTML document, just to get it work in a simpler document, but it only works with IDs and not Class names.

My HTML code:

    <div class="row animate-box grid" id="product-grid">
            <!-- LEFTBAR -->
            <div class="col-sm-6 col-md-4 col-lg-3 p-b-50 grid-item bolcher shots misc" id="leftbar">
                <div class="p-r-20 p-r-0-sm button-group button-group">
                    <!--  -->
                    <h4 class="m-text14 p-b-7" id="button-group-title-categories">
                        Kategorier
                    </h4>

                    <ul class="" id="leftbar-ul">
                        <li class="p-t-4" data-filter="*">
                            <a href="#" class="s-text13 active1 filter-button" onclick="filterAll()">
                                    Alle
                                </a>
                        </li>

                        <li class="p-t-4" data-filter=".bolcher">
                            <a href="#" class="s-text13" onclick="filterBolcher()">
                                    Bolcher
                                </a>
                        </li>

                        <li class="p-t-4" data-filter=".shots">
                            <a href="#" class="s-text13" onclick="filterShots()">
                                    Shots
                                </a>
                        </li>

                        <li class="p-t-4" data-filter=".misc">
                            <a href="#" class="s-text13" onclick="filterMisc()">
                                    Diverse
                                </a>
                        </li>
                    </ul>
                </div>
            </div>

            <!-- PRODUCTS LISTING -->
                        <div id="product_sorting-id_1" class="col-sm-12 col-md-6 col-lg-4 p-b-50 grid-item bolcher">
                <!-- Block2 -->
                <div class="block2">
                    <div class="block2-img wrap-pic-w of-hidden pos-relative">
                        <img src="/images/products/bolcher/abrikos.jpg" alt="IMG-PRODUCT">
                    </div>

                    <div class="block2-txt p-t-20">
                        <p class="block2-name dis-block s-text3 p-b-5" id="product-id-1">
                                        Abrikos</p>
                    </div>
                </div>
            </div>
                      <div id="product_sorting-id_2" class="col-sm-12 col-md-6 col-lg-4 p-b-50 grid-item bolcher">
                <!-- Block2 -->
                <div class="block2">
                    <div class="block2-img wrap-pic-w of-hidden pos-relative">
                        <img src="/images/products/bolcher/althea.jpg" alt="IMG-PRODUCT">
                    </div>

                    <div class="block2-txt p-t-20">
                        <p class="block2-name dis-block s-text3 p-b-5" id="product-id-2">
                                        Althea</p>
                    </div>
                </div>
            </div>
                      <div id="product_sorting-id_3" class="col-sm-12 col-md-6 col-lg-4 p-b-50 grid-item bolcher">
                <!-- Block2 -->
                <div class="block2">
                    <div class="block2-img wrap-pic-w of-hidden pos-relative">
                        <img src="/images/products/bolcher/banan-Lakrids.jpg" alt="IMG-PRODUCT">
                    </div>

                    <div class="block2-txt p-t-20">
                        <p class="block2-name dis-block s-text3 p-b-5" id="product-id-3">
                                        Banan-Lakrids</p>
                    </div>
                </div>
            </div>
                      <div id="product_sorting-id_4" class="col-sm-12 col-md-6 col-lg-4 p-b-50 grid-item bolcher">
                <!-- Block2 -->
                <div class="block2">
                    <div class="block2-img wrap-pic-w of-hidden pos-relative">
                        <img src="/images/products/bolcher/banan.jpg" alt="IMG-PRODUCT">
                    </div>

                    <div class="block2-txt p-t-20">
                        <p class="block2-name dis-block s-text3 p-b-5" id="product-id-4">
                                        Banan</p>
                    </div>
                </div>
            </div>
                      <div id="product_sorting-id_5" class="col-sm-12 col-md-6 col-lg-4 p-b-50 grid-item bolcher">
                <!-- Block2 -->
                <div class="block2">
                    <div class="block2-img wrap-pic-w of-hidden pos-relative">
                        <img src="/images/products/bolcher/blaber.jpg" alt="IMG-PRODUCT">
                    </div>

                    <div class="block2-txt p-t-20">
                        <p class="block2-name dis-block s-text3 p-b-5" id="product-id-5">
                                        Blaber</p>
                    </div>
                </div>
            </div>
                      <div id="product_sorting-id_6" class="col-sm-12 col-md-6 col-lg-4 p-b-50 grid-item bolcher">
                <!-- Block2 -->
                <div class="block2">
                    <div class="block2-img wrap-pic-w of-hidden pos-relative">
                        <img src="/images/products/bolcher/champagnebrus.jpg" alt="IMG-PRODUCT">
                    </div>

                    <div class="block2-txt p-t-20">
                        <p class="block2-name dis-block s-text3 p-b-5" id="product-id-6">
                                        Champagnebrus</p>
                    </div>
                </div>
            </div>
</div>

My JavaScript code is:

var g = document.getElementsByClassName("grid-item");
var b = document.getElementsByClassName("bolcher");
var s = document.getElementsByClassName("shot");
var m = document.getElementsByClassName("diverse");

function filterAll() {
  g.style.display="block";
}

function filterBolcher() {
  g.style.display="none";
  b.style.display="block";
}

function filterShots() {
  g.style.display="none";
  s.style.display="block";
}

function filterMisc() {
  g.style.display="none";
  s.style.display="block";
}
KyleFairns
  • 2,947
  • 1
  • 15
  • 35
Kevin From
  • 142
  • 2
  • 9
  • 3
    `getElementsByClassName` returns a [HTMLCollection](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection). So you'll have to iterate through each element in the list to set the style. – Sebastian Olsen Jul 10 '18 at 09:53
  • There are multiple elements with class name "grid-item". So, you need to iterate through them. Also, some classes are not in the HTML you have pasted. – Nikhil Koul Jul 10 '18 at 09:57
  • Possible duplicate of [What do querySelectorAll, getElementsByClassName and other getElementsBy\* methods return?](https://stackoverflow.com/questions/10693845/what-do-queryselectorall-getelementsbyclassname-and-other-getelementsby-method) – Mamun Jul 10 '18 at 09:57
  • Thank you, both. I looked up the w3schools example of it, and understand I had to make a for loop in my case :) I'm writing an answer on my post now, for people to learn – Kevin From Jul 10 '18 at 10:04

5 Answers5

2

As Sebastian Olsen mentioned in comments, getElementsByClassName returns a node list, not single element, so you can think of it as about an array of elements. And to do something with these elements, you should pick the element from this array like g[index]. You can iterate through this array of elements via regular for loop for example, so your filterAll method should look something like this:

function filterAll() {
  for (var i = 0; i < g.length; i++) {
    g[i].style.display = "block";
  }
}
P.S.
  • 15,970
  • 14
  • 62
  • 86
1

How to access one or more element by using document.getElementsByClassName?

Since document.getElementsByClassName() returns a NodeList with the affected elements which is simply a collection of the class names, you can access it by using indexing (where the indexing starts with 0) or simply with a for loop.

Example with a for loop

var x = document.getElementsByClassName("example");
function function(){
    for (var i = 0; i < g.length; i++){
    x[i].style.display = "block";
  }
}

Example with indexing

var x = document.getElementsByClassName("example");
x[0].style.display = "block";

Note that the for loop method adds a style display: block property for every element, while the indexing method will only apply style for the element with the given index.

Reference

W3C Schools' article about document.getElementsByClassName

squancy
  • 565
  • 1
  • 7
  • 25
0

Iterate through each element:

 function filterAll() {
 for(i=0;i<g.length;i++)
 g[i].style.display="block";
}
Lucifer
  • 645
  • 6
  • 14
0

I fixed it by using the example from W3Schools.com: https://www.w3schools.com/jsref/met_document_getelementsbyclassname.asp

The code I've rewritten it to is:

var g = document.getElementsByClassName("grid-item");
var b = document.getElementsByClassName("bolcher");
var s = document.getElementsByClassName("shot");
var m = document.getElementsByClassName("diverse");
var i;

function filterAll() {
  for (i = 0; i < g.length; i++) {
    g[i].style.display = "block";
  }
}

function filterBolcher() {
  for (i = 0; i < g.length; i++) {
    g[i].style.display = "none";
  }
  for (i = 0; i < b.length; i++) {
    b[i].style.display = "block";
  }
}

function filterShots() {
  for (i = 0; i < g.length; i++) {
    g[i].style.display = "none";
  }
  for (i = 0; i < s.length; i++) {
    s[i].style.display = "block";
  }
}

function filterMisc() {
  for (i = 0; i < g.length; i++) {
    g[i].style.display = "none";
  }
  for (i = 0; i < m.length; i++) {
    m[i].style.display = "block";
  }
}

What I'm doing is "going through" every element that has the corresponding class name, the changing the value of display (see more at the link).

Kevin From
  • 142
  • 2
  • 9
  • Have a look at [my answer](https://stackoverflow.com/a/51262504/7831383) if you want to improve readability and also correct some typos of your original code :) – Rafalon Jul 10 '18 at 10:18
0

Instead of writing a loop everytime, I used a function and called that one:

var g = document.getElementsByClassName("grid-item");
var b = document.getElementsByClassName("bolcher");
var s = document.getElementsByClassName("shot");
var m = document.getElementsByClassName("diverse");

function filterAll() {
  applyDisplay(g, "block");
}

function filterBolcher() {
  applyDisplay(g, "none");
  applyDisplay(b, "block");
}

function filterShots() {
  applyDisplay(g, "none");
  applyDisplay(s, "block");
}

function filterMisc() {
  applyDisplay(g, "none");
  applyDisplay(m, "block");
}

function applyDisplay(nodeList, display) {
  for (var i = 0; i<nodeList.length;i++){
    var node = nodeList[i];
    node.style.display = display;
  }
}
<div class="row animate-box grid" id="product-grid">
 <!-- LEFTBAR -->
 <div class="col-sm-6 col-md-4 col-lg-3 p-b-50 grid-item bolcher shot diverse" id="leftbar">
  <div class="p-r-20 p-r-0-sm button-group button-group">
   <!--  -->
   <h4 class="m-text14 p-b-7" id="button-group-title-categories">
    Kategorier
   </h4>

   <ul class="" id="leftbar-ul">
    <li class="p-t-4" data-filter="*">
     <a href="#" class="s-text13 active1 filter-button" onclick="filterAll()">
       Alle
     </a>
    </li>

    <li class="p-t-4" data-filter=".bolcher">
     <a href="#" class="s-text13" onclick="filterBolcher()">
       Bolcher
     </a>
    </li>

    <li class="p-t-4" data-filter=".shots">
     <a href="#" class="s-text13" onclick="filterShots()">
       Shots
     </a>
    </li>

    <li class="p-t-4" data-filter=".misc">
     <a href="#" class="s-text13" onclick="filterMisc()">
       Diverse
     </a>
    </li>
   </ul>
  </div>
 </div>

 <!-- PRODUCTS LISTING -->
 <div id="product_sorting-id_1" class="col-sm-12 col-md-6 col-lg-4 p-b-50 grid-item bolcher">
  <!-- Block2 -->
  <div class="block2">
   <div class="block2-img wrap-pic-w of-hidden pos-relative">
    <img src="/images/products/bolcher/abrikos.jpg" alt="IMG-PRODUCT">
   </div>

   <div class="block2-txt p-t-20">
    <p class="block2-name dis-block s-text3 p-b-5" id="product-id-1">
        Abrikos</p>
   </div>
  </div>
 </div>
 <div id="product_sorting-id_2" class="col-sm-12 col-md-6 col-lg-4 p-b-50 grid-item bolcher">
  <!-- Block2 -->
  <div class="block2">
   <div class="block2-img wrap-pic-w of-hidden pos-relative">
    <img src="/images/products/bolcher/althea.jpg" alt="IMG-PRODUCT">
   </div>

   <div class="block2-txt p-t-20">
    <p class="block2-name dis-block s-text3 p-b-5" id="product-id-2">
        Althea</p>
   </div>
  </div>
 </div>
 <div id="product_sorting-id_3" class="col-sm-12 col-md-6 col-lg-4 p-b-50 grid-item bolcher">
  <!-- Block2 -->
  <div class="block2">
   <div class="block2-img wrap-pic-w of-hidden pos-relative">
    <img src="/images/products/bolcher/banan-Lakrids.jpg" alt="IMG-PRODUCT">
   </div>

   <div class="block2-txt p-t-20">
    <p class="block2-name dis-block s-text3 p-b-5" id="product-id-3">
        Banan-Lakrids</p>
   </div>
  </div>
 </div>
 <div id="product_sorting-id_4" class="col-sm-12 col-md-6 col-lg-4 p-b-50 grid-item bolcher">
  <!-- Block2 -->
  <div class="block2">
   <div class="block2-img wrap-pic-w of-hidden pos-relative">
    <img src="/images/products/bolcher/banan.jpg" alt="IMG-PRODUCT">
   </div>

   <div class="block2-txt p-t-20">
    <p class="block2-name dis-block s-text3 p-b-5" id="product-id-4">
        Banan</p>
   </div>
  </div>
 </div>
 <div id="product_sorting-id_5" class="col-sm-12 col-md-6 col-lg-4 p-b-50 grid-item bolcher">
  <!-- Block2 -->
  <div class="block2">
   <div class="block2-img wrap-pic-w of-hidden pos-relative">
    <img src="/images/products/bolcher/blaber.jpg" alt="IMG-PRODUCT">
   </div>

   <div class="block2-txt p-t-20">
    <p class="block2-name dis-block s-text3 p-b-5" id="product-id-5">
        Blaber</p>
   </div>
  </div>
 </div>
 <div id="product_sorting-id_6" class="col-sm-12 col-md-6 col-lg-4 p-b-50 grid-item bolcher">
  <!-- Block2 -->
  <div class="block2">
   <div class="block2-img wrap-pic-w of-hidden pos-relative">
    <img src="/images/products/bolcher/champagnebrus.jpg" alt="IMG-PRODUCT">
   </div>

   <div class="block2-txt p-t-20">
    <p class="block2-name dis-block s-text3 p-b-5" id="product-id-6">
        Champagnebrus</p>
   </div>
  </div>
 </div>
</div>

Also note that your filter div contains the classes shots and misc where it should be shot and diverse according to your javascript. (or else change the names in the javascript, whatever)

I also corrected the fact that your question used s instead of m in the filterMisc function.

Rafalon
  • 4,450
  • 2
  • 16
  • 30