javascriptobject-literalqueryselector

How to select multiple sections to create an object literal with Javascript?


Goal: I'm trying to create an object literal that includes all the information in three different sections so a user can order multiple of multiple items and their order can be saved in session storage and later sent to a server.

My Problem: Other than selecting the parentNode of the order button, which only selects one of the three sections, I can't figure out how to get querySelectorAll to work with a variable that includes all three sections. It always says xVariable(container in this code).querySelectorAll isn't a function, or if it returns an object all the fields are null.

const orderButtons = document.querySelectorAll(".orderButton");
orderButtons.forEach(function(button) {
  button.addEventListener("click", function() {

    const container = document.querySelectorAll(".merch");

    let order = {
      title: container.querySelectorAll(".title").innerText,
      price: container.querySelectorAll(".price").innerText,
      description: container.querySelectorAll(".description").innerText,
      quantity: container.querySelectorAll(".orderQuantity").innerText
    };

    console.log(order);
  });
});
<article class="merchOrderPage">
  <h1>Treadhead and Tank Models, Merch, Books, and More</h1>
  <p>Here you can buy tank model kits, books about tanks and armored vehicles, and merch for our website.</p>

  <div class="row">
    <section id="orderItem1" class="column merch small-12 medium-12 large-4">
      <img src="/images/ShermanEasy8Model.jpg" alt="Model of M4A3E8 Sherman Tank">
      <h2 class="title">US M4A3E8 "Easy 8" Sherman </h2>
      <p class="description">A plastic model of the M4A3E8 "Easy 8" Sherman.</p>
      <p class="price">$29.99</p>
      <button data-minusOrder="easy8" type="button">-</button><span class="orderQuantity" id="Easy8ModelQuantity">0</span><button data-plusOrder="easy8" type="button">+</button>
      <button class="orderButton">Order</button>
    </section>

    <section id="orderItem2" class="column merch small-12 medium-12 large-4">
      <img src="/images/ShermanTanksByDennisOliver.jpg" alt="Book cover of 'Sherman Tanks: US Army, North-Western Europe, 1944 to 1945 by Dennis Oliver'">
      <h2 class="title">Sherman Tanks: US Army, North-Western Europe, 1944-1945</h2>
      <p class="description">This excellent book by Dennis Oliver chronicles the history and service of the Sherman in Europe from 1944-1945.</p>
      <p class="price">$49.99</p>
      <button data-minusOrder="shermanbookoliver" type="button">-</button><span class="orderQuantity" id="ShermanTanksDennisOliverQuantity">0</span><button data-plusOrder="shermanbookoliver" type="button">+</button>
      <button class="orderButton">Order</button>
    </section>

    <section id="orderItem3" class="column merch small-12 medium-12 large-4">
      <img src="/images/Pz.IV T-Shirt.jfif" alt="Black shirt with a white profile of a Panzer IV.">
      <h2 class="title">Panzer IV T-Shirt (Black)</h2>
      <p class="description">A black cotton t-shirt with a solid white outline of a Panzer IV tank on it.</p>
      <p class="price">$19.99</p>
      <button data-minusOrder="pzivshirt" type="button">-</button><span class="orderQuantity" id="PanzerIVShirtQuantity">0</span><button data-plusOrder="pzivshirt" type="button">+</button>
      <button class="orderButton">Order</button>
    </section>
  </div>
</article>


Solution

  • querySelectorAll returns a NodeList, which you need to iterate over. Then, you need just querySelector to find the only element:

        let order = Array.prototype.map.call(container, x => {
          return {
            title: x.querySelector(".title").innerText,
            price: x.querySelector(".price").innerText,
            description: x.querySelector(".description").innerText,
            quantity: x.querySelector(".orderQuantity").innerText
          }
        })