Home > Blockchain >  Get element data-attributes and insert them into the button
Get element data-attributes and insert them into the button

Time:10-21

I want to ensure that when I click on the divs (A, B, C), the link of the button changes and gets the values of the data attributes in the appropriate places. I wrote a small script, but it does not work, and there is still not enough knowledge to understand exactly where I went wrong. Any help would be welcome.

document.getElementById("product").onclick = function() {
  document.getElementById("purchase").href =
    "/?add-to-cart="   this.data-product   
    "&variation_id="   this.data-id   "/";
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="product__items" id="product">

    <div data-id="338" data-product="A" id="uI-1" class="items-uniqueItem">A</div>
    <div data-id="339" data-product="B" id="uI-2" class="items-uniqueItem">B</div>
    <div data-id="340" data-product="C" id="uI-3" class="items-uniqueItem">C</div>

    <div class="product__items---btn">
        <a href="" id="purchase" class="btn">Button</a>
    </div><!-- btn -->

</div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

You have several problems here.

First, I suggest you consult the documentation for HTMLElement.dataset or jQuery's .data().

Also, if you intend on using event delegation, you can't use this to refer to the event source element in a vanilla event listener as it will refer to the delegate.

Since you do have jQuery involved, you might as well use it since it makes this a lot easier (see also vanilla JS version below)

const button = $("#purchase")

$("#product").on("click", ".items-uniqueItem[data-id][data-product]", function() {
  // Due to the selector above, `this` is now the clicked `<div>`
  
  // Extract data properties
  const { product, id } = $(this).data()
  
  // Construct URL parameters
  const params = new URLSearchParams({
    "add-to-cart": product,
    "variation_id": id
  })
  
  // Set the `href`
  button.prop("href", `/?${params}/`)
})
/* this is just for visibility */
.items-uniqueItem{cursor:pointer;}#purchase{display:block;text-decoration:none;margin: 1rem;}#purchase:after{content:attr(href);display:block;color:#ccc;margin:.5rem;}
<!-- your HTML, just minified -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script><div class="product__items" id="product"><div data-id="338" data-product="A" id="uI-1" class="items-uniqueItem">A</div><div data-id="339" data-product="B" id="uI-2" class="items-uniqueItem">B</div><div data-id="340" data-product="C" id="uI-3" class="items-uniqueItem">C</div><div class="product__items---btn"><a href="" id="purchase" class="btn">Button</a></div></div>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>


A vanilla JS version would look something more like this. You can use Element.closest() to locate the delegated event source

const button = document.getElementById("purchase")

document.getElementById("product").addEventListener("click", e => {
  // find the required event source element
  const el = e.target.closest(".items-uniqueItem[data-id][data-product]")
  
  if (el) {
    // Extract data properties
    const { product, id } = el.dataset

    // Construct URL parameters
    const params = new URLSearchParams({
      "add-to-cart": product,
      "variation_id": id
    })

    // Set the `href`
    button.href = `/?${params}/`    
  }
})
.items-uniqueItem{cursor:pointer;}#purchase{display:block;text-decoration:none;margin: 1rem;}#purchase:after{content:attr(href);display:block;color:#ccc;margin:.5rem;}
<!-- your HTML, just minified -->
<div class="product__items" id="product"><div data-id="338" data-product="A" id="uI-1" class="items-uniqueItem">A</div><div data-id="339" data-product="B" id="uI-2" class="items-uniqueItem">B</div><div data-id="340" data-product="C" id="uI-3" class="items-uniqueItem">C</div><div class="product__items---btn"><a href="" id="purchase" class="btn">Button</a></div></div>
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

As you can see, it's not very different to the jQuery version so maybe you might not need jQuery

CodePudding user response:

I've never personally used the element.onlick = function() {...} notation, so I'll be usingelement.addEventListener('click', (e) => ...), but it should work the same way.

What you are doing is selecting the object that has the id "product". But "product" is the parent os the elements you want to select.

If you want to select several elements and do something with them, you can't use the id attribute, since id is unique for html page. So you'll want to use classes for that.

  1. Create a class and add that class to each child (the ones with the data-product).

  2. Select all children with .querySelectorAll(). Here is the doc. This returns a NodeList, but it's similar to an Array.

  3. Iterate thought the List with a .forEach(item => ...) where item represents each element of the list.

  4. Add an Event Listener (or .click, I guess) on each item.

    *theList*.forEach( (item) => {
      item.addEventListener('click', (event) => {
        event.target.href = "/?add-to-cart="   event.target.dataset.product   "&"   "variation_id="   event.target.dataset.id   "/";
      })
    ));
    
  5. To access a dataset in JS you use the .dataset property.

CodePudding user response:

First, grab all the divs that have a given class so that we can use their data.

const items = document.querySelectorAll('.items-uniqueItem');
items.forEach(item => item.addEventListener('click', (e) => console.log(e.target)))

Then inside you click handler you can get the button reference and assign the properties you want to get from it.

  • Related