0

I'm trying to create a JS collapsible with Show All / Hide all additional options. My code seems to work fine in all browsers apart from the Show all / Hide all buttons in IE. I've tried various things (though I'm novice to JS) but none makes a difference in IE. Could someone please help? Solution needs to be combination of JS, HTML, CSS as these are the only ones I can add in our interface.

  var coll = document.getElementsByClassName("accordion");
var i;

for (i = 0; i < coll.length; i++) {
  coll[i].addEventListener("click", function() {
    var content = this.nextElementSibling;
    if (content.style.display === "table-row") {
      content.style.display = "none";
      this.firstElementChild.firstChild.style.transform = "rotate(-45deg)";
    } else {
      content.style.display = "table-row";
      this.firstElementChild.firstChild.style.transform = "rotate(45deg)";
    }
  });
} 

  function showexplanation() {
    document.querySelectorAll('.accordion-content').forEach(item => {
      item.style.display = "table-row";
    })
    document.querySelectorAll('.arrow-right').forEach(item => {
      item.style.transform = "rotate(45deg)";
    })
  }

function hideAll() {
  document.querySelectorAll('.accordion-content').forEach(item => {
    item.style.display = "none";
  })
  document.querySelectorAll('.arrow-right').forEach(item => {
    item.style.transform = "rotate(-45deg)";
  })
} 
.accordion {
  background-color: #777;
  color: white;
  cursor: pointer;
  padding: 10px;
  width: 100%;
  border: none;
  text-align: left;
  outline: none;
  font-size: 15px;
}

.accordion td {
  padding: 15px;
}

.accordion td:nth-child(1) {
  min-width: 40px;
  text-align: center;
}

.accordion td:nth-child(2) {
  padding-left: 0px;
}

.accordion-content {
  padding: 25px;
  overflow: hidden;
  background-color: #f1f1f1;
  display: none;
}

.accordion-content td {
  padding: 15px;
}

.arrow-right {
  border: solid white;
  border-width: 0 1.5px 1.5px 0;
  display: inline-block;
  padding: 3px;
  transform: rotate(-45deg);
  transition: all 200ms ease 0s;
}
<table style="max-width: 700px;" border="0" cellspacing="0">
  <tbody>
    <tr class="accordion">
      <td style="width: 1%"><i class="arrow-right"></i></td>
      <td>Item 1</td>
      <td style="text-align: right;">£1,800</td>
    </tr>
    <tr class="accordion-content">
      <td colspan="3">
        <p>Explanation 1</p>
      </td>
    </tr>

    <tr class="accordion">
      <td style="width: 1%"><i class="arrow-right"></i></td>
      <td>Item 3</td>
      <td style="text-align: right;">£1,750</td>
    </tr>
    <tr class="accordion-content">
      <td colspan="3">
        <p>Explanation 3</p>
      </td>
    </tr>
    <tr class="accordion">
      <td style="width: 1%"><i class="arrow-right"></i></td>
      <td>Item 3</td>
      <td style="text-align: right;">£1,750</td>
    </tr>
    <tr class="accordion-content">
      <td colspan="3">
        <p>Explanation 3</p>
      </td>
    </tr>
  </tbody>
</table>
<p style="margin-top: 20px;">
  <button onclick="showexplanation()">Show all</button>
</p>
<p style="margin-top: 20px;" id="solution">
  <button onclick="hideAll()">Hide all</button>
</p>
novice
  • 5
  • 1
  • Arrow functions don't work in IE. – VLAZ Jun 09 '20 at 14:37
  • 1
    Does this answer your question? [Why doesn't this arrow function work in IE 11?](https://stackoverflow.com/questions/40216015/why-doesnt-this-arrow-function-work-in-ie-11) – VLAZ Jun 09 '20 at 14:37
  • Also relevant: [Syntax error in IE using ES6 arrow functions](https://stackoverflow.com/questions/40110022/syntax-error-in-ie-using-es6-arrow-functions/) – VLAZ Jun 09 '20 at 14:38
  • Also another issue you have: [forEach on querySelectorAll not working in recent Microsoft browsers](https://stackoverflow.com/questions/46929157/foreach-on-queryselectorall-not-working-in-recent-microsoft-browsers) – VLAZ Jun 09 '20 at 14:40

2 Answers2

0

Like the comments already mention, IE has horrible ES6/html5 support. A solution could be to use polyfills like babel.

Another solution would be to use only functions that IE supports, you can check if a function is supported by using caniuse

Lastly, you could drop IE support as IE is hardly used anymore, but this depends on your intended audience of course.

Douwe
  • 557
  • 7
  • 16
  • "*IE has horrible ES6/html5 support*" it **doesn't** have ES6 support. The closest it has is that it recognises `const` and `let` but only in as much that it doesn't throw errors. It merely treats them as aliases to `var`. – VLAZ Jun 09 '20 at 14:57
  • Please don't answer duplicate questions. We try our best to [keep all the good content in one place](https://stackoverflow.com/help/duplicates). You can always answer the proposed duplicate if you think you have additional useful information that isn't available there. – Ivar Jun 09 '20 at 15:03
  • @Ivar There is no duplicate flag? Also, while it might be obvious to you and me that this question can be generalized to be about browser support, for a novice this doesn't have to be apparent at all. Way too many questions are branded duplicate just because the _answer_ is the same, while the questions differ greatly. This is terribly confusing for novice programmers. – Douwe Jun 09 '20 at 15:43
  • @Douwe I'm not sure what you mean with "_There is no duplicate flag?_". You can flag questions as duplicate with the flag button under the question. There are currently 2 votes on it. (Although you can't see those without the close vote privilege.) If you mark a question as duplicate, the OP will also have access to that link and use that answer. I don't see any issues there. – Ivar Jun 09 '20 at 15:53
  • @Ivar I mean that there is nothing telling me that this question is being voted on for being a duplicate. So asking me not to answer because of that seems strange. And I am not at all convinced that it _is_ a duplicate, because OP asked a very specific question about a very specific piece of code. Again, if it's a duplicate because the _anwser_ is the same as for all questions asking about browser support than it shouldn't be a duplicate imho. Because that requires that OP understands the context in which their question was generalized, and that is certainly an issue (for educators at least) – Douwe Jun 09 '20 at 16:15
  • When you flag/vote to close a question as duplicate, the system automatically inserts a comment with "_Does this answer your question?_" with a link to the question after it. That is how you can tell that it is in the process of being closed. If OP doesn't understand the duplicate, they have the possibility to update their question to explain why it didn't/what they don't understand and then it can be reopened again. But having the same answer slightly different spelled out 100 times doesn't help in our goal to be a library of high-quality, up-to-date questions and answers. – Ivar Jun 09 '20 at 16:28
0

IE doesn't support arrow function and forEach for HTMLCollection.

You could add the following polyfill in your script to polyfill forEach then it can be used for both NodeList and HTMLCollection in IE:

//polyfill
var ctors = [typeof NodeList !== "undefined" && NodeList, typeof HTMLCollection !== "undefined" && HTMLCollection];
for (var n = 0; n < ctors.length; ++n) {
    var ctor = ctors[n];
    if (ctor && ctor.prototype && !ctor.prototype.forEach) {
        // (Yes, there's really no need for `Object.defineProperty` when doing the `forEach`)
        ctor.prototype.forEach = Array.prototype.forEach;
        if (typeof Symbol !== "undefined" && Symbol.iterator && !ctor.prototype[Symbol.iterator]) {
            Object.defineProperty(ctor.prototype, Symbol.iterator, {
                value: Array.prototype[Symbol.itereator],
                writable: true,
                configurable: true
            });
        }
    }
}

Besides, you should transpile the arrow functions in your code by editing the two functions in your script like below:

function showexplanation() {
    document.querySelectorAll('.accordion-content').forEach(function (item) {
        item.style.display = "table-row";
    });
    document.querySelectorAll('.arrow-right').forEach(function (item) {
        item.style.transform = "rotate(45deg)";
    });
}

function hideAll() {
    document.querySelectorAll('.accordion-content').forEach(function (item) {
        item.style.display = "none";
    });
    document.querySelectorAll('.arrow-right').forEach(function (item) {
        item.style.transform = "rotate(-45deg)";
    });
}
Yu Zhou
  • 11,532
  • 1
  • 8
  • 22