I am trying to display the selected variant stock value in shopify.
I am able to show the stock of the current selected or when i reload the browser of the selected variant but it doesn't seem to change when I select other variants
<div id="variant-inventory" class="my-variant-inventory">
{% if product.variants.first.inventory_management == "shopify" %}
{% if product.variants.first.inventory_quantity < 6 %}
Only <span class="nuStock">{{ product.variants.first.inventory_quantity }}</span> left!
{% else %}
<span class="myStock"></span>
{% endif %}
Related
I have created a gift note functionality which store notes but the problem is it is showing title on orders even though textarea is blank could you please help to get rid of this problem
if textarea is blank still order page is showing "cart note:"
{% if line_item.properties != empty %}
<ul class="CartItem__PropertyList">
{% for property in line_item.properties %}
{% assign first_character_in_key = property.first | truncate: 1, '' %}
{% if property.last == blank or first_character_in_key == '_' %}
{% continue %}
{% endif %}
<li class="CartItem__Property">{{ property.first }}: <p class="cart_note_txt">{{ property.last }}</p></li>
{% endfor %}
</ul>
{% endif %}
<textarea class="gift_note_pro" maxlength="300" name="properties[Cart Note]" style="display:none;" placeholder="Add a note">
</textarea>
Can someone help me to get rid of this problem ?
I have a custom button in the a header next to a "cart" link. Website uses AJAX cart. When an item is added to cart, the cart link enlarges to include nr of items in cart. This causes the cart link to overflow and overlap the custom button next to it. Essentially what I'm trying to achieve is to add a margin to the custom button when an item is added to cart and the cart link is expanded. My first thought was to wrap both in a div and use CSS flex to adjust the sizing of both, however, and please correct me if I'm wrong, I thought it would be quicker to just write a script that would add a margin to my custom button. Definitely didn't turn out to be the quicker way as I've been stuck on it for hours now - any help would be greatly appreciated. I've browsed through similar posts and couldn't find a result that I want - any help would be greatly appreciated (I'm still new to JS and jQuery but learning). Below is the code and some of the things that I've tried.
HTML - header
<div class="header--menu">
<div class="custom-btn-container">
Quick Order
</div>
{%
render 'framework--x-menu',
js_class: 'XMenu',
align: menu_alignment,
overlap_parent: 1,
handle: menu
%}
</div>
{% endif %}
<div class="header--cart">
{% render 'snippet-cart', cart_icon: cart_icon %}
</div>
</div>
HTML - cart
{% if settings.cart--type == 'drawer' %}
<div
class="cart--open-right off-canvas--open"
data-off-canvas--open="right-sidebar"
data-off-canvas--view="cart"
aria-haspopup=”menu”
>
{% endif %}
<a
class="header--cart-link"
data-item="accent-text"
href="{{ routes.cart_url }}"
aria-label="{{ 'layout.header.cart' | t }}"
>
{% if cart_icon == 'text' %}
{{ 'layout.header.cart' | t }}
{% elsif cart_icon == 'bag' %}
{% render 'framework--icons', icon: 'bag' %}
{% else %}
{% render 'framework--icons', icon: 'cart' %}
{% endif %}
<span class="header--cart-number" data-item-count="{{ cart.item_count }}">
(<span class="cart--external--total-items">{{ cart.item_count }}</span>)
</span>
</a>
{% if settings.cart--type == 'drawer' %}
</div>
{% endif %}
And these are some of the scripts that I've tried:
window.onload = () => {
if (jQuery('.header--cart-number').data('item-count') != '0') {
$(".custom-button").css('margin-right', '10px');
}
}
The above is nearly what I'm after, but only works after refreshing the page.
document.ajaxComplete = () => {
if (jQuery('.header--cart-number').data('item-count') != '0') {
$(".custom-button").css('margin-right', '10px');
}
}
similar story
$(document).ajaxSuccess(function() {
if (jQuery('.header--cart-number').data('item-count') != '0') {
$(".custom-button").css('margin-right', '10px');
}
}
This didn't do anything whatsoever.
I'm sure I'm missing something small, but it's driving me mad. Again, any help will be greatly appreciated!
Best,
J
I've checked a lot of other questions and I haven't seen my particular scenario really addressed and I've tried a lot of things out without success.
What I have is a DJango for loop in my HTML code, and within the for loop is an if statement checking if each element from the list that is being looped through equals a certain value. If that is true, then an entry is created on the page. I need to dynamically print the element number (eg. entry 1 would display as 1. and entry 2 would display as 2.)
The two best attempts I have made are:
1.
<!-- this approach prints out 1 for each entry -->
{% with counter=0 %}
{% for q in questionnaire.questions %}
{% if q.answer %}
<div class="row"><h3>
{{ counter|add:1 }}. {{ q.name }}
</h3></div>
<!-- some other code-->
{% endif %}
{% endfor %}
{% endwith %}
{% for q in questionnaire.questions %}
{% if q.answer %}
<div class="row"><h3>
<span id="displayCount">0</span>. {{ q.name }}
</h3></div>
<!-- some other code-->
{% endif %}
{% endfor %}
<script type="text/javascript">
var count = 0;
var display = document.getElementById("displayCount");
count++;
display.innerHTML = count;
</script>
Any help would be appreciated
You can access the built-in counter of your for loop using forloop.counter. It starts at 1, you can also you forloop.counter0 if you'd like to start at zero.
{% for q in questionnaire.questions %}
{% if q.answer %}
<div class="row">
<h3>
{{ forloop.counter }}. {{ q.name }}
</h3>
</div>
<!-- some other code-->
{% endif %}
{% endfor %}
Filter your queryset in your view as to avoid issues with indexing and separating presentation from logic.
I am sort of new with Shopify and I´ve been playing around with it for the ast week or so without much success when trying to solve my issue.
I am currently using the Brooklyn template and the way they represent the Product Page doesn´t precisely give the best user experience. The way it´s representing the images by default is by having all the product variants images showed to the customer all the time even if he hasn´t actually picket that variant (i.e. a specific colour for the product). It also displays all the product images in a vertical way which makes navigation for the user quite frustrating if you have more than a couple of pictures per product variant.
I´ve found online a tutorial ( http://littlesnippets.ca/blogs/tutorials/15665261-grouping-images-with-variants )that addresses the part of my issue to hide the pictures of the variants that are not selected by the customer, and show them once the user click on it.(you can see an example of what I want here http://group-variant-images.myshopify.com/collections/frontpage/products/anson-chair ). This is more or less how it looks my site now (https://themes.shopify.com/themes/brooklyn/styles/brooklyn/preview).
The problem is that that tutorial is being applied to a website that is not using the exact theme/functionality that Ii do, although it´s similar.
I´ve failed to apply those changes to my theme, can anybody give me a hand?
This is my product.liquid piece of code at the moment:
<!-- /templates/product.liquid -->
<div itemscope itemtype="http://schema.org/Product">
<meta itemprop="url" content="{{ shop.url }}{{ product.url }}">
<meta itemprop="image" content="{{ product.featured_image.src | img_url: 'grande' }}">
{% assign current_variant = product.selected_or_first_available_variant %}
<div class="grid product-single">
<div class="grid__item large--seven-twelfths medium--seven-twelfths text-center">
<div class="product-single__photos">
{% assign featured_image = current_variant.featured_image | default: product.featured_image %}
{% comment %}
Display current variant image, or default first
{% endcomment %}
<div class="product-single__photo-wrapper">
<img class="product-single__photo" id="ProductPhotoImg" src="{{ featured_image | img_url: 'grande' }}" {% if settings.product_zoom_enable %}data-mfp-src="{{ featured_image | img_url: '1024x1024' }}"{% endif %} alt="{{ featured_image.alt | escape }}" data-image-id="{{ featured_image.id }}">
</div>
{% comment %}
Display rest of product images, not repeating the featured one
{% endcomment %}
{% for image in product.images %}
{% unless image contains featured_image %}
<div class="product-single__photo-wrapper">
<img class="product-single__photo" src="{{ image.src | img_url: 'grande' }}" {% if settings.product_zoom_enable %}data-mfp-src="{{ image.src | img_url: '1024x1024' }}"{% endif %} alt="{{ image.alt | escape }}" data-image-id="{{ image.id }}">
</div>
{% endunless %}
{% endfor %}
</div>
</div>
<div class="grid__item product-single__meta--wrapper medium--five-twelfths large--five-twelfths">
<div class="product-single__meta">
{% if settings.product_vendor_enable %}
<h2 class="product-single__vendor" itemprop="brand">{{ product.vendor }}</h2>
{% endif %}
<h1 class="product-single__title" itemprop="name">{{ product.title }}</h1>
<div itemprop="offers" itemscope itemtype="http://schema.org/Offer">
{% comment %}
Optionally show the 'compare at' or original price of the product.
{% endcomment %}
{% if product.compare_at_price_max > product.price %}
<span class="product-single__price--wrapper">
<span class="visually-hidden">{{ 'products.general.regular_price' | t }}</span>
<span id="ComparePrice" class="product-single__price--compare-at">
{% if current_variant.compare_at_price > current_variant.price %}
{{ current_variant.compare_at_price | money }}
{% endif %}
</span>
<span class="visually-hidden">{{ 'products.general.sale_price' | t }}</span>
</span>
{% endif %}
<span id="ProductPrice" class="product-single__price{% if product.compare_at_price > product.price %} on-sale{% endif %}" itemprop="price">
{{ current_variant.price | money }}
</span>
<hr class="hr--small">
<meta itemprop="priceCurrency" content="{{ shop.currency }}">
<link itemprop="availability" href="http://schema.org/{% if product.available %}InStock{% else %}OutOfStock{% endif %}">
<form action="/cart/add" method="post" enctype="multipart/form-data" class="product-single__form" id="AddToCartForm">
<select name="id" id="ProductSelect" class="product-single__variants">
{% for variant in product.variants %}
{% if variant.available %}
<option {% if variant == product.selected_or_first_available_variant %} selected="selected" {% endif %} data-sku="{{ variant.sku }}" value="{{ variant.id }}">{{ variant.title }} - {{ variant.price | money_with_currency }}</option>
{% else %}
<option disabled="disabled">
{{ variant.title }} - {{ 'products.product.sold_out' | t }}
</option>
{% endif %}
{% endfor %}
</select>
{% comment %}
<div class="product-single__quantity">
<label for="Quantity" class="product-single__quantity-label js-quantity-selector">{{ 'products.product.quantity' | t }}</label>
<input type="number" hidden="hidden" id="Quantity" name="quantity" value="1" min="1" class="js-quantity-selector">
</div>
{% endcomment %}
<div class="product-single__add-to-cart">
<button type="submit" name="add" id="AddToCart" class="btn">
<span id="AddToCartText">{{ 'products.product.add_to_cart' | t }}</span>
</button>
</div>
</form>
</div>
<div class="product-single__description rte" itemprop="description">
{{ product.description }}
</div>
{% if settings.social_sharing_products %}
{% include 'social-sharing' %}
{% endif %}
</div>
</div>
</div>
{% if collection %}
<hr class="hr--clear">
<div class="text-center">
← {{ 'products.general.collection_return' | t: collection: collection.title }}
</div>
{% endif %}
</div>
{% comment %}
*IMPORTANT:*
This theme uses a customized version of `option_selection.js` to support using radio inputs for color and size variants. The custom version is in `variant_selection.js`.
If you wish to enable the default dropdowns for size and color
you can change the liquid asset tag below from:
{{ 'variant_selection.js' | asset_url | script_tag }}
to
{{ 'option_selection.js' | shopify_asset_url | script_tag }}
If you use the default `option_selection.js` the labels for the dropdowns will appear outside the dropdown.
You will also need to change `.radio-wrapper` to `.selector-wrapper` below.
{% endcomment %}
{{ 'variant_selection.js' | asset_url | script_tag }}
<script>
var selectCallback = function(variant, selector) {
timber.productPage({
money_format: "{{ shop.money_format }}",
variant: variant,
selector: selector,
translations: {
addToCart : {{ 'products.product.add_to_cart' | t | json }},
soldOut : {{ 'products.product.sold_out' | t | json }},
unavailable : {{ 'products.product.unavailable' | t | json }}
}
});
};
jQuery(function($) {
new Shopify.OptionSelectors('ProductSelect', {
product: {{ product | json }},
onVariantSelected: selectCallback,
enableHistoryState: true
});
// Add label if only one product option and it isn't 'Title'. Could be 'Size'.
{% if product.options.size == 1 and product.options.first != 'Title' %}
$('.radio-wrapper:eq(0)').prepend('<label for="ProductSelect-option-0" class="single-option-radio__label">{{ product.options.first | escape }} </label>');
{% endif %}
// Hide drop-down selectors if we only have 1 variant and its title contains 'Default'.
{% if product.variants.size == 1 and product.variants.first.title contains 'Default' %}
$('.selector-wrapper').hide();
{% endif %}
});
</script>
Shopify's admin interface only allows for one product image per variant. For this reason, to do what you are trying to do isn't as easy as you are hoping. Through the Shopify API you can add metafields to products and product variants and in these metafields you can store whatever information you want -- including links to additional images. Here is a link to the documentation for the metafields on variants: https://docs.shopify.com/api/reference/product_variant
Since the admin interface doesn't really give you the ability to modify the metafields directly, you have a couple of choices:
Spend the time and energy (or money) to hook up your own management tool to the API and modify it yourself.
Purchase an app from the Shopify app store that already does this for you. Here is a link to some of these apps that should guide you in the right direction: https://apps.shopify.com/search/query?utf8=%E2%9C%93&q=variant
Either way, you'll need to come up with some sort of property name convention so you know you're dealing with images because the metafields accept whatever you feel like dropping into them.
Once you are able to define the images for your product variants, then you'll need to update the logic in your liquid/javascript to accomplish the desired functionality. You can do this a few different ways, and different people will have different opinions based on SEO but my suggestion for the path of least resistance is to do something like this:
{% for v in product.variants %}
<div id="variant_{{ v.id }}">
{% for m in v.metafields %}
{% if m.key contains "WHATEVER_CONVENTION_YOU_USED_TO_DENOTE_IMAGES" %}
{% comment %}
OUTPUT THE IMAGE TAG - PROBABLY WRAPPED IN AN ANCHOR
{% endcomment %}
{% endif %}
{% endfor %}
</div>
{% endfor %}
You'll want to incorporate some logic to show and hide the div based on the variant. Note the <div id="variant_{{ v.id }}">
The reason for this approach rather than using the api to populate js objects is that your links are already in the DOM and you can create javascript handlers when the page loads. If you wait to populate your images and links until the user selects the variant, then you'll have to deal with the event handling of dynamically created nodes.
Hope all this guides you in a good direction. If you have questions or need help feel free to reach out to me via my profile.
Additional Note: Good software developers will note the O(n^2) time complexity in the code above. Shopify doesn't execute your backend code when the page loads, rather it is executed and cached when your theme is uploaded or modified. Because of this, the poor O(n^2) time complexity won't hurt your page load performance.
As a side fun fact, this is the reason Shopify cannot create Liquid tags for things like current_time or random. Their caching mechanism which keeps sites from crashing even when being presented on Shark Tank also relies on the fact that their liquid tags, filters, and blocks don't return variable results. So, they can cache the resulting HTML and serve it directly from their caching servers...thus tags like random or current_time would only ever have an opportunity to run once.
you can try variant-image-automator paid app. this hides unnecessary images from the product page.
I have been working through the Tango with Django exercises to cut my teeth into Django. Almost done but having a problem with the Ajax part.
Ajax function to auto_add a page is not being called. Idk what the problem is since the other functions are being called.
On the shell prompt, there is no call to the ajax function at all. Help needed.
Pertinent code attached. It is the same as on the website link above.
static/rango-ajax.js
$('.rango-add').click(function(){
var catid = $(this).attr("data-catid");
var title = $(this).atrr("data-title");
var url = $(this).attr("data-url");
$.get('/rango/auto_add_page/', {category_id: catid, url: url, title: title}, function(data){
$('#pages').html(data);
me.hide();
});
});
templates/rango/category.html
{% if user.is_authenticated %}
<button data-catid="{{category.id}}" data-title="{{ result.title }}" data-url="{{ result.link }}" class="rango-add btn btn-mini btn-info" type="button">Add</button>
{% endif %}
rango/views.py
#login_required
def auto_add_page(request):
context = RequestContext(request)
cat_id = None
url = None
title = None
context_dict = {}
if request.method == 'GET':
cat_id = request.GET['category_id']
url = request.GET['url']
title = request.GET['title']
if cat_id:
category = Category.objects.get(id=int(cat_id))
p = Page.objects.get_or_create(category=category, title=title, url=url)
pages = Page.objects.filter(category=category).order_by('-views')
#Adds our results list to the template context under name pages.
context_dict['pages'] = pages
return render_to_response('rango/page_list.html', context_dict, context)
rango/urls.py
urlpatterns = patterns('',
url(r'^$', views.index, name='index'),
url(r'^goto/$', views.track_url, name='track_url'),
url(r'^add_category/$', views.add_category, name='add_category'),
url(r'^auto_add_page/$', views.auto_add_page, name='auto_add_page'),
Complete code is at this link.
your code is good, the only thing what you have to do is to define your template in /tango/templates/rango/page_list.html. This template have the following code:
{% if pages %}
<ul>
{% for page in pages %}
<li>
{{ page.title}}
{% if page.views > 1 %}
({{page.views}} views)
{% elif page.views == 1 %}
({{page.views}} view)
{% endif %}
</li>
{% endfor %}
</ul>
{% else %}
<strong> No Pages currently in category. </strong>
{% endif %}
And inside of your category template you must define the following code:
% if category %}
{% if user.is_authenticated %}
Add a new Page <br>
{% endif %}
{% if pages %}
<div id="pages">
<ul>
{% for page in pages %}
<li>
{{ page.title}}
{% if page.views > 1 %}
({{page.views}} views)
{% elif page.views == 1 %}
({{page.views}} view)
{% endif %}
</li>
{% endfor %}
</ul>
</div>
{% else %}
<strong> No Pages currently in category. </strong>
{% endif %}
{% else %}
The specified category {{ category_name }} does not exist!
{% endif %}
I'm working through this section of the tutorial now and just want to add to Héctor's answer. To avoid duplicating the code to display the list of pages I did the following:
I added a get_page_list() method to tango/rango/templatetags/rango_extras.py, similar to the get_category_list() method used to display a list of categories in an earlier section of the tutorial.
from rango.models import Page
#register.inclusion_tag("rango/page_list.html")
def get_page_list(category):
pages = Page.objects.filter(category=category) if category else []
return {'pages': pages}
Then we just need to load rango_extras and call the get_page_list() method in tango/templates/rango/category.html.
{% extends 'rango/base.html' %}
{% load rango_extras %}
<!-- Existing code -->
{% if category %}
<!-- Existing code to show category likes and like button -->
<div id="page_list">
{% get_page_list category %}
</div>
<!-- Existing code to show search if user is authenticated -->
{% else %]
The specified category {{ category_name }} does not exist!
{% endif %}
This allows you to display the list of pages when a category page is first loaded and then refresh it if a category is added from the search area, without having to duplicate any code.