How to Enable a Custom Wishlist Modal

If you don’t want to pull your customers away from their journey on your site, a wishlist pop-up (or modal) can be a great option. Rather than sending them to a separate wishlist page, it creates a pop-up that appears on top of the page they are viewing. This allows customers to access items in their wishlist and then seamlessly return to browsing your site. 

On top of this, the wishlist modal is fully customizable. You can change styles, fonts, and colors to match the branding of your site. This helps build trust and creates a consistent experience for your customers. 

How to Enable a Custom Wishlist Pop-Up

Step 1: Create a snippet to store the wishlist pop-up

Create a new snippet file called “wishlist-modal”.

Add the following code to enable a launch button which will open the modal. For example, if you would like the launch button to show up on the header. You can copy and paste this code into the liquid file which renders the header section.

<!-- Trigger/Open the Modal -->
<a onclick="document.getElementById('wishlistModalBox').style.display='block'" class="swym-wishlist">
  <i aria-hidden="true" focusable="false" role="presentation" class="icon icon-swym-wishlist"></i>
</a>

Then add the following code to enable a launch button which would open the modal. For example, if you would like the launch button to show up on the header. You can copy and paste this code on the liquid file which renders the header section.

<!-- The Modal -->
<div id="wishlistModalBox" class="w3-modal">
  <div class="w3-modal-content text-left">
    <header class="w3-container w3-teal">
      <span onclick="document.getElementById('wishlistModalBox').style.display='none'"
            class="w3-button w3-display-topright">&times;</span>
      <h2>Wishlist</h2>
    </header>
    <div class="w3-container">
      <br>
      {% include 'swym-custom-wishlist' %}
      <br>
    </div>
    <footer class="w3-container w3-teal">
      <p>Modal Footer</p>
    </footer>
  </div>
</div>

Include the modal CSS file:

{% include 'wishlist-modal-css' %}

Step 2: Create a new snippet for the pop-up styles

Create a new snippet file called “wishlist-modal-css”.

Then add the CSS from this gist.

Note: This CSS only affects the pop-up itself. We’ll add CSS for the rendered wishlist elements in Step 5.

Step 3. Create a new snippet to store the wishlist elements

Create a new snippet file called “swym-custom-wishlist”.

Add the code below to the snippet you just created

<!-- Custom WL Snippet -->
<div class="page-width">
  <div class="grid swym-grid">
    <div class="grid__item medium-up--five-sixths medium-up--push-one-twelfth">
      <div class="section-header text-center">
        <h1>My Wishlist</h1>
      </div>
      <div class="rte">
        {{ page.content }}
        <div id="wishlist-items-container">
        </div>
      </div>
    </div>
  </div>
</div>
  <script src="{{ 'swym-custom-wishlist.js' | asset_url }}" async="async"></script>
  <!-- Swym Custom Page CSS  -->
  {% include 'swym-custom-wishlist-page-css'%}

Step 4: Add the wishlist rendering JavaScript

Add a new asset called “swym-custom-wishlist.js”.

Then add the following code in your new .js file:

/* Product Tile Markup - You can play around with this to change the
information that appears on the Wishlisted Product tiles  */
var productCardMarkup = `<div class="swym-wishlist-grid">
   {{#products}} 
   <a href="{{du}}"aria-label="{{dt}}" class="swym-wishlist-item swym-is-anchor">
     <button id="swym-remove-productBtn" aria-label="Delete" data-variant-id="{{epi}}" data-product-id="{{empi}}" class="swym-delete-btn swym-nav swym-nav-1 swym-is-button">
       <span class="swym-icon">
       </span>
     </button>
     <div class="swym-wishlist-image-wrapper">
       <img alt="" class="swym-wishlist-image" src="{{iu}}">
     </div>
     <button class="swym-is-button">
       <div class="swym-title swym-title-1">
         {{dt}}
       </div>
     </button>
     <div class="swym-variant-title swym-text swym-title-2 swym-variant-title-spacer">
       {{variantinfo}}
     </div>
     <div class="swym-product-price swym-text swym-text-1">
       <div class="swym-product-final-price swym-value">
         {{cu}}{{pr}}
       </div>
     </div>
     <button id="swym-custom-add-toCartBtn" data-state-cart="{{#isInCart}} swym-added{{/isInCart}}" data-product-url="{{du}}" data-variant-id="{{epi}}" data-product-id="{{empi}}" class="swym-add-to-cart-btn swym-button swym-button-1 swym-is-button swym-is-button">
       {{#isInCart}}Added to cart{{/isInCart}}{{^isInCart}}Add to cart{{/isInCart}}
     </button>
   </a>
   {{/products}}
</div>`;

function getVariantInfo(variants) {
	try {
		let variantKeys = ((variants && variants != "[]") ? Object.keys(JSON.parse(variants)[0]) : []),
			variantinfo;
		if (variantKeys.length > 0) {
			variantinfo = variantKeys[0];
			if (variantinfo == "Default Title") {
				variantinfo = "";
			}
		} else {
			variantinfo = "";
		}
		return variantinfo;
	} catch (err) {
		return variants;
	}
}

function onAddToCartClick(e) {
	e.preventDefault();
	var productId = e.currentTarget.getAttribute("data-product-id");
	var variantId = e.currentTarget.getAttribute("data-variant-id");
	var du = e.target.getAttribute("data-product-url");
	e.target.innerHTML = "Adding..";
	window._swat.replayAddToCart({
		empi: productId,
		du: du
	}, variantId, function(c) {
		e.target.innerHTML = "Added to Cart";
		e.target.setAttribute("data-state-cart", "swym-added");
		console.log("Successfully added product to cart.", c);
	}, function(e) {
		console.log(e);
	});
}

function onRemoveBtnClick(e) {
	e.preventDefault();
	var epi = +e.currentTarget.getAttribute("data-variant-id");
	var empi = +e.currentTarget.getAttribute("data-product-id");
	window._swat.fetch(function(products) {
		products.forEach(function(product) {
			if (epi && empi && product.epi == epi && product.empi == empi){
				window._swat.removeFromWishList(product, function() {
					if (!window.SwymCallbacks) {
						window.SwymCallbacks = [];
					}
					window.SwymCallbacks.push(swymRenderWishlist);
				});
			}
		});
	})
}

function swymRenderWishlist(swat) {
	// Get wishlist items
	swat.fetch(function(products) {
		console.log(products)
		var wishlistContentsContainer = document.getElementById("wishlist-items-container");
		var formattedWishlistedProducts = products.map(function(p) {
			p = SwymUtils.formatProductPrice(p); // formats product price and adds currency to product Object
			p.isInCart = _swat.platform.isInDeviceCart(p.epi) || (p.et == _swat.EventTypes.addToCart);
			p.variantinfo = (p.vi ? getVariantInfo(p.vi) : "");
			return p;
		});
		var productCardsMarkup = SwymUtils.renderTemplateString(productCardMarkup, {
			products: formattedWishlistedProducts
		});
		if(wishlistContentsContainer){
			wishlistContentsContainer.innerHTML = productCardsMarkup;
			attachClickListeners();
		} else{
		  console.log("Container not found, Wishlist Page element not found");
		}
	});
}

function attachClickListeners() {
	var addToCartButtons = document.querySelectorAll("#swym-custom-add-toCartBtn");
	var removeBtns = document.querySelectorAll("#swym-remove-productBtn");
	//   Add to cart Btns
	for (var i = 0; i < addToCartButtons.length; i++) {
		addToCartButtons[i].addEventListener('click', onAddToCartClick, false);
	}
	//   Remove Buttons
	for (var k = 0; k < removeBtns.length; k++) {
		removeBtns[k].addEventListener('click', onRemoveBtnClick, false);
	}
	console.log("Events attached!");
}

if (!window.SwymCallbacks) {
	window.SwymCallbacks = [];
}
window.SwymCallbacks.push(swymRenderWishlist); /* Init Here */

Here is an explanation of each function used: 

productCardMarkup – This is the HTML template that will be used to display each product in the wishlist section.
getVariantInfo – This function gets variant information for each product.
onAddToCartClick – This function adds a product to the cart from the wishlist when clicked. 
onRemoveBtnClick – This function removes a product from the wishlist when clicked.
swymRenderWishlist – This function is responsible for rendering the wishlist.
attachClickListeners – This function adds events to the “Add to Cart” and “Remove” buttons respectively.

Step 5: Add the wishlist section CSS

Create a new snippet called “swym-custom-wishlist-page-css”.

Add CSS in your new file. You have two options:

  1. You can apply your own CSS to the elements, allowing you better control over the UI assets.
  2. You can use the CSS code below which we use in our default modal.
<style class="custom-swym-wishlist-css">
  #wishlist-items-container {
    max-width: 1180px;
    margin: auto;
  }
  #wishlist-items-container .swym-wishlist-grid {
    max-width: 900px;
    margin: auto;
    width: 100%;
    display: flex;
    flex-wrap: wrap;
    justify-content: left;
  }
  .swym-wishlist-grid .swym-is-anchor {
    opacity: 1;
    cursor: pointer;
    text-decoration: none;
    touch-action: manipulation;
  }
  .swym-wishlist-grid * {
    font-size: 100%;
    font: inherit;
    font-family: "HelveticaNeue",Helvetica,Verdana,Arial,sans-serif;
    line-height: 1.4em;
    vertical-align: baseline;
    box-sizing: border-box;
    border: 0;
    -moz-box-sizing: border-box;
    -ms-box-sizing: border-box;
    -webkit-box-sizing: border-box;
    margin: 0;
    padding: 0;
    text-transform: none;
  }
  a.swym-wishlist-item.swym-is-anchor {
    background: #fff;
    border: 1px solid #333;
    width: 21%;
    margin: 0 4% 4% 0;
    display: flex;
    flex-direction: column;
    position: relative;
    justify-content: space-between;
    cursor: pointer;
  }
  button.swym-delete-btn.swym-nav.swym-nav-1.swym-is-button {
    position: absolute;
    right: 8px;
    top: 8px;
    width: 25px;
    height: 25PX;
    background: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .swym-wishlist-grid .swym-wishlist-image-wrapper {
    overflow: hidden !important;
    height: 180px;
  }
  .swym-wishlist-grid .swym-wishlist-image-wrapper img {
    max-width: 100%;
  }
  .swym-wishlist-grid .swym-is-button {
    text-align: left;
    background: inherit;
    height: auto;
    width: auto;
    z-index: auto;
    display: inline-block;
    background: 0;
    border: 0;
    text-transform: none;
    bottom: auto;
    box-shadow: none;
    clear: none;
    cursor: pointer;
    font-family: inherit;
    font-size: medium;
    font-style: normal;
    font-variant: normal;
    font-weight: normal;
    height: auto;
    left: auto;
    letter-spacing: normal;
    line-height: normal;
    margin: 0;
    max-height: none;
    max-width: none;
    min-height: 0;
    min-width: 0;
    opacity: 1;
    padding: 0;
    position: static;
    right: auto;
    text-align: inherit;
    text-decoration: none;
    text-transform: none;
    top: auto;
    transform: none;
    visibility: visible;
  }
  .swym-wishlist-grid .swym-wishlist-item .swym-delete-btn ::before {
    color: #000;
    content: "X";
    font-size: 16px;
  }
  button.swym-add-to-cart-btn.swym-button.swym-button-1.swym-is-button.swym-is-button {
    z-index : 1000;
  }
  button.swym-delete-btn.swym-nav.swym-nav-1.swym-is-button {
    z-index : 1000;
  }
  .swym-is-button .swym-title.swym-title-1 {
    font-weight: bold;
    font-size: 16px;
    color: #4f4f4f;
    margin: 12px 15px 6px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .swym-wishlist-grid .swym-wishlist-item .swym-variant-title {
    font-size: 14px;
    line-height: 16px;
    color: #333;
    margin: 0 15px 10px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .swym-wishlist-grid .swym-wishlist-item .swym-product-price {
    color: #333;
    font-weight: bold;
    font-size: 18px;
    padding: 0 15px 13px;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
  }
  .swym-wishlist-grid .swym-product-price .swym-product-final-price {
    display: inline-block;
    margin-right: .4em;
  }
  .swym-wishlist-grid .swym-wishlist-item .swym-add-to-cart-btn {
    background: #dc3b1a;
    font-weight: bold;
    font-size: 14px;
    text-align: center;
    text-transform: uppercase;
    padding: 6px;
    display: block;
    color: #fff;
  }
  /*   Mobile Screens   */
  @media only screen and (max-width: 900px){
    #wishlist-items-container .swym-wishlist-grid .swym-wishlist-item {
      width: 48%;
      max-width: none;
      margin: 0 4% 4% 0;
    }
    #wishlist-items-container .swym-wishlist-grid .swym-wishlist-item {
      width: auto ;
      margin: 0 0 4% 0;
      padding: 0px;
    }
    #wishlist-items-container .swym-wishlist-grid {
      justify-content: center;
    }
  }
  /*   Ipad   */
  @media only screen 
    and (min-device-width: 768px) 
    and (max-device-width: 1024px) 
    and (-webkit-min-device-pixel-ratio: 1) {
      .swym-wishlist-grid .swym-wishlist-image-wrapper {
        overflow: hidden !important;
        height: 280px;
      }
    }
  /* Landscape */
  @media only screen 
    and (min-device-width: 768px) 
    and (max-device-width: 1024px) 
    and (orientation: landscape) 
    and (-webkit-min-device-pixel-ratio: 1) {
      .swym-wishlist-grid .swym-wishlist-image-wrapper {
        overflow: hidden !important;
        height: 100px;
      }
    }
  button#swym-custom-add-toCartBtn[data-state-cart="swym-added"]{
    background : green;
  }
  
  /* Add your own CSS here */

</style>

Step 6. Activate the wishlist modal

With the necessary elements created it’s time to add the wishlist pop-up to your store’s frontend. You can place the button that launches the pop-up wherever you prefer. 

Most sites include it in the header. That’s what we’ll use for this example.

Navigate to the Header file. In this case, it is “header.liquid”.

Note: This file can be different depending on your theme. If you’re unsure which file is correct, please contact your theme developer and they’ll be able to identify it for you.

Include the “wishlist-modal” snippet in the correct location.

{% include 'wishlist-modal' %}

If you have a hard time adding a wishlist pop-up or have a question, please email us and we’d be happy to help.

You can find the example files used in this documentation here.

Frequently Asked Questions

I’ve implemented the custom wishlist but I keep getting this error: Container not found, swym-custom-wishlist….:81
Wishlist Page element not found

Please check to see if you’ve included

<div id="wishlist-items-container"></div>

in your page code. The render function picks up this element and it is necessary to display the wishlist products correctly.

I can see the wishlist section but the products are not displayed and there are no errors in the console

First check to see if you’ve implemented a wishlist section elsewhere on the same page. Our app only renders the wishlist section once on any given page.

For example, if you’ve implemented a wishlist section on the page, the code might get rendered before the wishlist pop-up code.

How can I add other functionality to this Wishlist section?

Please refer to our API documentation to add the available wishlist features to your section. You can add any buttons you’d like to the wishlist. 

Be sure to connect each button to its respective JavaScript function in “swym-custom-wishlist.js” and add the necessary CSS to the “swym-custom-wishlist-page-css.liquid” file.

I’ve added CSS to customize this feature but my changes are not being reflected

First, make sure you’re adding your custom CSS in the right file.

“wishlist-modal-css.liquid” affects the style of the pop-up. Meanwhile, “Swym-custom-wishlist-page-css.liquid” defines the style of the wishlist items being rendered (all the contents inside <div class=”w3-container”>).

Save for Later - Early Access

Let's discuss your needs!

Let's discuss your needs!

Let's discuss your needs!