Remove items from customer cart when a product offer ends - shopify

I'm not a developer, I started coding for fun a couple of weeks ago, so please be patient with me :)
I'm trying to customise something in my shopify shop (dawn theme).
I am creating some limited time products offers with a countdown timer in the product page.
When the timer hits 0, the add to cart button in the product page is removed, and the item can't be added to the cart anymore.
I found this countdown timer online and edited it to my needs. Once the time ends, the timer disappears and it's replaced by some text.
The code of the countdown timer is the following:
{% assign nowDateSec = 'now' | date: '%s' %}
{% assign modDateSec = countdown_timer_date | date: '%s' %}
{% if nowDateSec > modDateSec %}
<center>
<b
style="
font-size: x-large;
color: red;
"
>
The offer has ended.</b
>
</center>
{% else %}
{% if end_date != blank %}
<div class="timer">
{% if title != blank %}
<h4 class="timer__title">{{ title }}</h4>
{% endif %}
<div class="timer-display">
<div class="timer-block">
<span class="timer-block__num js-timer-days">00</span>
<span class="timer-block__unit">Giorni</span>
</div>
<div class="timer-block">
<span class="timer-block__num js-timer-hours">00</span>
<span class="timer-block__unit">Ore</span>
</div>
<div class="timer-block">
<span class="timer-block__num js-timer-minutes">00</span>
<span class="timer-block__unit">Minuti</span>
</div>
<div class="timer-block">
<span class="timer-block__num js-timer-seconds">00</span>
<span class="timer-block__unit">Secondi</span>
</div>
</div>
</div>
{% endif %}
<style>
/* styles for timer */
.timer {
font-size: x-large;
background: #FFFFFF;
padding: 5px;
margin: 5px 0;
}
.timer--expired {
display: none;
}
.timer__title {
#extend .paragraph;
text-align: center;
font-size: large;
}
.timer-display {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
-webkit-box-pack: justify;
-ms-flex-pack: justify;
justify-content: space-between;
margin-top: 5px;
}
.timer-block {
position: relative;
width: 25%;
padding: 0 10px;
&:not(:last-child):after {
content: ':';
position: absolute;
right: 0;
top: 3px;
}
}
.timer-block__num,
.timer-block__unit {
display: block;
text-align: center;
}
</style>
<script type="text/javascript">
var second = 1000,
minute = second * 60,
hour = minute * 60,
day = hour * 24;
var countDown = new Date('{{- end_date -}}').getTime(),
x = setInterval(function() {
var now = new Date().getTime(),
distance = countDown - now;
document.querySelector('.js-timer-days').innerText = Math.floor(distance / (day)),
document.querySelector('.js-timer-hours').innerText = Math.floor((distance % (day)) / (hour)),
document.querySelector('.js-timer-minutes').innerText = Math.floor((distance % (hour)) / (minute)),
document.querySelector('.js-timer-seconds').innerText = Math.floor((distance % (minute)) / second);
}, second)
</script>
{% endif %}
I have included the timer in my product page just below the add to cart button using the below code:
{% assign countdown_timer_boolean = product.metafields.custom.countdown_timer %}
{% assign countdown_timer_date = product.metafields.custom.countdown_timer_date %}
{% if countdown_timer_boolean == true %}
{% include 'shopify-countdown-timer',
title: "The offer will end in:",
end_date: countdown_timer_date
%}
{% endif %}
"countdown_timer_boolean" and "countdown_timer_date" are two metafields I have created for the product: the first one is a simple boolean to select which products will be on limited offer and which ones are regular, with the second I can set the date when the offer ends.
(I am sure there are multiple better solution for this, but again I'm a total novice and it's working, so I'm quite happy like this.)
The problem is that the product can still be bought by the customer if it has been added to the cart before the end of the offer, as it stays there up to 10 days.
I tried to play with the code in order to automatically delete the items in the cart when the offer has ended, but with no success. I've spent the last 3 days trying, and I've run out of ideas on how to do this.
I tried to set the item quantity of the product in the cart to 0 when the timer ends, but nothing happens. The quantity stays the same.
I tried to change the max quantity of the item to 0 but, like in the example above, it doesn't work.
Unfortunately I deleted the code because it didn't work, but it looked something like this:
{% assign nowDateSec = 'now' | date: '%s' %}
{% assign modDateSec = countdown_timer_date | date: '%s' %}
{% assign countdown_timer_boolean = product.metafields.custom.countdown_timer %}
{% if nowDateSec > modDateSec and countdown_timer_boolean == true %}
{% assign item.quantity = 0 %}
{% else %}
........rest of the code.......
{% endif %}
Has anyone got any clue how I could achieve this or point me in the right direction?
To be clear, I don't want anyone to do the work for me, I'll be happy with some advice.
Edit.
Following the comment from David, and having looked more into the Ajax API, that's what I need to use in order to solve my problem. I will keep reading more about it and I'll update my post if I find a solution. Still, if you have any advice, it's always appreciated.
Andrea

Related

add a small logo to the top right corner of a product images using shopify and liquid

I am looking to add a small logo to the top right corner of a product image. The tricky bit is that I only want it to appear on product images that correspond to a given product tag. For example: Only Show overlay "FitLeftFitRight.jpg" over product images when products have the tag "Fit Left Fit Left".
I am using Shopify which uses Liquid as its markup language.
I would really appreciate this help.
Thank you.
Please post the liquid file that contains the elements for the product image. My initial guess at solving this is to wrap the product image/slider in a <div> tag with the style position: relative and add the logo with styles position: absolute; top: 0; right: 0;
To only appear on product pages with the tag Fit Left Fit Left you can loop through the product tags and if tag is found show the logo, shown in the following code.
{% assign tagFound = false %}
{% for tag in product.tags %}
{% if tag == "Fit Left Fit Left" %}
{% assign tagFound = true %}
{% endif %}
{% endfor %}
// Place this inside the product image wrapper <div> with position relative
{% if tagFound == true %}
<img src="logo-url-here.jpg" style="position: absolute; top: 0; right: 0;" />
{% endif %}

Shopify: Display discount codes in new order email template

I want to display discount codes in new order email notification template, using this code:
{% for discount in discounts %}
{{ discount.code }} : {{ discount.savings | money_with_currency }}
{% endfor %}
It's displaying the discount amount but not the discount code name/title. It's returning blank even if the discount is manually entered in the back-end when creating an order.
How can I display discount codes no matter where it's entered i.e in admin or checkout?
In notifications you may access to discount_application object as explained here:
https://shopify.dev/docs/themes/liquid/reference/objects/discount-application
So (not tested), something like that might work:
{% for discount_application in discount_applications %}
{{ discount_application.title }} : {{ discount_application.value }}
{% endfor %}
HTH
You can get it from your cookies:
<div id="discount-message"></div>
<script type="text/javascript">
var codeCookieValue;
var getCookie = function(name) {
var value = "; " + document.cookie;
var parts = value.split('; '+name+'=');
if (parts.length == 2) return parts.pop().split(";").shift();
};
codeCookieValue = getCookie('discount_code');
</script>

HTML Tabbed Description

I am having trouble adding a tabbed description to my Shopify store, I have tried the options below with no luck!
The first issue is I am not sure I am using the split tag correctly, as the function doesn't pull the code.
Secondly, the tabbed description displays all the information in one view. Doesn't seem to be in a box format more of an overflow?
Any help will be grateful! I am not a coder, but I gave it a try. Can you help?
Product.liquid
Option-1: Replace {% section 'product-template' %} with HTML below
Option-2: No replacement just add
Or
Product-template.liquid
Option-3: Replace {% section 'product-template' %} with HTML below
Option-4: No replacement just add
Or
Product description HTML editor
Option-5: Add HTML
HTML
<div id="product_tabs">
<ul>
<li class="tab_1"><h4>Description</h4></li>
<li class="tab_2"><h4>Specs</h4></li>
<li class="tab_3"><h4>Shipping</h4></li>
<li class="tab_4"><h4>Returns/Refunds</h4></li>
</ul>
<div id="tabs-1">
{% if product.description contains '<!-- split -->' %}
{{ description[0] }}
{% else %}
<p>No Content</p>
{% endif %}
</div>
<div id="tabs-2">
{% if product.description contains '<!-- split -->' %}
{{ description[1] }}
{% else %}
<p>No Content</p>
{% endif %}
</div>
<div id="tabs-3">
{{ pages.shipping-policy.content }}
</div>
<div id="tabs-4">
{{ pages.refund-policy.content }}
</div>
</div>
CSS
Add to Theme.scss.liquid
#product_tabs > ul {
list-style: none;
margin: 0;
}
#product_tabs > ul > li {
display: inline-block;
border: 1px solid;
padding: 10px;
}
#product_tabs > ul > li h4 {
margin: 0;
}
#product_tabs > ul > li.ui-tabs-active {
background: #ddd;
}
It appears to me as though there is nothing that is making the tabs active or inactive. Did you forget to post some of your code? If not it explains why everything is being displayed all at once. If nothing is telling it when to show it will just display everything back to back like you described.
For the explanation of how split works see here. Essentially it can pull from an array; however I don't know why your product description would be an array.
The shopify official help center created a post on making tabs that has worked for many people in the past see here.

How can I assign a new variable value based on text selection in .liquid

Ok so I have a table with 2 columns. In the left column I have a 4 anchor links say 'FAQS', 'HOW TO', 'LIKES', 'OTHER'. each of these links have there own page. What I want to do is populate the right column with the page content based on what the user selected.
Below is the code for my page. please help
<table width = 100% border = "1px">
<tr><h3>Test</h3></tr>
<tr>
<td width = 20% border = "1px" valign = "top">
<a>FAQS</a>
<a>HOW TO</a>
<a>LIKES</a>
<a>other</a>
</td>
<td width = 80% border = "1px">
{% assign infopg = 2 %}
{% case infopg %}
{% when 1 %}
{{ pages.faqs.content }}
{% when 2 %}
{{ pages.how-to-shop.content }}
{% when 3 %}
{{ pages.likes.content }}
{% else %}
{{ pages.other.content }}
{% endcase %}
</td>
</tr>
</table>
You are mixing up the front end with the back end. Liquid is used to render your HTML. If you want to react to some customer clicks, like selecting a menu, you need to use Javascript, not Liquid. You are free to render all the content you need with Liquid, so that Javascript clicks show/hide things, but the answer to your question is "Use Javaascript".

Color Swatch / Variant dropdown list for shopify products

What I intend to do is to do a dropdown list for the product 'color' variant, however with some sort of association with the option value, an image swatch or jpg is displayed.
I found this tutorial to do association of color swatches with product color choice.
However, this displays variants in a button form instead of the defaul dropdown.
http://docs.shopify.com/manual/configuration/store-customization/add-color-swatches-to-your-products
I've been messing about with the scripts but I never got around to getting what I needed.
so here I am for a little bit of help.
Here's my variant list:
<select id="product-select-option-1" class="single-option-selector">
<option value="Red">Red</option>
<option value="White">White</option>
<option value="Black">Black</option>
</select>
generated by :
{% for variant in product.variants %}
<option value="{{ variant.id }}">{{ variant.title }} - {{ variant.price | money }}
</option>
{% endfor %}
Is there a way for me to.. say, associate value="Red" with a 20x20 red square or say, red.jpg ?
Here's a screenshot for a better idea:
http://i.imgur.com/XgW2qHa.png
I used the code from the Shopify article you linked to in your question (Add color swatches to your products) as a starting point and tweaked it to only display one square that changes color depending on the selected option.
Create a new snippet, swatch.liquid (this is a reduced version of swatches.liquid):
<style>
/* Style the swatch */
.swatch { margin:15px 0; }
.swatch ul { list-style-type:none; margin:0; padding:0; }
.swatch li {
/* Rounded corners */
-webkit-border-radius:2px;
-moz-border-radius:2px;
border-radius:2px;
/* Cross-browser inline-block */
display:-moz-inline-stack;
display:inline-block;
zoom:1;
*display:inline;
/* Content must stretch all the way to borders */
padding:0;
/* Background color */
background-color:#ddd;
/* Spacing between buttons */
margin:0px 5px 10px 0;
/* Fake that those are buttons, i.e. clicky */
cursor:pointer;
/* The border when the button is not selected */
border: #DDD 1px solid !important;
}
/* Styles for the text or color container within the swatch button */
.swatch li span { display:block; margin:5px 10px; }
/* Special styles for color swatches */
/* They don't contain text so they need to have a width and height */
.swatch li.color { width:50px; height:35px; }
/* The container of the image/color must be as big as its container */
.swatch li.color span { width:100%; height:100%; margin:0; }
</style>
<div class="swatch clearfix">
<ul>
<li class="color">
<span></span>
</li>
</ul>
</div>
Include the swatch wherever you want it to be displayed in product.liquid:
{% include 'swatch' %}
Add something like this to the selectCallback function:
if (variant) {
jQuery('.swatch li span').css("background-color", variant.option2); // or whichever option 'colour' is in your case...
}
You'll probably need to adjust that javascript depending on how you have your variants set up. For me, the colour is option2, which is then assigned to the background-color css property of the swatch.
Here's what it looks like in action:
It's a bit rough, but hopefully it will provide you with a starting point.
Edit: gist available here