Home > Back-end >  execute a function on each element that has a certain class (.js only)
execute a function on each element that has a certain class (.js only)

Time:06-22

As a beginner I'm having problems with logic.

I have this html with ids that i'm not allowed to change, so i won't be able to work with unique ids like infoPrice1,infoPrice2... And what i have to do is to verify if the product has a promotion and create a flag with a class that is already in use in other cases. I checked the promo case by verifying if the priceFrom id exists (it will only exists in this cases).Then I treated the values ​​to know the discount percentage and then write the value in the HTML.

I finally found a way to create a list with elements that have the class product by using getElementsByClassName (which works when I give a console.log[i] to check the elements), but when I pass the function that i created to make the calculations and insert the elements in, it seems to run only on the first element.

I want it to run the function in each element with the class "product". verifying if it has a promo, making the math to create the html element and putting the element in if it have a promo (note tha it may not have when the id priceFrom doesnt exists in the product div)

below the complete code with commented js for better understanding:

function write() {
  var infoPrice = document.getElementById("infoPrice");
  var temPromocao = infoPrice.querySelector("#priceFrom");

  if (temPromocao !== null) {
    //check if element with id priceFrom exists
    var valorDe = document.getElementById("priceFrom").innerText.replace("R$ ", "");
    var valorPor = document.getElementById("bestPrice").innerText.replace("R$ ", "");
    //get values like R$00,00 and returns only  00,00
    var valorIntDe = Number.parseFloat(valorDe.replace(",", "."));
    var valorIntPor = Number.parseFloat(valorPor.replace(",", "."));
    //turns values in number so i can make the calcs = 00.00
    var desconto = Math.round(((valorIntDe - valorIntPor) / valorIntDe) * 100);
    //percentage calculation
    var recebeP = document.getElementById("flagArea");
    recebeP.innerHTML = "<p id='flagBox' class='flag'>-"   (desconto)  "%</p>";
    //create element in html
  };
}

document.addEventListener("DOMContentLoaded", function(a) {
  var products = document.getElementsByClassName("product");

  for (var i = 0; i < products.length; i  ) {
    write(products[i]);
    console.log(products[i].innerHTML)
  }
  //My idea was that this would apply the function on each element with the product class
});
.product {
  border: 1px solid #e41021;
  width: 200px;
  padding: 20px;
}

.fac-product__content__info__price__from {
  display: flex;
  gap: 5px;
}

.flag-area p {
  background-color: #e41021;
  color: #FFFFFF;
  font-weight: 600;
  font-family: sans-serif;
  width: fit-content;
  padding: 5px 10px;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>fac-vtex-cms-auto-flag</title>
  <link rel="stylesheet" href="/styles/style.css" />
</head>

<body>
  <div >
    <div  id="flagArea">
      <p></p>
    </div>
    <div id="infoPrice" >
      <p>Product 1</p>
      <span >
          <p >Old price:</p>
          <p
            id="priceFrom"
            
          >
            R$ 149,00
          </p>
          <p >Sale:</p>
        </span>
      <span id="bestPrice" >R$ 50,00</span
        >
        <em >
          <em>in cash</em>
        </em>
      </div>
    </div>
    <div >
      <div  id="flagArea"></div>
      <p>Product 2</p>
      <div id="infoPrice" >
        <span >
          <p >Old price:</p>
          <p
            id="priceFrom"
            
          >
            R$ 10,00
          </p>
          <p >Sale:</p>
        </span>
      <span id="bestPrice" >R$ 5,00</span
        >
        <em >
          <em>in cash</em>
        </em>
      </div>
    </div>
    <script type="text/javascript" src="/js/script.js"></script>
  </body>
</html>

CodePudding user response:

The write() function needs to use its parameter to access the elements in that product.

It can use querySelector() to select elements with a class inside the product div.

function write(product) {
  var infoPrice = product.querySelector(".fac-product__content__info__price");
  var temPromocao = infoPrice.querySelector(".fac-product__content__info__price__from__price");

  if (temPromocao !== null) {
    var valorDe = temPromocao.innerText.replace("R$ ", "");
    var valorPor = infoPrice.querySelector(".fac-product__content__info__price__sale-price").innerText.replace("R$ ", "");
    //get values like R$00,00 and returns only  00,00
    var valorIntDe = Number.parseFloat(valorDe.replace(",", "."));
    var valorIntPor = Number.parseFloat(valorPor.replace(",", "."));
    //turns values in number so i can make the calcs = 00.00
    var desconto = Math.round(((valorIntDe - valorIntPor) / valorIntDe) * 100);
    //percentage calculation
    var recebeP = product.querySelector(".flag-area");
    recebeP.innerHTML = `<p id="flagBox" >-${desconto}%</p>`;
    //create element in html
  };
}

document.addEventListener("DOMContentLoaded", function(a) {
  var products = document.getElementsByClassName("product");

  for (var i = 0; i < products.length; i  ) {
    write(products[i]);
  }
  //My idea was that this would apply the function on each element with the product class
});
.product {
  border: 1px solid #e41021;
  width: 200px;
  padding: 20px;
}

.fac-product__content__info__price__from {
  display: flex;
  gap: 5px;
}

.flag-area p {
  background-color: #e41021;
  color: #FFFFFF;
  font-weight: 600;
  font-family: sans-serif;
  width: fit-content;
  padding: 5px 10px;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>fac-vtex-cms-auto-flag</title>
  <link rel="stylesheet" href="/styles/style.css" />
</head>

<body>

  <div >
    <div  id="flagArea">
      <p></p>
    </div>
    <div id="infoPrice" >
      <p>Product 1</p>
      <span >
        <p >Old price:</p>
        <p id="priceFrom" >
          R$ 149,00
        </p>
        <p >Sale:</p>
      </span>
      <span id="bestPrice" >R$ 50,00</span>
      <em >
        <em>in cash</em>
      </em>
    </div>
  </div>

  <div >
    <div  id="flagArea"></div>
    <p>Product 2</p>
    <div id="infoPrice" >
      <span >
          <p >Old price:</p>
          <p id="priceFrom" >
            R$ 10,00
          </p>
          <p >Sale:</p>
        </span>
      <span id="bestPrice" >R$ 5,00</span>
      <em >
        <em>in cash</em>
      </em>
    </div>
  </div>
  <script type="text/javascript" src="/js/script.js"></script>
</body>

</html>

  • Related