-
-
Save elghorfi/c916d63cac0a42bb61a557086d26fa07 to your computer and use it in GitHub Desktop.
| {% layout none%} | |
| {% assign applied_discounts = cart.discount_applications | where: "type", "discount_code" %} | |
| {% capture discounts %} | |
| {% for discount_application in applied_discounts %} | |
| { | |
| "title" : "{{ discount_application.title }}", | |
| "value" : "{{ discount_application.value }}", | |
| "value_type": "{{ discount_application.value_type }}", | |
| "type": "{{ discount_application.type }}", | |
| "amount" : "{{ discount_application.total_allocated_amount | money }}", | |
| "target_type": "{{ discount_application.target_type }}" | |
| } | |
| {% endfor %} | |
| {% endcapture %} | |
| { | |
| "discounts": [{{ discounts }}], | |
| "total_price": "{{ cart.total_price }}", | |
| "total_price_with_currency": "{{ cart.total_price | money }}" | |
| } |
| {%comment%} | |
| ############################################# | |
| # Mohamed El-Ghorfi Discount Code on Cart # | |
| # [Simplified Version] # | |
| ############################################# | |
| # Paypal Me: https://paypal.me/elghorfimed # | |
| # Buy Me A Coffee: # | |
| # https://www.buymeacoffee.com/elghorfi # | |
| # My Links: # | |
| # https://linktr.ee/elghorfi # | |
| ############################################# | |
| # [email protected] # | |
| ############################################# | |
| {%endcomment%} | |
| <style> | |
| :root { | |
| --primary_color: {{ section.settings.color }}; | |
| --btn_text_color: {{ section.settings.btn_text_color }}; | |
| --bg_color: {{ section.settings.bg_color }}; | |
| --input_bg_color: {{ section.settings.input_bg_color }}; | |
| --input_text_color: {{ section.settings.input_text_color }}; | |
| --margin: {{ section.settings.margin }}px; | |
| --padding: {{ section.settings.padding }}px; | |
| } | |
| .cart-sidebar-discount { | |
| display: grid; | |
| grid-template-columns: 1fr auto; | |
| width: fit-content; | |
| margin: var(--margin); | |
| padding: var(--padding); | |
| background: var(--bg_color); | |
| } | |
| #applied-discount-code small { | |
| grid-column-start: 1; | |
| grid-column-end: 3; | |
| } | |
| #applied-discount-code { | |
| grid-column-start: 1; | |
| grid-column-end: 3; | |
| } | |
| .cart-sidebar-discount input { | |
| margin-top: 15px; | |
| background: var(--input_bg_color); | |
| color: var(--input_text_color); | |
| border: 1px solid var(--input_bg_color); | |
| height: 45px; | |
| outline: none; | |
| font-size: 16px; | |
| letter-spacing: .75px; | |
| text-align: center; | |
| } | |
| .cart-sidebar-discount input:focus { | |
| border: 1px solid var(--input_bg_color); | |
| } | |
| #apply-discount-btn { | |
| background-color: var(--primary_color); | |
| color: var(--btn_text_color); | |
| margin-top: 15px; | |
| border: 0; | |
| height: 45px; | |
| width: 100%; | |
| font-size: 16px; | |
| font-weight: 600; | |
| text-transform: uppercase; | |
| letter-spacing: .75px; | |
| cursor: pointer; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| gap: 15px; | |
| } | |
| #apply-discount-btn:hover { | |
| opacity: .7; | |
| } | |
| .applied-discount-code-value > small { | |
| background: var(--input_bg_color); | |
| padding: 0 10px; | |
| color: var(--primary_color); | |
| font-weight: bold; | |
| border-radius: 20px; | |
| } | |
| .loader { | |
| border: 5px solid #f3f3f3; | |
| border-top: 4px solid var(--primary_color); | |
| border-radius: 50%; | |
| width: 25px; | |
| height: 25px; | |
| animation: spin .5s linear infinite; | |
| } | |
| #discount-code-error { | |
| background: #ff00004f; | |
| color: #e22120; | |
| padding: 5px; | |
| border-radius: 4px; | |
| font-size: 13px; | |
| line-height: 1; | |
| grid-column-start: 1; | |
| grid-column-end: 3; | |
| } | |
| .applied-discount-code-wrapper { | |
| display: none; | |
| align-items: center; | |
| margin: 4px 0; | |
| width: fit-content; | |
| line-height: 1; | |
| } | |
| #clear-discount-btn { | |
| padding: 2px; | |
| margin: 0 2px; | |
| } | |
| #clear-discount-btn:hover { | |
| cursor: pointer; | |
| color: var(--primary_color); | |
| } | |
| #discount-code-error:empty, | |
| .applied-discount-code-value:empty + button { | |
| display: none; | |
| } | |
| @keyframes spin { | |
| 0% { transform: rotate(0deg); } | |
| 100% { transform: rotate(360deg); } | |
| } | |
| </style> | |
| <div class="cart-sidebar-discount"> | |
| <span id="applied-discount-code"> | |
| {{ section.settings.descriptive_text }} | |
| <span class="applied-discount-code-wrapper"{% if content_for_header contains "Shopify.designMode" %}style="display: flex" {% endif %}> | |
| <span class="applied-discount-code-value">{% if content_for_header contains "Shopify.designMode" %}Preview ($10){% endif %}</span> | |
| <span id="clear-discount-btn">X</span> | |
| </span> | |
| </span> | |
| <small id="discount-code-error">{% if content_for_header contains "Shopify.designMode" %}Preview: {{ section.settings.invalid_discount_error }}{% endif %}</small> | |
| <input type="text" id="discount-code-input" placeholder="{{ section.settings.input_placeholder }}" autocomplete="on" value=""> | |
| <button id="apply-discount-btn">{{ section.settings.button_text }}</button> | |
| </div> | |
| <script> | |
| document.addEventListener("DOMContentLoaded", function() { | |
| let clearBtn = document.querySelector("#clear-discount-btn"); | |
| let applyBtn = document.querySelector("#apply-discount-btn"); | |
| let discountCodeError = document.querySelector("#discount-code-error"); | |
| let discountCodeWrapper = document.querySelector("#applied-discount-code .applied-discount-code-wrapper"); | |
| let discountCodeValue = document.querySelector("#applied-discount-code .applied-discount-code-value"); | |
| let discountCodeInput = document.querySelector("#discount-code-input"); | |
| let totalCartSelector = document.querySelector(".cart__subtotal .money"); // Total Cart Selector to update the total amount. | |
| if (localStorage.discountCode) applyDiscountCode( JSON.parse(localStorage.discountCode).code); | |
| if(applyBtn) | |
| applyBtn.addEventListener("click", function(e){ | |
| e.preventDefault() | |
| if(discountCodeInput.value !== '') { | |
| applyDiscountCode(discountCodeInput.value) | |
| discountCodeInput.style.border = 'unset' | |
| }else{ | |
| discountCodeInput.style.border = '1px solid red' | |
| } | |
| }); | |
| if(clearBtn) | |
| clearBtn.addEventListener("click", function(e){ | |
| e.preventDefault() | |
| clearDiscount(); | |
| }); | |
| function clearDiscount() { | |
| discountCodeValue.innerHTML = ""; | |
| discountCodeError.innerHTML = ""; | |
| clearLocalStorage(); | |
| fetch("/checkout?discount=%20"); | |
| } | |
| function clearLocalStorage() { | |
| if(discountCodeWrapper) discountCodeWrapper.style.display = "none"; | |
| if(totalCartSelector) totalCartSelector.innerHTML = JSON.parse(localStorage.discountCode).totalCart; | |
| localStorage.removeItem("discountCode"); | |
| } | |
| function applyDiscountCode(code) { | |
| applyBtn.innerHTML = "{{ section.settings.progress_button_text }} <div class='loader'></div>"; | |
| applyBtn.style.pointerEvents = "none"; | |
| console.clear() | |
| console.log('code', code) | |
| fetch(`/discount/${code}`).then(()=> { | |
| fetch('/cart?view=discount', {}).then(function(res){return res.text();}) | |
| .then(function(data) { | |
| let dataObject = JSON.parse(JSON.stringify(data)) | |
| dataObject = JSON.parse(dataObject) | |
| const appliedCodes = data.discounts.map(i => i.title.trim().toLowerCase()); | |
| if (appliedCodes.includes(code.trim().toLowerCase())) { | |
| if(discountCodeWrapper) discountCodeWrapper.style.display = "inline-flex"; | |
| if(discountCodeError) discountCodeError.innerHTML = ""; | |
| if(discountCodeValue) discountCodeValue.innerHTML = dataObject.discounts[0].title + " (" + dataObject.discounts[0].amount + ")"; | |
| let localStorageValue = { | |
| 'code': code.trim(), | |
| 'totalCart': dataObject.total_price_with_currency | |
| }; | |
| localStorage.setItem("discountCode", JSON.stringify(localStorageValue)); | |
| if(totalCartSelector) totalCartSelector.innerHTML = dataObject.total_price; | |
| }else { | |
| if(discountCodeValue) discountCodeValue.innerHTML = ""; | |
| clearLocalStorage(); | |
| if(discountCodeError) discountCodeError.innerHTML = "{{ section.settings.invalid_discount_error }}" | |
| } | |
| }) | |
| .finally(function() { | |
| if(applyBtn){ | |
| applyBtn.innerHTML = "{{ section.settings.button_text }}"; | |
| applyBtn.style.pointerEvents = "all"; | |
| } | |
| }); | |
| }) | |
| } | |
| }); | |
| </script> | |
| {% schema %} | |
| { | |
| "name": "Discount Field By Mohamed", | |
| "settings": [ | |
| { | |
| "type": "range", | |
| "id": "padding", | |
| "min": 0, | |
| "max": 50, | |
| "step": 1, | |
| "unit": "px", | |
| "label": "Padding:", | |
| "default": 10 | |
| }, | |
| { | |
| "type": "range", | |
| "id": "margin", | |
| "min": 0, | |
| "max": 50, | |
| "step": 1, | |
| "unit": "px", | |
| "label": "Margins:", | |
| "default": 20 | |
| }, | |
| { | |
| "type": "select", | |
| "id": "items_align", | |
| "label": "Align Items", | |
| "default": "default", | |
| "options": [ | |
| { | |
| "label": "Center", | |
| "value": "center" | |
| }, | |
| { | |
| "label": "Left", | |
| "value": "left" | |
| }, | |
| { | |
| "label": "Right", | |
| "value": "right" | |
| }, | |
| { | |
| "label": "Default", | |
| "value": "default" | |
| } | |
| ] | |
| }, | |
| { | |
| "type": "header", | |
| "content": "Content" | |
| }, | |
| { | |
| "type": "text", | |
| "id": "descriptive_text", | |
| "label": "Descriptive Text", | |
| "default": "Apply A Discount Code!" | |
| }, | |
| { | |
| "type": "text", | |
| "id": "input_placeholder", | |
| "label": "Input Placeholder" | |
| }, | |
| { | |
| "type": "text", | |
| "id": "button_text", | |
| "label": "Button Text", | |
| "default": "APPLY" | |
| }, | |
| { | |
| "type": "text", | |
| "id": "progress_button_text", | |
| "label": "Progress Button Text", | |
| "default": "APPLYING", | |
| "info": "Text showing on applying the discount" | |
| }, | |
| { | |
| "type": "text", | |
| "id": "invalid_discount_error", | |
| "label": "Invalid Discount Error", | |
| "default": "Please Enter Valid Coupon Code." | |
| }, | |
| { | |
| "type": "header", | |
| "content": "Colors" | |
| }, | |
| { | |
| "type": "color", | |
| "id": "bg_color", | |
| "label": "background Color", | |
| "default": "#ddd" | |
| }, | |
| { | |
| "type": "color", | |
| "id": "color", | |
| "label": "Button Color", | |
| "default": "#f38a01" | |
| }, | |
| { | |
| "type": "color", | |
| "id": "btn_text_color", | |
| "label": "Button Text Color", | |
| "default": "#fff" | |
| }, | |
| { | |
| "type": "color", | |
| "id": "input_bg_color", | |
| "label": "Input Background Color", | |
| "default": "#eee" | |
| }, | |
| { | |
| "type": "color", | |
| "id": "input_text_color", | |
| "label": "Input Text Color", | |
| "default": "#000" | |
| } | |
| ], | |
| "presets": [ | |
| { | |
| "name": "Discount Field By Mohamed" | |
| } | |
| ] | |
| } | |
| {% endschema %} |
I tried to implement this in the cart drawer and not the cart page--but pherhaps this is not possible. When I made the call to /cart?view=discount , the data returned seems to be the entire html document:
Then I get this error on json parse:
Any ideas?
Thank you @Coru89 For sharing, can you share with me a preview link for the theme you set it on so I can check?
of course! thanks so much for looking! @elghorfi
https://trsp28beo0t1gssm-82564219224.shopifypreview.com/
the code input doesnt show in the cart drawer until an item gets added to the cart
@elghorfi forgot to mention, you can use the test codes:
test_cmd
test_prod
These do get applied, after you force a refresh, but the code is erroring out still. =)
@elghorfi this is an amazing solution — thanks so much! The only issue I found is that the discount code check is case-sensitive.
To fix it, you can replace the following lines:
const appliedCodes = data.discounts.map(i => i.title);
if (appliedCodes.includes(code)) {
with
const appliedCodes = data.discounts.map(i => i.title.trim().toLowerCase());
if (appliedCodes.includes(code.trim().toLowerCase())) {
Just wanted to follow up and say thank you. I got this working! I didn't understand the intention behind the cart.discount.liquid file. I never seen this approach of creating your own end-point to call like this. Very clever.
@elghorfi this is an amazing solution — thanks so much! The only issue I found is that the discount code check is case-sensitive.
To fix it, you can replace the following lines:
const appliedCodes = data.discounts.map(i => i.title); if (appliedCodes.includes(code)) {with
const appliedCodes = data.discounts.map(i => i.title.trim().toLowerCase()); if (appliedCodes.includes(code.trim().toLowerCase())) {
Thank you for the suggestion, I will update it.
Just wanted to follow up and say thank you. I got this working! I didn't understand the intention behind the cart.discount.liquid file. I never seen this approach of creating your own end-point to call like this. Very clever.
Hey @Coru89,
Thank you for the update, glad it worked for you!


I tried to implement this in the cart drawer and not the cart page--but pherhaps this is not possible. When I made the call to /cart?view=discount , the data returned seems to be the entire html document:
Then I get this error on json parse:
Any ideas?