how do you map classes to an array which was a HTMLcollection earlier

50 views Asked by At

When clicking, IF the with #CNC_Mach_btn contains an .active class then the tags with .CNC_Machinery class in it should receive a .show class, this part works.

But I also want to remove the .show class on tags without a .CNC_Machinery class.

I changed the NodeLists to arrays and then iterate through tehm and then appended .s

I tried the JS idea "else if (!CNC_Mach_btn.classList.contains("active")) { " ! from here but that didn't work.

HTML & PHP:

JS:

      //gets all category buttons
      // this returns a !!!nodeList!!!!
      let category_btn = document.querySelectorAll('.category-button');
      // gets the button with #CNC_Machining_button for click EventListener
      // this returns a !!!HTMLCollection!!!!
      let CNC_Mach_btn = document.getElementById("CNC_Machining_button");
      //gets anchor tags where the .images class is (all <a> have an image class)
      // this returns a !!!nodeList!!!!

      let Images_Class_In_Anchor_Tag = document.querySelectorAll('.images');
      //transforming nodeList into an array
      const All_Images_Class_MakeArray = Array.from(Images_Class_In_Anchor_Tag);
      //gets .CNC_Machinery classes from anchor tags where also .images class is located
      // this returns a !!!NodeList!!!!
      let CNC_Machining_Class_In_AnchorTag = document.querySelectorAll(".CNC_Machinery");
      //transforming nodeList into an array
      const CNC_Machining_Class_MakeArray = Array.from(CNC_Machining_Class_In_AnchorTag);



    CNC_Mach_btn.addEventListener("click", function() {

       if (CNC_Mach_btn.classList.contains("active")) {
        CNC_Machining_Class_MakeArray.forEach(el => el.classList.add("show"));  
        if (!All_Images_Class_MakeArray.forEach(el => el.classList.contains("CNC_Machinery"))) {
        CNC_Machining_Class_MakeArray.forEach(el => el.classList.remove("show"));
        }
      }
    });

HTML & PHP:

<section class="gallery-links">
<div class="wrapper">
  <h2 class="product-gallery-title">Product Gallery</h2>

  <div class="gallery-container">
    <?php
    include_once 'includes/dbh.inc.php';

    $sql = 'SELECT * FROM gallery ORDER BY orderGallery DESC';
    $stmt = mysqli_stmt_init($conn);
    if (!mysqli_stmt_prepare($stmt,$sql)) {
      echo 'SQL statement failed!';
    } else {
      mysqli_stmt_execute($stmt);
      $result = mysqli_stmt_get_result($stmt);

      while ($row = mysqli_fetch_assoc($result)) {
        //what's echoed out by the database

        echo '  <a class="images '.$row["image_category"].'" style="background-repeat:no-repeat; background-image: url(gallery/'.$row["imgFullNameGallery"].')">
                <div class="color-overlay">
                <h3>'.$row["titleGallery"].'</h3>
                <p>'.$row["descGallery"].'</p>
                </div>
                </a>';
      }
    }


    ?>  

  </div>

Expected Result: .show should be added to anchor tag which contains .CNC_Machinery

Actual Result: .show is not added and removed to anchor tag which contains .CNC_Machinery

2

There are 2 answers

4
Terry On BEST ANSWER

Your script is actually mostly correct, with one exception: your are trying to access the .classList of an array of nodes, that does not work. Instead, you simply loop through the array of nodes and then access the classList for each individual node:

CNC_Mach_btn.addEventListener("click", function() {
  if (CNC_Mach_btn.classList.contains("active")) {
    CNC_Machining_Class_MakeArray.forEach(function(el) {
      el.classList.add("show");
    });
  }
});

Update: since you are using ES6, you can also use arrow functions to make your code a little more concise:

CNC_Mach_btn.addEventListener("click", () => {
  if (CNC_Mach_btn.classList.contains("active")) {
    CNC_Machining_Class_MakeArray.forEach(el => el.classList.add("show"));
  } 
});
0
quirimmo On

You can use the forEach method of NodeList after fetching all the elements with class CNC_Machinery:

document.querySelectorAll('.CNC_Machinery').forEach(e => {
  e.classList.add('show');
});
.show {
  background: red;
}
<div class="CNC_Machinery">Div 1</div>
<div>Div 2</div>
<p class="CNC_Machinery">P 1</p>