Product Dropdown Text

Written by Paul Richard Lewis

2023-12-15

TL;DR

You can paste the below code into a new section, which I've named product-info-dropdown.liquid. You'll then need to render this within your main-product.liquid page.

Introduction

Perhaps you aren't looking to have all of your product information available to the customer, but rather want to present information in bite-size chunks. You can do that by adding a show / hide button (giving the appearance of a text reveal upon button click). Examples of sections that can be useful encapsulate within this functionality are fields like 'Shipping', 'Returns' or 'Materials'.

Step-By-Step

1. Navigate to your Shopify store admin page

There you'll want to navigate to custom data via settings, and select products and then 'add definition' (settings -> custom data -> products -> add definition).

2. Create relevant definitions

If you're wanting to create a 'Shipping' dropdown text-box then you'll want to create a definition called shipping, but you can obviously create or call it whatever you wish. The important part of this is remembering the metafield definition path and rename it. If you entered Shipping, then by default it will look like this custom.shipping. I would be inclined to rename the custom part to something meaningful, for instance product_info. So you'll have product_info.shippin if you've done as I've done.

Add as many fields as you like, just remember the path for each - you can always return if you forget.

3. Head to the code editor

Once you're in your code editor (which you can access via your theme editor or your store admin page) you'll see file or directory names on the left-hand-side. We're going to create a new file called product-info-dropdown.liquid, and then paste in the following code.

html
{% comment %}
Accepts:
- content: whatever content is passed in
- button_name: the name of the button dropdown
{% endcomment %}
<button class="btn btn-{{button_name | remove: " " | downcase }}">
<span class="btn_name">{{button_name}}</span>
<div class="icon-show">+</div>
<div class="icon-hide hide">-</div>
</button>
<div class="content-container hide">
{{ content | metafield_tag }}
</div>

The top part of this code is just a comment that is for readability. This means that we are accepting two parameters (essentially, data that we're passing in - I'll show you where a bit later): that is, content and the button_name.

Below that we have the actual html with some liquid mixed in. You'll note that where the content is placed that we have a metafield_tag function. This allows for the use of rich text.

CSS
<style>
.btn {
border: none;
width: 100%;
border-radius: 20px;
text-align: left;
font-size: 1em;
padding: 0.5em 2em;
transition: all 0.3s ease;
display: flex;
justify-content: space-between;
align-items: center;
}
.btn:hover {
cursor: pointer;
background-color: gray;
}
.icon-hide, .icon-show {
font-size: 1.2em;
}
.content-container {
display: block;
padding-left: 1em;
}
.hide {
display: none;
}
</style>

The above part is for styling, that is to make the button look nice and also specify the classes that will hide and display our text (in this case the hide class).

JavaScript
<script>
const toggleContent = (event) => {
const button = event.currentTarget;
const showIcon = button.querySelector(".icon-show");
const hideIcon = button.querySelector(".icon-hide");
const content = button.nextElementSibling;
content.classList.toggle("hide");
showIcon.classList.toggle("hide");
hideIcon.classList.toggle("hide");
}
document.addEventListener("DOMContentLoaded", () => {
const buttons = document.querySelectorAll(".btn")
buttons.forEach((button) => {
button.removeEventListener("click", toggleContent);
button.addEventListener("click", toggleContent);
})
});
</script>

This last part of the puzzle makes the dropdown work, by adding an event listener to each button, so that when it's clicked it will display or hide the content.

In sum, make sure that you paste each of those code segments one below the other (the order doesn't matter, but by convention liquid / html is normally up top).

4. Now head to the main-product.liquid page

Although you can place these product-info dropdown text boxes wherever you like, I'm going to place them below the description area of the product page. In order to do that, on the main-product page search for (control + f) 'description'. In my editor this occurs, on the 174th line, but this may be different for you. You'll probably notice the line {%- if product.description != blank -%} and below that there will be an endif. Clear some space after the endif and we'll insert some more code:

liquid
{% render 'product-info-dropdown', content: product.metafields.product_info.shipping, button_name: "Shipping" %}
{% render 'product-info-dropdown', content: product.metafields.product_info.payment_methods, button_name: "Payment
Methods" %}

The above code is first rendering our product-info-dropdown snippet that we just created, and it's passing in two variables. The first one is content which we're assigning the value, in our case shipping, from our metafield. Product metafields always start with product.metafields, and then your custom path. So, if you labeled your metafield path superduperdropdown.shipping then that's what you'll need to insert after product.metafields.

Obviously, the above example is rendering two instances of our 'product-info-dropdown' but you can render as many as you like, or just one (depending on how many metafields you want to display).

Don't for get to save and test your work.

5. Test it out

Back in your store admin page if you navigate to a product you'll notice your metafields down the bottom. Paste some dummy information in there from another website (as this will be Rich text) and then head back over to your theme preview and navigate to that particular product.

You should now be able to hide / reveal the text content.

Summary

So, today we have created product metafields and enabled text dropdowns for a product page that reveals the containing information.

If you need any further help, please reach out.

Inspired by others built by me.