Home > front end >  ForEach accessing last value from array list
ForEach accessing last value from array list

Time:07-31

I'm trying to create a tabs, for that I used foreach to replicate the tabs in the dom, each block has its price I need to retrieve the specific price of each block in order, but when I try the way I thought it always results in the value of the last object in the array , how can I retrieve the right value of each block with the order form?

let plansVal = [{
    id: 1,
    price: "2,90",
    follows: "50"
  },
  {
    id: 2,
    price: "3,90",
    follows: "150"
  },
  {
    id: 3,
    price: "5,90",
    follows: "250"
  },
  {
    id: 4,
    price: "150,90",
    follows: "350"
  },
  {
    id: 5,
    preco: "300,90",
    follows: "450"
  },
  {
    id: 6,
    preco: "9,90",
    follows: "1000"
  },
  {
    id: 7,
    price: "19,90",
    follows: "1500"
  },
  {
    id: 8,
    price: ",30",
    follows: "2000"
  },
  {
    id: 9,
    price: "59,90",
    follows: "3000"
  },
  {
    id: 10,
    price: "99,90",
    follows: "3500"
  },
];

const tabs = add => {

  const plansContent = $(".plans-content");

  plansContent.append(`

            <div id="plan${add.id}" >
                <div >
                    <span><strong>${add.follows}</strong></span>
                    <p>Seguidores</p>
                </div>
            </div>
        `);

  plansContent.click(function() {
    console.log(add.price);
  });
}

plansVal.forEach(add => tabs(add));
.plans {
  max-width: max-content;
  padding: 0;
}

.plans .plans-title {
  text-align: center;
  font-size: 1.3rem;
  margin-bottom: 25px;
}

.plans .plans-title b {
  color: var(--roxo);
}

.vector_donthavelikes {
  width: 90%;
}

.vector_donthavelikes img {
  max-width: 100%;
  display: block;
  margin: auto;
  image-rendering: optimizeSpeed;
}

.plans .plans-content {
  display: flex;
  justify-content: center;
  flex-flow: row wrap;
  place-items: center;
}

.plans .plans-content .plan {
  min-width: 125px;
  max-width: 125px;
  margin: 5px 3px;
  cursor: pointer;
}

.plans .plans-content .plan .plan-text {
  background-color: #fff;
  height: 80px;
  padding: 10px 5px;
  line-height: 20px;
}

.plans .plans-content .plan.active .plan-text {
  background-color: transparent;
}

.plans .plans-content .plan.active .plan-text p {
  color: #fff;
}

.plans .plans-content .plan .plan-text span {
  font-size: 1.2rem;
  margin-top: 10px;
  display: block;
}

.plans .plans-content .plan .plan-text p {
  font-size: 0.9rem;
  color: var(--cinza-escuro);
}

.plans .plans-content .plan.active {
  color: #fff;
}

.plans .plans-content .plan,
.plans .plans-content .plan.active {
  padding: 7px;
  border-radius: 5px;
  text-align: center;
}

.plans .plans-content .plan.active {
  background-image: -moz-linear-gradient( -151deg, rgb(143, 23, 219) 0%, rgb(220, 134, 125) 100%);
  background-image: -webkit-linear-gradient( -151deg, rgb(143, 23, 219) 0%, rgb(220, 134, 125) 100%);
  background-image: -ms-linear-gradient( -151deg, rgb(143, 23, 219) 0%, rgb(220, 134, 125) 100%);
}

.plans div .plan-value {
  font-size: 1.7rem;
  font-weight: 550;
}

.plans div .plan-value sup {
  color: var(--cinza);
}
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj 3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<div >
  <div >
    <h3 >
      É hora de dar engajamento ao seu Instagram com Seguidores Reais.
      <b>Entrega em poucos minutos.</b>
    </h3>

    <div >
      <img src="/src/imgs/others/donthavelikes.png" alt="">
    </div>
  </div>

  <div ></div>

  <div >
    <p id="planValue" ><sup>R$</sup> 3.99</p>
    <a href="#" >
                            Buy
                        </a>
  </div>
</div>

CodePudding user response:

You're adding multiple click handlers to .plansContent, so when you click on it they all run, and it doesn't know which price you want to print.

You should use event delegation from .plansContent to the .plan elements, then it will get the price out of that element.

let plansVal = [{
    id: 1,
    price: "2,90",
    follows: "50"
  },
  {
    id: 2,
    price: "3,90",
    follows: "150"
  },
  {
    id: 3,
    price: "5,90",
    follows: "250"
  },
  {
    id: 4,
    price: "150,90",
    follows: "350"
  },
  {
    id: 5,
    price: "300,90",
    follows: "450"
  },
  {
    id: 6,
    price: "9,90",
    follows: "1000"
  },
  {
    id: 7,
    price: "19,90",
    follows: "1500"
  },
  {
    id: 8,
    price: ",30",
    follows: "2000"
  },
  {
    id: 9,
    price: "59,90",
    follows: "3000"
  },
  {
    id: 10,
    price: "99,90",
    follows: "3500"
  },
];

const plansContent = $(".plans-content");

plansContent.on("click", ".plan", function() {
  console.log($(this).data("price"));
});

const tabs = add => {
  plansContent.append(`

            <div id="plan${add.id}"  data-price="${add.price}">
                <div >
                    <span><strong>${add.follows}</strong></span>
                    <p>Seguidores</p>
                </div>
            </div>
        `);
}

plansVal.forEach(add => tabs(add));
.plans {
  max-width: max-content;
  padding: 0;
}

.plans .plans-title {
  text-align: center;
  font-size: 1.3rem;
  margin-bottom: 25px;
}

.plans .plans-title b {
  color: var(--roxo);
}

.vector_donthavelikes {
  width: 90%;
}

.vector_donthavelikes img {
  max-width: 100%;
  display: block;
  margin: auto;
  image-rendering: optimizeSpeed;
}

.plans .plans-content {
  display: flex;
  justify-content: center;
  flex-flow: row wrap;
  place-items: center;
}

.plans .plans-content .plan {
  min-width: 125px;
  max-width: 125px;
  margin: 5px 3px;
  cursor: pointer;
}

.plans .plans-content .plan .plan-text {
  background-color: #fff;
  height: 80px;
  padding: 10px 5px;
  line-height: 20px;
}

.plans .plans-content .plan.active .plan-text {
  background-color: transparent;
}

.plans .plans-content .plan.active .plan-text p {
  color: #fff;
}

.plans .plans-content .plan .plan-text span {
  font-size: 1.2rem;
  margin-top: 10px;
  display: block;
}

.plans .plans-content .plan .plan-text p {
  font-size: 0.9rem;
  color: var(--cinza-escuro);
}

.plans .plans-content .plan.active {
  color: #fff;
}

.plans .plans-content .plan,
.plans .plans-content .plan.active {
  padding: 7px;
  border-radius: 5px;
  text-align: center;
}

.plans .plans-content .plan.active {
  background-image: -moz-linear-gradient( -151deg, rgb(143, 23, 219) 0%, rgb(220, 134, 125) 100%);
  background-image: -webkit-linear-gradient( -151deg, rgb(143, 23, 219) 0%, rgb(220, 134, 125) 100%);
  background-image: -ms-linear-gradient( -151deg, rgb(143, 23, 219) 0%, rgb(220, 134, 125) 100%);
}

.plans div .plan-value {
  font-size: 1.7rem;
  font-weight: 550;
}

.plans div .plan-value sup {
  color: var(--cinza);
}
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj 3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<div >
  <div >
    <h3 >
      É hora de dar engajamento ao seu Instagram com Seguidores Reais.
      <b>Entrega em poucos minutos.</b>
    </h3>

    <div >
      <img src="/src/imgs/others/donthavelikes.png" alt="">
    </div>
  </div>

  <div ></div>

  <div >
    <p id="planValue" ><sup>R$</sup> 3.99</p>
    <a href="#" >
                            Buy
                        </a>
  </div>
</div>

CodePudding user response:

you're first issue is here:

plansVal.forEach(add => tabs(add));

you are creating a new function that just calls function tabs, which is redundant. you should be able to replace with:

plansVal.forEach(tabs);

your second issue is here. where in your loop, you keep adding duplicate event listeners to the same HTML element.

plansContent.click(function() {

do you mean to be adding these event listeners to the newly added element that you append, rather than that appended element's parent? if so you will have to change your code in a way that you create a node to append, rather than just appending an HTML string. you can then add the event listener to the node, rather than the parent element that you are appending the node to. Thought there are other ways to do this as well that may be even more efficient.

const newNode = document.createElement('div');
newNode.innerHTML = `<div id="plan${add.id}" >
                <div >
                    <span><strong>${add.follows}</strong></span>
                    <p>Seguidores</p>
                </div>
            </div>`;
plansContent.append(newNode);
newNode.click(function() {

CodePudding user response:

You are selecting the whole container for onClick handler, target each tab.

let plansVal = [{
    id: 1,
    price: "2,90",
    follows: "50"
  },
  {
    id: 2,
    price: "3,90",
    follows: "150"
  },
  {
    id: 3,
    price: "5,90",
    follows: "250"
  },
  {
    id: 4,
    price: "150,90",
    follows: "350"
  },
  {
    id: 5,
    preco: "300,90",
    follows: "450"
  },
  {
    id: 6,
    preco: "9,90",
    follows: "1000"
  },
  {
    id: 7,
    price: "19,90",
    follows: "1500"
  },
  {
    id: 8,
    price: ",30",
    follows: "2000"
  },
  {
    id: 9,
    price: "59,90",
    follows: "3000"
  },
  {
    id: 10,
    price: "99,90",
    follows: "3500"
  },
];


const tabs = (add) => {

  const plansContent = $(".plans-content");

  plansContent.append(`

            <div id="plan${add.id}" >
                <div >
                    <span><strong>${add.follows}</strong></span>
                    <p>Seguidores</p>
                </div>
            </div>
        `);

  document.getElementById(`plan${add.id}`).onclick = () => {
    console.log(add.price);
  }
}

plansVal.forEach(add => tabs(add));
.plans {
  max-width: max-content;
  padding: 0;
}

.plans .plans-title {
  text-align: center;
  font-size: 1.3rem;
  margin-bottom: 25px;
}

.plans .plans-title b {
  color: var(--roxo);
}

.vector_donthavelikes {
  width: 90%;
}

.vector_donthavelikes img {
  max-width: 100%;
  display: block;
  margin: auto;
  image-rendering: optimizeSpeed;
}

.plans .plans-content {
  display: flex;
  justify-content: center;
  flex-flow: row wrap;
  place-items: center;
}

.plans .plans-content .plan {
  min-width: 125px;
  max-width: 125px;
  margin: 5px 3px;
  cursor: pointer;
}

.plans .plans-content .plan .plan-text {
  background-color: #fff;
  height: 80px;
  padding: 10px 5px;
  line-height: 20px;
}

.plans .plans-content .plan.active .plan-text {
  background-color: transparent;
}

.plans .plans-content .plan.active .plan-text p {
  color: #fff;
}

.plans .plans-content .plan .plan-text span {
  font-size: 1.2rem;
  margin-top: 10px;
  display: block;
}

.plans .plans-content .plan .plan-text p {
  font-size: 0.9rem;
  color: var(--cinza-escuro);
}

.plans .plans-content .plan.active {
  color: #fff;
}

.plans .plans-content .plan,
.plans .plans-content .plan.active {
  padding: 7px;
  border-radius: 5px;
  text-align: center;
}

.plans .plans-content .plan.active {
  background-image: -moz-linear-gradient( -151deg, rgb(143, 23, 219) 0%, rgb(220, 134, 125) 100%);
  background-image: -webkit-linear-gradient( -151deg, rgb(143, 23, 219) 0%, rgb(220, 134, 125) 100%);
  background-image: -ms-linear-gradient( -151deg, rgb(143, 23, 219) 0%, rgb(220, 134, 125) 100%);
}

.plans div .plan-value {
  font-size: 1.7rem;
  font-weight: 550;
}

.plans div .plan-value sup {
  color: var(--cinza);
}
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj 3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<div >
  <div >
    <h3 >
      É hora de dar engajamento ao seu Instagram com Seguidores Reais.
      <b>Entrega em poucos minutos.</b>
    </h3>

    <div >
      <img src="/src/imgs/others/donthavelikes.png" alt="">
    </div>
  </div>

  <div ></div>

  <div >
    <p id="planValue" ><sup>R$</sup> 3.99</p>
    <a href="#" >
                            Buy
                        </a>
  </div>
</div>

  • Related