0

Objective: Have multiple "Full Product Specifications" buttons that need to toggle the visibility of their respective Product Specification Tables. Initially, set all Product Specification tables to NOT display, then use the buttons to control. Cant use jQuery because ... reasons/stupid old website I don't have full control over...

I'm trying to use an anonymous JavaScript Function, but I'm unsure how to pass in my table? Or if I even can? My JS is not that great...

With jQuery I could probably just use .click() and .closest(). Unsure how to translate into pure JavaScript, so this is what I have instead.

The error...

Uncaught TypeError: Cannot set property 'display' of undefined at HTMLButtonElement.y.(anonymous function).onclick

And the code...

var x = document.getElementsByClassName("pdp-full-specs-table");
console.log("There are " + x.length + " tables");
for(i = 0; i < x.length; i++){
    x[i].style.display = "none";
}

var y = document.getElementsByClassName("pdp-full-specs-toggle");
console.log("There are " + y.length + " toggles");
for(i = 0; i < y.length; i++){

    var pdpTable = x[i];
    y[i].onclick = function(pdpTable){

        // Make this a toggle later
        pdpTable.style.display = "table";
    }
}

And the HTML in case that helps anyone

<button type="button" class="btn btn-link pdp-full-specs-toggle">Full Specifications &rsaquo;</button><br>
<table class="pdp-full-specs-table">
    <tr>
        <td>Product Size</td>
            <td>some size</td>
    </tr>
</table>
Sanfly
  • 1,021
  • 1
  • 11
  • 19

1 Answers1

0

A simple, efficient solution is just to store the index of each element on the element itself so that when the handler is invoked, you can reference it via the this reference to the element.

for(var i = 0; i < y.length; i++){
    y[i].__table__ = i;
    y[i].onclick = buttonHandler;
}

function buttonHandler() {
    x[this.__table__].style.display = "table";
}

Some may use closures and such to accomplish this, but there's no need to be so complicated.

If each button comes just before each table, then you could do this.nextElementSibling to get to the table, but that won't work in IE8 and lower.

  • Thanks, I ended up using the this.nextElementSibling. Only 0.6% of my website visitors are using IE8 or lower, so I'm happy with that! – Sanfly Dec 17 '17 at 01:10
  • Very good. That's definitely the simplest solution if you can get away with it. –  Dec 17 '17 at 01:11