PRODUCT UPSELL
Product Upsell enables a store to offer products via a popup. It is adminable, and the popup is shown on either product pages, or on the cart page.
Its settings enable the admin to display the upsell when
- a minimum cart sub-total is met,
- when a specified product is added to the cart,
- when products in a specific collection are added to the cart,
- when any product is added to the cart
STRICTLY ENFORCE UPSELL
There is a setting called: "STRICTLY ENFORCE UPSELL"
When enabled, this script uses CartJS to loop through the cart lineitems, and ensures that, if an offered product is in the cart, the conditions for which it was added are still maintained.
For example, if a price threshold is met, and an offered product is added to the cart, but the customer removes a few products and the cart subsequently drops below the threshold, the Javascript will remove the offered product.
For this reason, it is prudent to not enable this setting when the "Upsell" product can be purchased regularly within the store.
If such a case were to occur, as in the offer product was added regularly by a user, the script would remove the product from the customer's cart.
INCLUDES
Product Upsell requires three files:
- upsell.liquid,
- popup-product-add-to-cart-form.liquid,
- settings_schema.json
Within theme.liquid add
{% include 'upsell' %} before the closing body tag.
{% include 'upsell' %}
</body>
Upsell.liquid
upsell.liquid contains all Liquid logic, CSS, and Javascript for the popup. Its first section gets and sets liquid values for trigger on product pages, and price values on the cart page.
Its second section assigns values for that which the popup will display internally.
Its HTML section defines the popup with display: none, and includes the popup-product-add-to-cart-form.
Its Javascript section calls the display function if necessary conditions have been met. In the console, 'UPSELL' is always logged for debugging convenience.
Its CSS section contains necessary styling for basic formatting.
<!-- Product Upsell -->
<!-- include necessary scripts -->
{% if settings.upsell-enforce %}
<!-- CARTJS for Upsell -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/shopify-cartjs/0.4.1/cart.min.js"></script>
<script type="text/javascript">
console.log('this is being included');
jQuery(function() {
CartJS.init({{ cart | json }});
});
</script>
{% endif %}
<!-- trigger for product pages, price values for cart page -->
{% capture trigger %}{{ settings.upsell-product-trigger }}{% endcapture %}
{% capture cart-total %}{{ cart.total_price | abs }}{% endcapture %}
{% assign upsell-price = settings.upsell-price | times: 1 %}
<!-- assigning popup information to be displayed, based off template -->
{% if template == 'product' %}
{% capture upsell-show-img %}
<img src="{{ all_products[settings.upsell-product-show].featured_image | img_url: 'large' }}">
{% endcapture %}
{% capture upsell-show-title %}
{{ all_products[settings.upsell-product-show].title }}
{% endcapture %}
{% capture upsell-show-cost %}
{{ all_products[settings.upsell-product-show].price | money }}
{% endcapture %}
{% assign upsell-message = settings.upsell-product-message %}
{% assign popup_product = all_products[settings.upsell-product-show] %}
{% elsif template == 'cart' %}
{% capture upsell-show-img %}
<img src="{{ all_products[settings.upsell-price-show].featured_image | img_url: 'large' }}">
{% endcapture %}
{% capture upsell-show-title %}
{{ all_products[settings.upsell-price-show].title }}
{% endcapture %}
{% capture upsell-show-cost %}
{{ all_products[settings.upsell-price-show].price | money }}
{% endcapture %}
{% assign upsell-message = settings.upsell-price-message %}
{% assign popup_product = all_products[settings.upsell-price-show] %}
{% endif %}
/* =============================================
================================================
POPUP HTML
================================================
==============================================*/
<!-- if upsell is enabled settings.upsell-product-enable -->
{% if settings.upsell-product-enable or settings.upsell-price-enable %}
<!-- Trigger the modal with a button -->
<button style="display: none;" id="upsell-button" type="button" class="btn btn-info btn-lg" data-toggle="modal" data-target="#myModal">Product Upsell Button</button>
<!-- Modal -->
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">
{{ upsell-message }}
</h4>
</div>
<div class="modal-body col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="modal-image col-lg-6 col-md-6 col-sm-6 col-xs-6">
{{ upsell-show-img }}
</div>
<div class="modal-form col-lg-6 col-md-6 col-sm-6 col-xs-6">
<span class="title the-title" itemprop="title">{{ upsell-show-title }}</span>
<span class="money" itemprop="price">{{ upsell-show-cost }}</span>
{% if has_cart %}{% include 'popup-product-add-to-cart-form' %}{% endif %}
</div>
</div>
<div class="modal-footer">
<button id="no-thanks" type="button" class="btn btn-default" data-dismiss="modal">No Thanks</button>
</div>
</div>
</div>
</div>
{% endif %}
/* =============================================
================================================
JAVASCRIPT
================================================
==============================================*/
<!-- CART -->
<!-- loop through cart to check if product's already been added -->
{% assign cart_contains_upsell_product = false %}
{% for item in cart.items %}
{% if item.product.handle contains all_products[settings.upsell-price-show].handle %}
{% assign cart_contains_upsell_product = true %}
{% endif %}
{% endfor %}
<!-- add script if conditions have been met -->
{% if template == 'cart' and settings.upsell-price-enable %}
<script>
$( window ).load(function() {
console.log('UPSELL')
//append price information to the page's header
$('.page-header').append("<br />Cart Total: {{ cart-total | money }}<br />Upsell price limit: {{ upsell-price | money }}");
{% if cart.total_price >= upsell-price %}
{% unless cart_contains_upsell_product %}
$('.modal').modal('show');
{% endunless %}
{% endif %}
});
</script>
{% endif %}
<!-- PRODUCT -->
<!-- loop through cart to check if product's already been added -->
{% assign cart_contains_upsell_product = false %}
{% for item in cart.items %}
{{item.product.handle}}{{ all_products[settings.upsell-product-show].handle }}
{% if item.product.handle contains all_products[settings.upsell-product-show].handle %}
{% assign cart_contains_upsell_product = true %}
{% endif %}
{% endfor %}
<!-- capture script to be added -->
{% capture script-to-be-added %}
<script>
$( window ).load(function() {
console.log('UPSELL')
{%if cart_contains_upsell_product%} console.log(' cart already contains product');{%endif%}
{% unless cart_contains_upsell_product %}
document.getElementById('purchase').onclick = function(){
$('#upsell-button').click();
}
{% endunless %}
});
</script>
{% endcapture %}
<!-- switching clause for when to show popup, defined by admin -->
{% if template == 'product' and settings.upsell-product-enable %}
{% assign trigger-check = settings.upsell-product-trigger-option %}
{% case trigger-check %}
<!-- All products is trigger -->
{% when 'upsell-product-trigger-option-all' %}
{{ script-to-be-added }}
<!-- One product is the trigger -->
{% when 'upsell-product-trigger-option-product' %}
{% if product.handle contains settings.upsell-product-trigger %}
{{ script-to-be-added }}
{% endif %}
<!-- Every product in a collection is the trigger -->
{% when 'upsell-product-trigger-option-collection' %}
{% for collection in product.collections %}
{% if collection.handle == settings.upsell-product-collection %}
{{ script-to-be-added }}
{% break %}
{% endif %}
{% endfor %}
{% endcase %}
{% endif %}
<!-- ENFORCE -->
{% if template == 'cart' and settings.upsell-enforce %}
<script>
/**************************
***************************
WINDOW LOAD
***************************
***************************/
$( window ).load(function(){
/**************************
***************************
LIQUID VARIABLES
***************************
***************************/
upsell_price_enable = {{settings.upsell-price-enable}}; //default to false
upsell_product_enable = {{ settings.upsell-product-enable }}; //default to false
upsell_price = parseInt('{{ upsell-price = settings.upsell-price | times: 1 }}'); //should not have decimal
upsell_price_product_id = parseInt('{{ all_products[settings.upsell-price-show].id }}');
upsell_product_trigger_id = parseInt('{{ all_products[ settings.upsell-product-trigger ].id }}');
upsell_product_show_id = parseInt('{{ all_products[settings.upsell-product-show].id }}' );
upsell_product_trigger_option = '{{ settings.upsell-product-trigger-option }}';
upsell_collection_handle = '{{ settings.upsell-product-collection }}';
//Maps arrays of collection title strings to keys of product ids
products_collections_map = new Map();
console.log('making map');
{% for item in cart.items %}
var current_array = [];
{% assign item_product = item.product %}
{% for collection in item_product.collections %}
//push collection into array
current_array.push( '{{ collection.handle }}' );
{% endfor %}
products_collections_map.set( {{ item_product.id }} , current_array );
{% endfor %}
//callbacks for CartJS requests
options = {
"success": function(data, textStatus, jqXHR) {
console.log('removed!');
},
"error": function(jqXHR, textStatus, errorThrown) {
console.log('Error: ' + errorThrown + '!');
}
}
function lineItemsContainsProduct( product_id, currentCart ){
for( var i = 0; i < currentCart.items.length; i++){
var item = currentCart.items[i];
if( item.product_id == product_id ){
return true;
}
}
return false;
}
function lineItemsOnlyContainsProduct( product_id, currentCart ){
for( var i = 0; i < currentCart.items.length; i++){
var item = currentCart.items[i];
if( item.product_id != product_id ){
return false;
}
}
return true;
}
function getLineItemIdsByProductId( product_id, currentCart ){
var ids = [];
for( var i = 0; i < currentCart.items.length; i++){
var item = currentCart.items[i];
if( item.product_id == product_id ){
ids.push(item.id);
}
}
return ids;
}
function removeIdsWithinArray( idsToRemove, currentCart ){
for( var i = 0; i < idsToRemove.length; i++){
var currentId = idsToRemove[i];
console.log('removing: '+ currentId);
CartJS.removeItemById( currentId, options );
}
}
function removeProductFromCart( product_id, currentCart ){
var idsToRemove = getLineItemIdsByProductId( product_id, currentCart );
removeIdsWithinArray( idsToRemove, currentCart );
if(!alert("Your cart no longer meet product offer requirements. Offer item(s) will be removed")){window.location.reload();}
}
/**************************
***************************
MAIN CART CHECK FUNCTION
***************************
***************************/
checkCart = function(){
console.log('checking cart');
var currentCart = CartJS.cart;
var totalPrice = currentCart.total_price;
//if price upsell is enabled and price is not yet met
if( upsell_price_enable ){
console.log( 'upsell_price_enable' );
if(totalPrice < upsell_price){
console.log('price isnt met yet');
//if cart contains upsell product remove it
if( lineItemsContainsProduct( upsell_price_product_id, currentCart ) ){
removeProductFromCart( upsell_price_product_id, currentCart )
};
}
}
//when upsell_product_enable
if( upsell_product_enable ){
console.log( 'upsell_product_enable' );
//Trigger for single item
if( upsell_product_trigger_option == 'upsell-product-trigger-option-product'){
console.log('single item trigger');
if( lineItemsContainsProduct( upsell_product_show_id, currentCart ) ){
console.log('cart contains upsell_product_show_id');
//if cart doesn't contain trigger item remove upsell_product_show_id
if( !lineItemsContainsProduct( upsell_product_trigger_id, currentCart ) ){
removeProductFromCart( upsell_product_show_id , currentCart );
}
}
}
//Trigger for items within specific collection
if( upsell_product_trigger_option == 'upsell-product-trigger-option-collection' ){
console.log('specific collection trigger');
//if offer item is in cart
if( lineItemsContainsProduct( upsell_product_show_id, currentCart ) ){
var cart_contains_product_with_collection = false;
//go through items and see if any item have selected collection
for(var j = 0; j < currentCart.items.length; j++ ){
var item = currentCart.items[j];
//if item is offer item, continue
if( item.product_id == upsell_product_show_id){
continue
};
var item_collections = products_collections_map.get( item.product_id );
var item_has_collection = false;
//search item collections array for upsell_collection_handle
for(var h = 0; h < item_collections.length; h++){
if( item_collections[h] == upsell_collection_handle ){
item_has_collection = true;
break;
}
}
if( item_has_collection ){
cart_contains_product_with_collection = true;
break;
}
}
//if no items (excluding offer item) in cart have correct collection
if(!cart_contains_product_with_collection){
removeProductFromCart( upsell_product_show_id , currentCart );
}
}
}
//Trigger for any product
if( upsell_product_trigger_option == 'upsell-product-trigger-option-all' ){
console.log('any item trigger');
if( lineItemsContainsProduct( upsell_product_show_id, currentCart ) ){
//see if there are other items in cart other than offer product
var contains_only_product = lineItemsOnlyContainsProduct( upsell_product_show_id, currentCart );
//remove items
if(contains_only_product){
removeProductFromCart( upsell_product_show_id , currentCart );
}
}
}
}
};
$('.main-content').change( checkCart );
$('.main-content').click( checkCart );
checkCart();
});
</script>
{% endif %}
/* =============================================
================================================
CSS
================================================
==============================================*/
<style>
.modal-content .form-control {
border-color: black;
}
.modal-content img {
display: block;
float: left;
}
.modal-content select#product-select {
margin-bottom: 20px;
}
.modal-content .detail-wrap.desc-wrap {
display: none;
}
.modal-content .modal-footer {
display: inline-block;
width: 100%;
}
.modal-content .modal-form {
display: inline-block;
float: right;
}
.modal-content .product-price {
display: inline-block;
}
.modal-content span.detail-title {
display: inline-block;
width: 100% !important;
position: relative !important;
margin-bottom: 15px;
}
.modal-content .detail-title{
margin-left: 15px;
}
.modal-content .detail-wrap.quantity-wrap {
display: inline-block;
padding: 0 !important;
margin: 0 !important;
border: none;
width: 100%;
}
.modal-content .modal-form, .modal-image{
min-height: 0;
}
.modal-content .product-price {
padding-left: 15px !important;
}
.modal-content .product-quantity-wrapper{
min-width:1px;
display: block;
margin: 0 auto;
}
.modal-content .product-quantity-wrapper {
width: 160px !important;
display: block;
margin: 0 auto;
}
.modal-content span.money {
font-size: 20px;
}
.modal-content .detail-wrap {
border: none;
}
.modal-content .detail-wrap {
padding: 0;
padding-top: 60px;
padding-bottom: 20px;
}
.modal-content span.title {
width: 100%;
display: block;
text-align: center;
font-size: 28px;
color: black;
}
.modal-content span.money {
width: 100%;
display: block;
text-align: left;
font-size: 24px !important;
color: black;
}
.modal-content #modal-cart-button {
color: white;
background: black;
}
.modal-content h4.modal-title {
text-align: center;
font-size: 28px;
color: black;
}
.modal-content .detail-wrap.quantity-wrap {
display: none !important;
}
.modal-content button#no-thanks {
background: grey;
}
.modal-content .add-to-cart-button-wrap {
display: inline-block ;
clear: both ;
}
.modal-content input#purchase {
background: black;
font-size: 20px;
}
.modal-content .share-icons {
display: none;
}
.modal-content span.title.the-title {
text-align: left;
}
.modal-content input#purchase:hover{
color: white;
}
</style>
popup-product-add-to-cart-form.liquid is a duplicate of product-add-to-cart-form.liquid, but all instances of the global variable 'product' are replaced with a prefixed variable.
This works around the problem of the popup's internal add-to-cart button inadvertently adding the original product to the cart a second time.
It's Javascript has been commented out to stop duplicate modifications to the original product form.
<form id="{% include '__advanced-layout-id' with 'product-form' %}" action="/cart/add" method="post" role="form" enctype="multipart/form-data">
<div class="product-variants">
<div class="col-xs-12 col-lg-6">
<select id="{% include '__advanced-layout-id' with 'product-select' %} popup-single-option-selector" name="id" class="form-control input-lg">
{% for v in popup_product.variants %}
{{ v }}
<option value="{{ v.id }}"{% if v == popup_product.selected_or_first_available_variant %} selected="selected"{% endif %}>{{ v.title }}</option>
{% endfor %}
</select>
</div>
{% if popup_product.metafields.properties.size > 0 %}
<div class="col-xs-12 col-lg-6">
{% for l_item in popup_product.metafields.properties %}
{% assign key = l_item.first | split: ':' %}
{% assign key_type = key.last %}
{% assign key_title = key.first %}
{% assign value = l_item.last %}
<div class="form-group">
<label>{{ key_title }}</label>
{% if key_type == 'select' %}
{% assign value_array = value | split: ',' %}
<select class="form-control" name="properties[{{ key_title }}]">
{% for v in value_array %}
<option value="{{ v }}">{{ v }}</option>
{% endfor %}
</select>
{% elsif key_type == 'text' %}
<input type="text" class="form-control" name="properties[{{ key_title }}]" placeholder="{{ value }}" />
{% elsif key_type == 'checkbox' %}
<p><input type="checkbox" name="properties[{{ key_title }}]" value="{{ value }}" /> {{ value }}</p>
{% elsif key_type == 'file' %}
<p><input type="file" id="{{ key_title }}" name="properties[{{ key_title }}]"> <small><em>{{ value }}</em></small></p>
{% endif %}
</div>
{% endfor %}
</div>
{% endif %}
</div>
{% if popup_product.template_suffix == 'quantity-limit-1' %}
{% assign product_max_qty = 1 %}
{% for line_item in cart.items %}
{% if popup_product.id == line_item.product_id %}
{% assign disable_btn = true %}
{% endif %}
{% endfor %}
{% elsif popup_product.template_suffix == 'quantity-limit-2' %}
{% assign product_max_qty = 2 %}
{% for line_item in cart.items %}
{% if popup_product.id == line_item.product_id %}
{% assign disable_btn = true %}
{% endif %}
{% endfor %}
{% elsif popup_product.template_suffix == 'quantity-limit-3' %}
{% assign product_max_qty = 3 %}
{% for line_item in cart.items %}
{% if popup_product.id == line_item.product_id %}
{% assign disable_btn = true %}
{% endif %}
{% endfor %}
{% elsif popup_product.template_suffix == 'quantity-limit-4' %}
{% assign product_max_qty = 4 %}
{% for line_item in cart.items %}
{% if popup_product.id == line_item.product_id %}
{% assign disable_btn = true %}
{% endif %}
{% endfor %}
{% elsif popup_product.template_suffix == 'quantity-limit' %}
{% assign product_max_qty = settings.product-max-quantity %}
{% for line_item in cart.items %}
{% if popup_product.id == line_item.product_id %}
{% assign disable_btn = true %}
{% endif %}
{% endfor %}
{% endif %}
<div class="row {% unless disable_btn == blank %} hidden{% endunless %}">
<div class="col-sm-4 quantity-wrap">
{% unless price_is_poa %}
<div class="form-group">
<input class="form-control input-lg" type="number" id="quantity" placeholder="Quantity" name="quantity" value="1" min="0"{% if product_max_qty %} max="{{ product_max_qty }}"{% endif %} />
</div>
{% endunless %}
</div>
<div class="col-sm-8 add-to-cart-button-wrap">
{% unless price_is_poa %}
<div class="form-group">
{% if popup_product.template_suffix == 'preorder' %}
{% assign cart_label = 'Preorder' %}
{% else %}
{% assign cart_label = 'Add to cart' %}
{% endif %}
<input type="submit" name="add" value="{% include '__localize' with cart_label %}" id="purchase" class="btn-main purchase-btn {% if popup_product.template_suffix == 'preorder' %}preorder-btn{% endif %}" />
</div>
{% endunless %}
{% if settings.secondary-call-to-action-url != blank %}
<p class="secondary-call-to-action"><br><em>{% include '__localize' with settings.secondary-call-to-action-text %}</em><br><a href="{{ settings.secondary-call-to-action-url }}?title={{ popup_product.title | replace: ' ', '%20' }}&handle={{ popup_product.handle }}"><strong>{% include '__localize' with settings.secondary-call-to-action-link-text %}</strong></a></p>
{% endif %}
{% if settings.show-social-share-links %}
<div class="share-icons">
{% capture tweet %}https://twitter.com/intent/tweet?text={% include '__localize' with 'Check out' %} {{ page_title }}—{{ canonical_url }}{% unless settings.social-links-twitter == blank %} (via @{{ settings.social-links-twitter | split: '/' | last }}){% endunless %}{% endcapture %}
{% capture email_subject %}{% include '__localize' with 'Check out' %} {{ page_title }}{% endcapture %}
{% capture email_body %}{% include '__localize' with 'Hey' %}, {% include '__localize' with 'I was just looking at' %} {{ page_title }} {% include '__localize' with 'on' %} {{ shop.name }} {% include '__localize' with 'and wanted to share it with you' %}. {% include '__localize' with 'Check out' %} {{ canonical_url }}{% endcapture %}
Share:
<a href="{{ tweet | replace: ' ','%20' }}" target="_blank"><i class="fa fa-twitter fa-fw"></i></a>
<a href="https://www.facebook.com/sharer/sharer.php?u={{ canonical_url }}" target="_blank"><i class="fa fa-facebook fa-fw"></i></a>
<a href="http://pinterest.com/pin/create/button/?url={{ canonical_url }}&media={{ popup_product.featured_image.src | product_img_url: '2048x2048' }}&description={{ page_title | replace: ' ','%20' }}" target="_blank"><i class="fa fa-pinterest fa-fw"></i></a>
<a href="mailto:?subject={{ email_subject | replace: ' ','%20' }}&body={{ email_body }}" target="_blank"><i class="fa fa-envelope fa-fw"></i></a>
</div>
{% endif %}
</div>
</div>
</form>
{% if settings.show-notify-me %}
<div class="row notify-me-wrapper">
<div class="col-xs-12">
{% form 'contact' %}
<div class="notify-me-form well">
<h3>{{ popup_product.title }} is unavailable</h3>
<p>{% include '__localize' with 'Leave your email address if you would like to be notified when it becomes available.' %}</p>
<div class="alert" style="display: none"></div>
<div class="form-group">
<input type="hidden" name="contact[body]" value="Please notify me when {{ popup_product.title | escape }} becomes available." />
<div class="input-group">
<input class="form-control input-lg{% if form.errors contains 'email' %} error{% endif %}" id="{% include '__advanced-layout-id' with 'notify-input' %}" required="required" type="email" name="contact[email]" placeholder="your@email.com" value="{{ contact.fields.email }}" />
<span class="input-group-btn">
<input class="btn btn-primary btn-lg" type="submit" value="{% include '__localize' with 'Notify me' %}" >
</span>
</div>
</div>
</div>
{% endform %}
</div>
</div>
<hr>
{% endif %}
<!-- <script>
jQuery(function() {
// option selectors extended with boostrap markup and link options
new Shopify.BootstrapifyOptionSelectors("{% include '__advanced-layout-id' with 'product-select' %}", { product: {{ popup_product | json }}, onVariantSelected: selectCallback, enableHistoryState: true{% unless settings.show-unavailable-products %}, linkOptions: true {% endunless %}});
{% for option in popup_product.options %}
console.log("this is an option in product.options: {{option}}");
$('.popup-single-option-selector:eq({{ forloop.index0 }})').prepend('<option class="popup-appended" value="">Pick a {{ popup_product.options[forloop.index0] }}</option>').val('').trigger('change');
{% endfor %}
{% if popup_product.template_suffix == 'quantity-limit' %}
$('.purchase-btn').on('click', function() {
$('#product-form .row').hide();
});
{% endif %}
});
</script> -->
SETTINGS SCHEMA
settings_schema.json contains all the necessary admin settings for the popup to function properly.
{
"name": "Product Upsell",
"settings": [
{
"type": "header",
"content": "Upsell When Price is X"
},
{
"type": "checkbox",
"id": "upsell-price-enable",
"label": "Enable Product Upell based on price threshold ie if cart price is greater than x show popup",
"default": false
},
{
"type": "product",
"id": "upsell-price-show",
"label": "Choose the product that shows on popup"
},
{
"type": "textarea",
"id": "upsell-price-message",
"default": "You Qualify for an Exclusive Offer"
},
{
"type": "text",
"id": "upsell-price",
"label": "Enter the price threshold without currenty symobols or period. Last two digits are decimal points. E.G. 1000 instead of $10.00"
},
{
"type": "header",
"content": "Upsell on Product Pages"
},
{
"type": "checkbox",
"id": "upsell-product-enable",
"label": "Enable Product Upsell on Product Pages",
"default": false
},
{
"type": "product",
"id": "upsell-product-show",
"label": "Choose product that shows on popup"
},
{
"type": "textarea",
"id": "upsell-product-message",
"default": "You Qualify for an Exclusive Offer"
},
{
"type": "select",
"id": "upsell-product-trigger-option",
"label": "Choose how the product upsell will fire, if nothing selected the default will be all products",
"options": [
{
"value": "upsell-product-trigger-option-all",
"label": "Display on all products"
},
{
"value": "upsell-product-trigger-option-product",
"label": "Display on a single product"
},
{
"value": "upsell-product-trigger-option-collection",
"label": "Display on every product within a specific collection"
}
]
},
{
"type": "product",
"id": "upsell-product-trigger",
"label": "(Display on single product) Choose product that triggers the upsell"
},
{
"type": "collection",
"id": "upsell-product-collection",
"label": "(Display within specific collection) Choose collection whose containing products' pages will trigger upsell"
},
{
"type": "header",
"content": "Strict Enfore: Remove Upsell Products when Conditions Not Met"
},
{
"type": "checkbox",
"id": "upsell-enforce",
"default": false,
"label": "This should not be enabled if the upsell products are generic and regularly purchasable throughout the store. Enabling this option will add javascript to ensure conditions for upsell are met before checkout. The script will remove instances of the upsell items if conditions are false."
}
]
}