1

I'm trying to create a FAQ accordion on a classic Google Sites page but unable to determine the best route.

The closest I've got was copying the example in w3schools.com in to an HTML gadget (code below). However, the panel doesn't seem to expand and I don't quite understand the part of the code either.

I've also tried hosting a custom gadget but Google has become very strict on that and couldn't figure out how to host.

Here's a test page with the code: https://sites.google.com/a/cartomark.com/test/

Here's the code:

<style>
button.accordion {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
transition: 0.4s;
}

button.accordion.active, button.accordion:hover {
    background-color: #ddd;
}

button.accordion:after {
    content: '\002B';
    color: #777;
    font-weight: bold;
    float: right;
    margin-left: 5px;
}

button.accordion.active:after {
    content: "\2212";
}

div.panel {
    padding: 0 18px;
    background-color: white;
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.2s ease-out;
}
</style>
<h2>Accordion with symbols</h2>
<p>In this example we have added a "plus" sign to each button. When the user clicks on the button, the "plus" sign is replaced with a "minus" sign.</p>
<button class="accordion">Section 1</button>
<div class="panel">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>

<button class="accordion">Section 2</button>
<div class="panel">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>

<button class="accordion">Section 3</button>
<div class="panel">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>

<script>
var acc = document.getElementsByClassName("accordion");
var i;

for (i = 0; i < acc.length; i++) {
  acc[i].onclick = function() {
    this.classList.toggle("active");
    var panel = this.nextElementSibling;
    if (panel.style.maxHeight){
      panel.style.maxHeight = null;
    } else {
      panel.style.maxHeight = panel.scrollHeight + "px";
    } 
  }
}
</script>
Tony Leary
  • 13
  • 8

1 Answers1

1

Short answer

Use an HTML Box gadget or create a Google Apps Script web app and insert it as gadget.

Explanation

HTML Box gadget

One alternative is to use the HTML Box gadget to insert your HTML/CSS/JavaScript code into a Google Sites page. One advantage of this alternative is that the height will be adjusted as to the content automatically.

For details see Create custom page layouts or gadgets, but bear in mind that not all works the same way as it does on other places. In this specific case, it looks that HTML Box doesn't support nextElementSibling. A workaround for this is to replace

var panel = this.nextElementSibling;

by

var panel = nextElementSibling(this);

or

var panel = this.nextElementSibling || nextElementSibling(this);

and add at the end add

function nextElementSibling( el ) {
    do { el = el.nextSibling } while ( el && el.nodeType !== 1 );
    return el;
}

I took this idea from the answer by user113716 to Portability of nextElementSibling/nextSibling

NOTE: I posted a question on the official Google Sites Help Forum asking why this.nextElementSibling returns null.

Screenshots

Three accordions collapsed on a Google Sites page

The second of three accordions expanded on a Google Sites page

Code

<style>
  button.accordion {
    background-color: #eee;
    color: #444;
    cursor: pointer;
    padding: 18px;
    width: 100%;
    border: none;
    text-align: left;
    outline: none;
    font-size: 15px;
    transition: 0.4s;
  }
  
  button.accordion.active,
  button.accordion:hover {
    background-color: #ddd;
  }
  
  button.accordion:after {
    content: '\002B';
    color: #777;
    font-weight: bold;
    float: right;
    margin-left: 5px;
  }
  
  button.accordion.active:after {
    content: "\2212";
  }
  
  div.panel {
    padding: 0 18px;
    background-color: white;
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.2s ease-out;
  }
</style>

<h2>Accordion with symbols</h2>
<p>In this example we have added a "plus" sign to each button. When the user clicks on the button, the "plus" sign is replaced with a "minus" sign.</p>
<button id="button_1" class="accordion">Section 1</button>
<div class="panel">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>

<button id="button_2" class="accordion">Section 2</button>
<div class="panel">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>

<button id="button_3" class="accordion">Section 3</button>
<div class="panel">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>

<script>
  var acc = document.getElementsByClassName("accordion");
  var i;

  for (i = 0; i < acc.length; i++) {
    acc[i].onclick = function() {
      this.classList.toggle("active");
      var panel = this.nextElementSibling || nextElementSibling(this);
      if (panel.style.maxHeight) {
        panel.style.maxHeight = null;
      } else {
        panel.style.maxHeight = panel.scrollHeight + "px";
      }
    }
  }


  function nextElementSibling(el) {
    do {
      el = el.nextSibling
    } while (el && el.nodeType !== 1);
    return el;
  }
</script>

Google Apps Script web app

The other alternative is to create a Google Apps Script web application, the insert it as a Google Apps Script gadget. The "problem" with this alternative is that its height is static. The gadget has the option to show a vertical scrollbar when it be required. For broad steps about how to do this see my answer to Invoke app scripts with parameters from classic google site

Rubén
  • 34,714
  • 9
  • 70
  • 166
  • Thanks for trying it out. I did use the HTML Box gadget. Do your panels expand? I've got the same result as yours but the panels height do not change. Example: https://sites.google.com/a/cartomark.com/test/ – Tony Leary Jun 20 '17 at 12:55
  • No, my panels don't expand. I think that the problem is due to [Caja](https://developers.google.com/caja/). One alternative is to create a Google Apps Script web app and insert it as a Google Sites gadget but the problem with this is that the height doesn't grow/shrink dynamically so you should set the height on the gadget settings – Rubén Jun 20 '17 at 14:57
  • Ok thanks. I haven't had any luck hosting a gadget either. I tried to host the xml file from Drive and Dropbox and neither worked. I really wish the customer didn't insist on Google Sites :) – Tony Leary Jun 20 '17 at 19:17
  • If you and your customer could be patients I think that I could help you with broad overall guidance to get an Google Apps Script web app work (I'm wondering if I was too redundant,hehe ). I already make a gadget that use use bootstrap's Toggleable / Dynamic Pills on a demo for client of my own but should solve other thing first. – Rubén Jun 20 '17 at 19:23