Custom accordion collapsible content

Hi

I’m trying to add an accordion/collapsible section to product pages, I followed a

YouTube tutorial and have managed to get the accordions to appear on the product page, but there is content is empty on all except the details (which is not formatted properly).

Have I missed something???

This is the code i used:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

/* Accordion CSS Code by WebSensePro.com 
https://websensepro.com/blog/how-to-create-collapsible-accordion-for-product-description-shopify/
*/
.accordion {
	 margin: 1rem 0;
	 padding: 0;
	 list-style: none;
	 border-top: 1px solid #e5e5e5;
}
 .accordion-item {
	 border-bottom: 1px solid #e5e5e5;
   list-style: none !important; 
}
/* Thumb */
 .accordion-thumb {
	 margin: 0;
	 padding: 0.8rem 0;
	 cursor: pointer;
	 font-weight: normal;
}
 .accordion-thumb::before {
	 content: '';
	 display: inline-block;
	 height: 7px;
	 width: 7px;
	 margin-right: 1rem;
	 margin-left: 0.5rem;
	 vertical-align: middle;
	 border-right: 1px solid;
	 border-bottom: 1px solid;
	 transform: rotate(-45deg);
	 transition: transform 0.2s ease-out;
}
/* Panel */
 .accordion-panel {
	 margin: 0;
	 padding-bottom: 0.8rem;
	 display: none;
}
/* Active */
 .accordion-item.is-active .accordion-thumb::before {
	 transform: rotate(45deg);
}

// Accordion by WebSensePro.com
$(function() {
	// (Optional) Active an item if it has the class "is-active"	
	$(".accordion > .accordion-item.is-active").children(".accordion-panel").slideDown();
	
	$(".accordion > .accordion-item").click(function() {
		// Cancel the siblings
		$(this).siblings(".accordion-item").removeClass("is-active").children(".accordion-panel").slideUp();
		// Toggle the item
		$(this).toggleClass("is-active").children(".accordion-panel").slideToggle("ease-out");
	});
});

<ul class="accordion">
<li class="accordion-item is-active">
<h3 class="accordion-thumb">{{ product.metafields.my_fields.first_tab_title }}</h3>
<p class="accordion-panel">{{ product.metafields.my_fields.first_tab_description }}</p>
</li>
<li class="accordion-item">
<h3 class="accordion-thumb">{{ product.metafields.my_fields.second_tab_title }}</h3>
<p class="accordion-panel">{{ product.metafields.my_fields.second_tab_description }}</p>
</li>
<li class="accordion-item">
<h3 class="accordion-thumb">{{ product.metafields.my_fields.third_tab_title }}</h3>
<p class="accordion-panel">{{ product.metafields.my_fields.third_tab_description }}</p>
</li>
</ul>

Hi @needhelp8,

What theme are you using? Because if you just add a collapsible accordion and use the jQuery library, it won’t be really good.

You can refer to the following JavaScript code, it will work better:

<style>
.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;
}

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

.panel {
  padding: 0 18px;
  display: none;
  background-color: white;
  overflow: hidden;
}
</style>
<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>
const accordions = document.querySelectorAll('.accordion');

accordions.forEach(acc => {
  acc.addEventListener('click', () => {
    acc.classList.toggle('active');

    const panel = acc.nextElementSibling;
    const isOpen = panel.style.display === 'block';

    panel.style.display = isOpen ? 'none' : 'block';
  });
});
</script>

Thanks. That creates the collapsible accordion, but how do I then link to the metafields for each section to fill with the correct information?

Hi @needhelp8,

It will need to be changed back and schema code added to be able to display it. This will require creating a section file instead of using a Custom Liquid section.

You can refer to the following code:

<style>
.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;
}

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

.panel {
  padding: 0 18px;
  display: none;
  background-color: white;
  overflow: hidden;
}
</style>
<div id="Accordion--{{ section.id }}">
  {%- for block in section.blocks -%}
    <button class="accordion">{{ block.settings.heading }}</button>
    <div class="panel">
      {{ block.settings.text }}
    </div>
  {%- endfor -%}
</div>

<script>
const content = document.querySelector('#Accordion--{{ section.id }}');
const accordions = content.querySelectorAll('.accordion');

accordions.forEach(acc => {
  acc.addEventListener('click', () => {
    acc.classList.toggle('active');

    const panel = acc.nextElementSibling;
    const isOpen = panel.style.display === 'block';

    panel.style.display = isOpen ? 'none' : 'block';
  });
});
</script>

{% schema %}
{
  "name": "Accordion",
  "class": "section",
  "blocks": [
    {
      "type": "accordion",
      "name": "Accordion",
      "settings": [
        {
          "type": "inline_richtext",
          "id": "heading",
          "default": "Heading",
          "label": "Heading"
        },
        {
          "type": "richtext",
          "id": "text",
          "label": "Content"
        }
      ]
    }
  ],
  "presets": [
    {
      "name": "Accordion",
      "blocks": [
        {
          "type": "accordion"
        },
        {
          "type": "accordion"
        },
        {
          "type": "accordion"
        }
      ]
    }
  ]
}
{% endschema %}

Hi @needhelp8

Try this code.

<!-- jQuery (needed for accordion) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

<style>
/* Accordion Styles */
.accordion {
  margin: 1rem 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid #e5e5e5;
}
.accordion-item {
  border-bottom: 1px solid #e5e5e5;
  list-style: none !important;
}
.accordion-thumb {
  margin: 0;
  padding: 0.8rem 0;
  cursor: pointer;
  font-weight: normal;
}
.accordion-thumb::before {
  content: '';
  display: inline-block;
  height: 7px;
  width: 7px;
  margin-right: 1rem;
  margin-left: 0.5rem;
  vertical-align: middle;
  border-right: 1px solid;
  border-bottom: 1px solid;
  transform: rotate(-45deg);
  transition: transform 0.2s ease-out;
}
.accordion-panel {
  margin: 0;
  padding-bottom: 0.8rem;
  display: none;
}
.accordion-item.is-active .accordion-thumb::before {
  transform: rotate(45deg);
}
</style>

<script>
$(function() {
  // Open default active panel
  $(".accordion > .accordion-item.is-active").children(".accordion-panel").slideDown();

  $(".accordion > .accordion-item").click(function() {
    $(this).siblings(".accordion-item")
      .removeClass("is-active")
      .children(".accordion-panel").slideUp();

    $(this).toggleClass("is-active")
      .children(".accordion-panel").slideToggle("ease-out");
  });
});
</script>

<!-- Accordion HTML -->
<ul class="accordion">
  {% if product.metafields.my_fields.first_tab_title.value %}
    <li class="accordion-item is-active">
      <h3 class="accordion-thumb">{{ product.metafields.my_fields.first_tab_title.value }}</h3>
      <div class="accordion-panel">
        {{ product.metafields.my_fields.first_tab_description | metafield_tag }}
      </div>
    </li>
  {% endif %}

  {% if product.metafields.my_fields.second_tab_title.value %}
    <li class="accordion-item">
      <h3 class="accordion-thumb">{{ product.metafields.my_fields.second_tab_title.value }}</h3>
      <div class="accordion-panel">
        {{ product.metafields.my_fields.second_tab_description | metafield_tag }}
      </div>
    </li>
  {% endif %}

  {% if product.metafields.my_fields.third_tab_title.value %}
    <li class="accordion-item">
      <h3 class="accordion-thumb">{{ product.metafields.my_fields.third_tab_title.value }}</h3>
      <div class="accordion-panel">
        {{ product.metafields.my_fields.third_tab_description | metafield_tag }}
      </div>
    </li>
  {% endif %}
</ul>