Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 106 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ With this extension, you can:

![(null) 2022-04-27 at 2 24 48 PM](https://user-images.githubusercontent.com/32713913/165585127-ebfc4740-552b-4bdc-a677-b87c0e9b3ac0.jpg)


## How to Add to Your Theme

1. Add an `countdown-trellis.liquid` file to the `sections` directory and copy in the file's code from this repo.
Expand Down Expand Up @@ -301,3 +300,109 @@ With this extension, you can:

![On A Mission Skincare _ Product metafield definitions _ Edit countdown _ Shopify 2022-04-27 at 2 43 42 PM](https://user-images.githubusercontent.com/32713913/165587600-0854f953-b134-412a-849b-480d62f56731.jpg)

## How to add multiple countdown timers on your Product Listing Page

1. If you have not already done so, please follow steps 1 to 3 from "How to add to your theme".

2. After adding the neccessary files, in sections > main-collection-product-grid.liquid, add the following code as a new "block" in the schema:

```
{
"type": "countdown",
"name": "Countdown",
"limit": 1,
"settings": [
{
"type": "select",
"id": "countdown_style",
"options": [
{
"value": "banner",
"label": "Banner"
},
{
"value": "text",
"label": "Text"
}
],
"default": "banner",
"label": "CountDown Style"
},
{
"type": "color",
"id": "bkg_color",
"label": "Background Color",
"default": "transparent"
},
{
"type": "color",
"id": "content_color",
"label": "Content Color",
"default": "#000000"
},
{
"type": "text",
"id": "title",
"label": "Title",
"default": "ON SALE for"
},
{
"type": "richtext",
"id": "expired_text",
"label": "Text to display when the countdown finishes.",
"default": "<p>Countdown Finished!</p>"
},
{
"type": "color",
"id": "countdown_content_color",
"label": "Countdown Text Color",
"default": "#000000"
},
{
"type": "checkbox",
"id": "show_days",
"label": "Show Days",
"default": true
},
{
"type": "checkbox",
"id": "show_hours",
"label": "Show Hours",
"default": true
},
{
"type": "checkbox",
"id": "show_minutes",
"label": "Show Minutes",
"default": true
},
{
"type": "checkbox",
"id": "show_seconds",
"label": "Show Seconds",
"default": true
}
]
}
```

3. In sections > main-collection-product-grid.liquid, paste the following code within the grid.

```
{%- for block in section.blocks -%}
{%- case block.type -%}
{%- when 'countdown' -%}
{% liquid
if product.metafields.global.countdown
render 'countdown-trellis',
data: block.settings,
date: product.metafields.global.countdown,
identifier: product.title,
type: 'block'
endif
%}
{%- endcase -%}
{%- endfor -%}
```

4. Add a new product's metafield called 'global.countdown' of type Date and Time to each of the individual products you'd like a countdown timer displayed. If the product's metafield has a value, then the countdown will be displayed for each product on the PLP.
109 changes: 49 additions & 60 deletions snippets/countdown-trellis.liquid
Original file line number Diff line number Diff line change
@@ -1,69 +1,62 @@
{% liquid
if type == 'section'
assign main_container_classes = 'twcss-w-screen twcss-flex twcss-justify-center twcss-items-center twcss-flex-col twcss-max-w-full twcss-section-pt twcss-px-[20px] md:twcss-px-[52px] twcss-pb-[40px] twcss-pt-[30px] md:twcss-pt-[85px]'
assign countdown_wrapper_classes = 'twcss-max-w-[280px] md:twcss-max-w-none twcss-flex twcss-align-center twcss-justify-center sm:twcss-justify-between md:twcss-justify-center twcss-flex-wrap'
assign increment_container_classes = 'twcss-border-[3px] twcss-mb-[55px] md:twcss-mb-0 twcss-min-w-[126px] twcss-min-h-[126px] twcss-px-[18px] twcss-pt-[25px] twcss-pb-[20px] md:twcss-mr-[39px] twcss-relative twcss-opacity-0'
assign increment_text_classes = 'twcss-text-[70px] md:twcss-text-[75px] twcss-leading-none twcss-text-right'
assign increment_label_classes = 'twcss-body20 twcss-pt-[10px] twcss-absolute -twcss-translate-x-1/2 twcss-left-1/2 twcss-bottom-[-43px]'
assign custom_padding = 'padding-top:{{ data.padding_top }}px;padding-bottom:{{ data.padding_bottom }}px'
assign countdown_style = ''
elsif type == 'block'
assign main_container_classes = 'countdown-pdp-block'
assign countdown_wrapper_classes = 'twcss-flex'
assign increment_container_classes = 'twcss-flex'
assign increment_text_classes = ''
assign increment_label_classes = ''
assign custom_padding = ''
assign countdown_style = 'twcss-px-[10px] twcss-py-[5px] twcss-justify-center'
if data.countdown_style == 'text'
assign countdown_style = ''
if type == 'section'
assign main_container_classes = 'twcss-w-screen twcss-flex twcss-justify-center twcss-items-center twcss-flex-col twcss-max-w-full twcss-section-pt twcss-px-[20px] md:twcss-px-[52px] twcss-pb-[40px] twcss-pt-[30px] md:twcss-pt-[85px]'
assign countdown_wrapper_classes = 'twcss-max-w-[280px] md:twcss-max-w-none twcss-flex twcss-align-center twcss-justify-center sm:twcss-justify-between md:twcss-justify-center twcss-flex-wrap'
assign increment_container_classes = 'twcss-border-[3px] twcss-mb-[55px] md:twcss-mb-0 twcss-min-w-[126px] twcss-min-h-[126px] twcss-px-[18px] twcss-pt-[25px] twcss-pb-[20px] md:twcss-mr-[39px] twcss-relative twcss-opacity-0'
assign increment_text_classes = 'twcss-text-[70px] md:twcss-text-[75px] twcss-leading-none twcss-w-[84px] twcss-text-right'
assign increment_label_classes = 'twcss-body20 twcss-pt-[10px] twcss-absolute -twcss-translate-x-1/2 twcss-left-1/2 twcss-bottom-[-43px]'
elsif type == 'block'
assign main_container_classes = ''
assign countdown_wrapper_classes = 'twcss-flex twcss-justify-center twcss-py-2'
assign increment_container_classes = 'twcss-flex'
assign increment_text_classes = ''
assign increment_label_classes = ''
endif
endif

if data.date
assign date = data.date
endif
%}

<div class="{{ main_container_classes }}" id="countdown-content" style="background-color: {{ data.bkg_color }};{{ custom_padding }}">
<div class="{{ main_container_classes }}" style="background-color: {{ data.bkg_color }} ">
{% if type == 'section' %}
{% if data.title != blank %}
<h2 class="twcss-text-center twcss-text-[65px] md:twcss-text-[75px] twcss-leading-0 twcss-pb-[30px]" style="color: {{ data.content_color }}">
{{ data.title }}
</h2>
{% endif %}
{% endif %}
{% if data.description != blank %}
<div class="twcss-text-center twcss-pb-[30px] twcss-mx-auto twcss-max-w-screen-xlg md:twcss-px-[10%]" style="color: {{ data.content_color }}">
{{ data.description }}
</div>
{% endif %}
{% endif %}

<div id="countdown-wrapper" class="{{ countdown_wrapper_classes }} {{ countdown_style }}">
<div id="countdown-wrapper-{{ identifier | split: ' ' | join: '' }}" class="{{ countdown_wrapper_classes }}">
{% if type == 'block' %}
<span style="color: {{ data.content_color }};">
{{ data.title }}&nbsp;
<span style="color: {{ data.content_color }}; ">
ON SALE for&nbsp;
</span>
{% endif %}
<div id="days" class="{{ increment_container_classes }} {% unless data.show_days %}twcss-hidden{% endunless %}" style="border-color:{{ data.content_color }}">
<div id="days-{{ identifier | split: ' ' | join: '' }}" class="{{ increment_container_classes }} {% unless data.show_days %}twcss-hidden{% endunless %}" style="border-color:{{ data.content_color }}">
<p class="{{ increment_text_classes }}" style="color: {{ data.content_color }}"></p>
<span class="{{ increment_label_classes }}" style="color: {{ data.content_color }}">
{% if type == 'section' %}Days{% else %}&nbsp;Days&nbsp;{% endif %}
</span>
</div>
<div id="hours" class="{{ increment_container_classes }} {% unless data.show_hours %}twcss-hidden{% endunless %}" style="border-color:{{ data.content_color }}">
<div id="hours-{{ identifier | split: ' ' | join: '' }}" class="{{ increment_container_classes }} {% unless data.show_hours %}twcss-hidden{% endunless %}" style="border-color:{{ data.content_color }}">
<p class="{{ increment_text_classes }}" style="color: {{ data.content_color }}"></p>
<span class="{{ increment_label_classes }}" style="color: {{ data.content_color }}">
{% if type == 'section' %}Hours{% else %}:{% endif %}
</span>
</div>
<div id="minutes" class="{{ increment_container_classes }} {% unless data.show_minutes %}twcss-hidden{% endunless %}" style="border-color:{{ data.content_color }}">
</div>
<div id="minutes-{{ identifier | split: ' ' | join: '' }}" class="{{ increment_container_classes }} {% unless data.show_minutes %}twcss-hidden{% endunless %}" style="border-color:{{ data.content_color }}">
<p class="{{ increment_text_classes }}" style="color: {{ data.content_color }}"></p>
<span class="{{ increment_label_classes }}" style="color: {{ data.content_color }}">
{% if type == 'section' %}Minutes{% else %}:{% endif %}
</span>
</div>
<div id="seconds" class="{{ increment_container_classes }} {% unless data.show_seconds %}twcss-hidden{% endunless %}" style="border-color:{{ data.content_color }}">
<div id="seconds-{{ identifier | split: ' ' | join: '' }}" class="{{ increment_container_classes }} {% unless data.show_seconds %}twcss-hidden{% endunless %}" style="border-color:{{ data.content_color }}">
<p class="{{ increment_text_classes }}" style="color: {{ data.content_color }}"></p>
<span class="{{ increment_label_classes }}" style="color: {{ data.content_color }}">
{% if type == 'section' %}Seconds{% endif %}
Expand All @@ -73,56 +66,52 @@
</div>

<script>
// run below function
runme()

// create a function to contain below variables within scope
function runme() {

// Set the date we're counting down to
var countDownDate = new Date("{{ date }}").getTime();
var now = new Date().getTime();
var distance = countDownDate - now;
const countDownElement = document.getElementById("countdown-content")

function hideCounter(){
if(countDownElement.classList.contains('countdown-pdp-block')){
document.getElementById("countdown-content").classList.add('twcss-hidden');
}else{
document.getElementById("countdown-wrapper").innerHTML = '<div class="twcss-h4">{{ data.expired_text }}</div>';
}
}
const countDownDate = new Date("{{ date }}").getTime();
const now = new Date().getTime();
const temp = "{{ identifier | split: ' ' | join: '' }}"
const distance = countDownDate - now

if (distance < 0) {

hideCounter();
document.getElementById(`countdown-wrapper-${temp}`).innerHTML = '<div class="twcss-h4" style="color:{{ data.countdown_content_color }}">{{ data.expired_text }}</div>';

} else {

document.getElementById("days").classList.remove('twcss-opacity-0');
document.getElementById("hours").classList.remove('twcss-opacity-0');
document.getElementById("minutes").classList.remove('twcss-opacity-0');
document.getElementById("seconds").classList.remove('twcss-opacity-0');
document.getElementById(`days-${temp}`).classList.remove('twcss-opacity-0');
document.getElementById(`hours-${temp}`).classList.remove('twcss-opacity-0');
document.getElementById(`minutes-${temp}`).classList.remove('twcss-opacity-0');
document.getElementById(`seconds-${temp}`).classList.remove('twcss-opacity-0');

// Update the count down every 1 second
var x = setInterval(function() {

var now = new Date().getTime();
var distance = countDownDate - now;

// Time calculations for days, hours, minutes and seconds
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
const days = (`${temp}-days`, Math.floor(distance / (1000 * 60 * 60 * 24)))
const hours = (`${temp}-hours`, Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)))
const minutes = (`${temp}-minutes`, Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)))
const seconds = (`${temp}-seconds`, Math.floor((distance % (1000 * 60)) / 1000))


// Display the result in the elements
document.querySelector("#days p").innerHTML = days.toLocaleString('en-US', {minimumIntegerDigits: 2, useGrouping:false});
document.querySelector("#hours p").innerHTML = hours.toLocaleString('en-US', {minimumIntegerDigits: 2, useGrouping:false});
document.querySelector("#minutes p").innerHTML = minutes.toLocaleString('en-US', {minimumIntegerDigits: 2, useGrouping:false});
document.querySelector("#seconds p").innerHTML = seconds.toLocaleString('en-US', {minimumIntegerDigits: 2, useGrouping:false});
document.querySelector(`#days-${temp} p`).innerHTML = days.toLocaleString('en-US', {minimumIntegerDigits: 2, useGrouping:false});
document.querySelector(`#hours-${temp} p`).innerHTML = hours.toLocaleString('en-US', {minimumIntegerDigits: 2, useGrouping:false});
document.querySelector(`#minutes-${temp} p`).innerHTML = minutes.toLocaleString('en-US', {minimumIntegerDigits: 2, useGrouping:false});
document.querySelector(`#seconds-${temp} p`).innerHTML = seconds.toLocaleString('en-US', {minimumIntegerDigits: 2, useGrouping:false});

// If the count down is finished, write some text
if (distance < 0) {
clearInterval(x);
hideCounter();
document.getElementById(`countdown-wrapper-${temp}`).innerHTML = '<div class="twcss-h4" style="color:{{ data.countdown_content_color }}" >{{ data.expired_text }}</div>';
}
}, 1000);

}
</script>
}
</script>