Sale Sticker

You’ll need to add the following to your product-template.liquid

This code will go inside the div tag with the class=”product-single__photo-wrapper” before the tag is closed so it shows up on top of the product image.

<!-- If the product is sold out show a sticker saying Sold Out!-->
{% if product.available == false %}
  <div class="sticker__sold-out">
    <p style="font-weight:bold; padding:12.5px 0;">{{ 'products.product.sold_out_html' | t }}</p>
  </div>
<!-- Else if the product is on special show amount saved-->
{% elsif product.compare_at_price_max > product.price and product.price != 0 and product.available != false %}
  <div class="sticker__on-sale">         
    <p style="font-weight:bold; padding:12.5px 0;">Save<br/>{{ product.compare_at_price_max | minus: product.price | times: 100.0 | divided_by: product.compare_at_price_max | money_without_currency | times: 100 | remove: '.0'}}%</p>
  </div>
<!-- Else if the product is $0 show a sticker saying Free!-->
{%elsif product.price == 0 %}
  <div class="sticker__on-sale">
    <p style="font-weight:bold; padding:22.5px 0;">FREE!</p>
  </div>
{% endif %}

You’ll also need to add this to your custom.css or custom.scss.liquid file

.sticker__sold-out, .sticker__on-sale {
  position: absolute;
  background: crimson;
  border: 1px solid crimson;
  width: 70px;
  height: 70px;
  border-radius: 35px;
  top: -15px;
  left: -15px;
}
.sticker__sold-out p, .sticker__on-sale p {
  font-family: "Montserrat", "HelveticaNeue", "Helvetica Neue", sans-serif;
  font-size: 0.8em;
  font-weight: 400;
  font-style: normal;
  letter-spacing: 0.1em;
  font-weight: bold;
  text-transform: uppercase;
  color: #FFF;
}

 

Someone recently purchased this item

from recently purchased the Majestic Unicorn

This was created as a little challenge for myself originally to see if I could create a social proof model with freely available random user data and it turned out pretty well. Next step is creating an app that pulls real orders from shopify.

I’ve added comments to it all so even non-coders can get a general idea of how it all works.

Please Note: I don’t suggest using this in a real store scenario as it’s all fake/random data.

If you do decide to use this, keep in mind that there are only a certain number of profile pictures which will regenerate with new random names, just refresh constantly and you’ll see for yourself.

Without futher ado, heres all the code!

Assuming you’re using Shopify and the Brooklyn theme you would add this code into your product-template.liquid file where you would like it shown.

<div class="grid no-marg-left">
  <div class="grid__item user-purchase">
    <div class="grid">
      <div class="grid__item one-quarter">
      <img id="user-pic" />
      </div>
      <div class="grid__item three-quarters">
        <div class="user-details text-left">
          <span id="fName"></span> from <span id="city"></span> recently purchased the {{product.title}}
        </div>
        <p id="user-date" class="text-left"></p>
      </div>
    </div>
  </div>
</div>

 

In your Assets folder create a new file and name it user-purchase ending with .css and copy paste this code below.

/* fixes up margin issues to display properly*/

.no-marg-left {
	margin-left: 0px;
}

/* This makes the user image round rather than square */

#user-pic {
	border-radius: 50%;
}

/* font-size to work with my theme design and margin to work with social sharing buttons underneath */

.user-details {
	font-size: 14px;
	margin-bottom: 10px;
}

/* smaller font size and more greyed out color for the date/time details */

#user-date {
	margin-bottom: 9px;
	font-size: 12px;
	color: #717171;
}

/* This is all the "user" details that will pop up */

.user-purchase {
	/* This border was added to work with my design */
	/* border-top: 1px solid #e3e3e3; */
	padding: 10px 0;
	margin-top: 10px;
	/* This will make sure nothing is shown at first*/
	display: none;
}
.user-details span {
	/* Fixes the spacing issue for the #city underline(border-bottom) */
	display: inline-block;
}
#fName {
	/* Makes the name bold */
	font-weight: bold;
}

/* Dotted underline for the city */

#city {
	border-bottom: 1px dotted #000;
	text-decoration: none;
}

Make sure you also call it by adding this line of code into your theme.liquid file

{{ 'user-purchase.css' | asset_url | stylesheet_tag }}

In your Assets folder create a new file and name it user-purchase ending with .js and copy paste this code below.

// Only runs after page is loaded
$(document).ready(function() {
	// Makes sure all the user information is hidden to begin
  $(".user-purchase").hide().fadeIn(3000).fadeOut(3000);
  //// Only runs after element is loaded
  $(".user-purchase").ready(function() {
		//function to capitalize first letter of each word as the API sends everything lowercase 
    $.fn.capitalize = function() {

      return this.each(function() {
        var $this = $(this),
          text = $this.text(),
          tokens = text.split(" ").filter(function(t) {
            return t != "";
          }),
          res = [],
          i,
          len,
          component;
        for (i = 0, len = tokens.length; i < len; i++) {
          component = tokens[i];
          res.push(component.substring(0, 1).toUpperCase());
          res.push(component.substring(1));
          res.push(" "); // put space back in
        }
        $this.text(res.join(""));
      });
    };
		// Calls the API and data
    $.ajax({
    	// You can customize nationality, gender and do much more
      // Check out the documentation for more info here
      // https://randomuser.me/documentation
      
      // Calling API and specifying nationalities US, AU & NZ to be generated
      url: 'https://randomuser.me/api/?nat=us,au,nz,gb&gender=female',
      dataType: 'json',
      success: function(data) {
				
        //just to shorten code when calling each variable
        var api = data.results["0"];
				
        // You can call mutiple variables like first name, last name, city, state and post code
        // For more info check out the Results section https://randomuser.me/
        // Below are are few examples of what has been added in so far
        
        //Requests first name and adds it to the ID fName
        $('#fName').html(api.name.first);
        //Requests city and adds it to the ID city
        $('#city').html(api.location.city);
         //Requests state and adds it to the ID state
        $('#state').html(api.location.state);
         //Requests user image and adds it to the link to the img tag with the class user-pic 
        $('#user-pic').attr("src", api.picture.medium);

				// Capitalizes variables first name, city and state
        $('#fName,#city,#state').capitalize();
      }

    });
		// Function to generate a date between 2 dates
    function randomDate(start, end) {
      var genDate = new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime()));
      var formattedDate = dateFormat(genDate, "dddd, mmmm dS yyyy 'at' h:MMTT");
      $('#user-date').append(formattedDate);

    }
		
    // creating old date
    var daysAgo = new Date();
    // Amount of days ago - you can change this to however many days you would like 
    var days = 3;
    daysAgo.setDate(daysAgo.getDate() - days);
		
    //calls the randomDate function to call a date between the daysAgo you set and today
    randomDate(daysAgo, new Date());
		
    // fades in all the information 3 seconds (3000 miliseconds) after the page and element has loaded
    $(".user-purchase").hide().fadeIn(3000); //animating
  });
});

Make sure you also call it by adding this to the bottom of your product-template.liquid file above {% schema %}

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js">
{{ 'user-purchase.js' | asset_url | script_tag }}

You will also need to download and upload Steven Levithan’s date.format.js code and upload it to your Assets folder

http://stevenlevithan.com/assets/misc/date.format.js

Make sure you also call it by adding this to the bottom of your product-template.liquid file too.

{{ 'date.format.js' | asset_url | script_tag }}

 

Product Tabs

Product Description

 

 

Product Reviews

 

 

Why shop with us?

 

 

Assuming you’re using Shopify and the Brooklyn theme you would add this code into your product-template.liquid file where you would like it shown.

<div class="grid">
  <div class="grid__item">
    <ul class="tabs">
      <li class="tab-link current" data-tab="tab-1">
        <p class="tab-title" for="tab-1">Product Description</p>
      </li>
      <li class="tab-link" data-tab="tab-2">
        <p class="tab-title" for="tab-2">Product Reviews</p>
      </li>
      <li class="tab-link" data-tab="tab-3">
        <p class="tab-title" for="tab-3">Why Shop With Us?</p>
      </li>
    </ul>
    <section class="tab-content current" id="tab-1">
      <div class="text-center">
        <h3>Product Description</h3>
      </div>
      <div class="product-single__description rte" itemprop="description">
        {{ product.description }}
      </div>
    </section>
    <section class="tab-content" id="tab-2">
      <div data-id="{{product.id}}" id="shopify-product-reviews">
        {{ product.metafields.spr.reviews }}
      </div>
    </section>
    <section class="trusted tab-content" id="tab-3">
      <div class="text-center">
        <h3>Why shop with us?</h3>
      </div>
    </section>
  </div>
</div>

 

Add this to the bottom of your product-template.liquid file above {% schema %}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>
//This is the code that will change the content when tabs are pressed
$(document).ready(function(){
  
  $('ul.tabs li').click(function(){
    var tab_id = $(this).attr('data-tab');

    $('ul.tabs li').removeClass('current');
    $('.tab-content').removeClass('current');

    $(this).addClass('current');
    $("#"+tab_id).addClass('current');
  })

})
</script>

In your Assets folder create a new file and name it custom-tabs ending with .css and copy paste this code below.

.tabs {
  margin: 0;
  list-style: none;
  padding: 0;
  display: table;
  table-layout: fixed;
  width: 100%;
  background: #FAFAFA;
}
.tab-content {
  padding: 20px 0 0;
}
.tab-link {
  display: inline-block;
  margin: 0 0 -1px;
  padding: 15px 25px;
  text-align: center;
  font-weight: 600;
  color: #bbb;
  border: 1px solid transparent;
  border-bottom: 1px solid #ddd;
  display: table-cell;
}

.tab-link:hover {
  color: #888;
  cursor: pointer;
}

/* .tab-link:first-child{
  border-left:none !important; 
}

.tab-link:last-child{
  border-right:none !important; 
} */

.tab-link.current {
  color: #555;
  border: 1px solid #ddd;
  border-top: 2px solid orange;
  border-bottom: 1px solid #fff;
  background: #FFF;
}

.tab-title {
  display: block;
}
.tab-content {
  display: none;
}
.tab-content.current {
  display: block;
}

.tab-link p {
  margin: 0;
}

.tab-title:before {
  font-family: fontawesome;
  font-weight: normal;
  margin-right: 10px;
}
.tab-title[for*='1']:before {
  content: '\f129';
}
.tab-title[for*='2']:before {
  content: '\f005';
}
.tab-title[for*='3']:before {
  content: '\f128';
}
@media screen and (max-width: 650px) {
  .tab-title {
    font-size: 0;
  }
  .tab-title:before {
    margin: 0;
    font-size: 18px;
  }

}
@media screen and (max-width: 400px) {
  .tab-title {
    padding: 15px;
  }
}

 

Make sure you also call it by adding this line of code into your theme.liquid file

{{ 'custom-tabs.css' | asset_url | stylesheet_tag }}

Font Awesome is required to show the icons so make sure you also call it by adding this line of code into your theme.liquid file or visit their website https://fontawesome.io for the latest version

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.css">

 

 

 

 

Countdown Timer

0

Days

1

Hours

23

Minutes

36

Seconds

This countdown timer is almost identical to the conversionpirate countdown timer.

All I’ve done is:
– Tidy up some of the code by closing tags and indenting it.
– Make the progress bar animate the stripes.

There are probably a few more things I could fix up but for now this does what I want and looks damn good doing it!


Assuming you’re using Shopify and the Brooklyn theme you would add this code into your product-template.liquid file.

We suggest experimenting to see where you think it will work best when it comes to your theme.

<!-- Countdown Timer-->
              <div class="items-count" id="progress_bar"></div>
                <div id="clock-ticker" class="clearfix">
                  <div class="block">
                    <span class="flip-top" id="numdays">0</span>
                    <br>
                    <span class="label">Days</span>
                  </div>
                  <div class="block">
                    <span class="flip-top" id="numhours">1</span>
                    <br>
                    <span class="label">Hours</span>
                  </div>
                  <div class="block">
                    <span class="flip-top" id="nummins">23</span>
                    <br>
                    <span class="label">Minutes</span>
                  </div>
                  <div class="block">
                    <span class="flip-top" id="numsecs">36</span>
                    <br>
                    <span class="label">Seconds</span>
                  </div>
                </div>

 

In your Assets folder create a new file and name it countdown-timer ending with .js and copy paste this code below.

I haven’t added any comments to this other than the line that I’ve changed.
I plan to either re-write or comment this one in the near future. For now I’m just putting up all the code as quickly as possible for ya’ll!

  function randomIntFromInterval(min, max) {
      return Math.floor(Math.random() * (max - min + 1) + min);
  }

  var total_items = 50;
  var d = new Date();
  var min_items_left = 12;
  var max_items_left = 20;
  var remaining_items = randomIntFromInterval(min_items_left, max_items_left);
  var min_of_remaining_items = 1;
  var decrease_after = 1.7;
  var decrease_after_first_item = 0.17;

  (function($) {
      $.fn.progressbar = function() {
          var a = "<p>Hurry! Only <span class='count'>" + remaining_items + "</span> left in stock.</p>" + "<div class='progressbar '><div style='width:100%'></div></div>";
          this.addClass('items-count');
          this.html(a + this.html());
          updateMeter(this);
          var b = this;
          setTimeout(function() {
              remaining_items--;
              if (remaining_items < min_of_remaining_items) {
                  remaining_items = randomIntFromInterval(min_items_left, max_items_left);
              }
              $('.count').css('background-color', '#CE0201');
              $('.count').css('color', '#fff');
              setTimeout(function() {
                  $('.count').css('background-color', '#fff');
                  $('.count').css('color', '#CE0201');
              }, 1000 * 60 * 0.03);
              b.find(".count").text(remaining_items);
              updateMeter(b);
          }, 1000 * 60 * decrease_after_first_item);
          setInterval(function() {
              remaining_items--;
              if (remaining_items < min_of_remaining_items) {
                  remaining_items = randomIntFromInterval(min_items_left, max_items_left);
              }
              $('.count').css('background-color', '#CE0201');
              $('.count').css('color', '#fff');
              setTimeout(function() {
                  $('.count').css('background-color', '#fff');
                  $('.count').css('color', '#CE0201');
              }, 1000 * 60 * 0.03);
              b.find(".count").text(remaining_items);
              updateMeter(b);
          }, 1000 * 60 * decrease_after);
      };

      function updateMeter(a) {
          var b = 100 * remaining_items / total_items;
          if (remaining_items < 10) {
              a.find('.progressbar div:first').addClass('less-than-ten');
          }
          a.find('.progressbar').addClass('active progress-striped');
          setTimeout(function() {
              myanimate(a.find('.progressbar div:first'), b);
               //This has been commented out so that the stripes would show and animate continuously
               //a.find('.progressbar').removeClass('active progress-striped');
          }, 1000);
      }
  }(jQuery));

  function myanimate(a, b) {
      var c = 0;
      var d = parseInt(a.closest('.progressbar').css('width'));
      var e = Math.floor(100 * parseInt(a.css('width')) / d);
      if (e > b) {
          c = e;
      }

      function frame() {
          if (e > b) {
              c--;
          } else {
              c++;
          }
          a.css('width', c + '%');
          if (c == b || c <= 0 || c >= 100) clearInterval(f);
      }
      var f = setInterval(frame, 40);
  }
  jQuery.noConflict()(function($) {
      $(document).ready(function() {
          $("#progress_bar").progressbar();
          var tag = "ctdn-12-12".match(/\d+/g);
          var hour = 14;
          var theDaysBox = $("#numdays");
          var theHoursBox = $("#numhours");
          var theMinsBox = $("#nummins");
          var theSecsBox = $("#numsecs");
          var d = new Date();
          var n = d.getDay();
          var date = 1;
          var gg = 0;
          var hh = 0;
          var ii = 0;
          var nsec = 0 - d.getSeconds();
          if (nsec < 0) {
              nsec = 60 - d.getSeconds();
              gg = 1;
          }
          var nmin = 0 - d.getMinutes() - gg;
          if (nmin < 0) {
              nmin = 60 - d.getMinutes() - gg;
              hh = 1;
          }
          var nhrs = 14 - d.getHours() - hh;
          if (nhrs < 0) {
              nhrs = 38 - d.getHours() - hh;
              ii = 1;
          }
          var ndat = date - 1;
          if (ndat < 0) {
              var mmon = d.getMonth();
              ndat = 30 + date - d.getDate() - ii;
          }
          theSecsBox.html(nsec);
          theMinsBox.html(nmin);
          theHoursBox.html(nhrs);
          theDaysBox.html(ndat);
          var refreshId = setInterval(function() {
              var e = theSecsBox.text();
              var a = theMinsBox.text();
              var c = theHoursBox.text();
              var b = theDaysBox.text();
              if (e == 0 && a == 0 && c == 0 && b == 0) {} else {
                  if (e == 0 && a == 0 && c == 0) {
                      theDaysBox.html(b - 1);
                      theHoursBox.html("23");
                      theMinsBox.html("59");
                      theSecsBox.html("59");
                  } else {
                      if (e == 0 && a == 0) {
                          theHoursBox.html(c - 1);
                          theMinsBox.html("59");
                          theSecsBox.html("59");
                      } else {
                          if (e == 0) {
                              theMinsBox.html(a - 1);
                              theSecsBox.html("59");
                          } else {
                              theSecsBox.html(e - 1);
                          }
                      }
                  }
              }
          }, 1000);
      });
  });

 

Make sure you also call it by adding this to the bottom of your product-template.liquid file above {% schema %}

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js">
{{ 'countdown-timer.js' | asset_url | script_tag }}

 

In your Assets folder create a new file and name it countdown-timer ending with .css and copy paste this code below.

#progress_bar {
  margin-top: 15px;
}
.progressbar.progressbar {
  background: whitesmoke;
  border: 0px solid whitesmoke;
  border-radius: 5px;
  height: 11px;
}
.progressbar.progressbar div {
  background: #d95350;
  border-radius: inherit;
  height: 11px;
}
.progress-striped.progressbar.progressbar.active div {
  -webkit-animation: stripes 2s linear infinite;
  	-moz-animation: stripes 2s linear infinite;
  	-ms-animation: stripes 2s linear infinite;
            animation: stripes 2s linear infinite;
}
.progress-striped.progressbar.progressbar div {
  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
    background-image:         linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, rgba(0, 0, 0, 0) 25%, rgba(0, 0, 0, 0) 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, rgba(0, 0, 0, 0) 75%, rgba(0, 0, 0, 0));
    background-size: 40px 40px;
  	
  	
}
.items-count {
  margin-top: 0px;
  margin-bottom: 0px;
}
.count {
  color: #a94442;
  padding: 1px;
}
.items-count p {
  padding-bottom: 5px;
  margin: 0;
  text-transform: uppercase;
  font-weight: 700;
  text-align: center;
  font-family: "Avant Garde",Avantgarde,"Century Gothic",CenturyGothic,"AppleGothic",sans-serif; 
}
.progressbar {
  position: relative;
  display: block;
  background-color: #ca0000;
  border: 1px solid #ddd;
  margin-bottom: 15px;
  -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
}
.progressbar>div {
  background-color: #ca0000;
  width: 0;
  margin-bottom: 0;
  height: 15px;
}
.progressbar>div.less-than-ten {
  background-color: #ca0000 !important;
}
#clock-ticker {
  display: block;
  margin-bottom: 15px;
}
#clock-ticker .block {
  position: relative;
  color: #383838;
  font-weight: bold;
  float: left;
  text-align: center;
  width: 25%;
}
#clock-ticker .block .flip-top {
  width: 88px;
  height: 39px;
  line-height: 40px;
  font-size: 40px;
  text-align: center;
}
#clock-ticker .block .label, span.flip-top {
  color: #383838;
  font-weight: bold;
  text-align: center;
  font-size: 14px;
  text-transform: uppercase;
  width: 88px;
  line-height: 25px;
  font-family: "Avant Garde",Avantgarde,"Century Gothic",CenturyGothic,"AppleGothic",sans-serif;
  
}


//All the animation keyframes for the stripes

@-webkit-keyframes stripes{
  from {
    background-position:40px 0;
  }to {
    background-position:0 0;
  }
}

@-moz-keyframes stripes{
  from {
    background-position:40px 0;
  }to {
    background-position:0 0;
  }
}


@keyframes stripes{
  from {
    background-position:40px 0;
  }to {
    background-position:0 0;
  }
}

Make sure you also call it by adding this line of code into your theme.liquid file.

{{ 'countdown-timer.css' | asset_url | stylesheet_tag }}

 

There are x people looking at this

 

 

🔥 There are people looking at this 🔥

 

How is this of any use?
It will create social proof and if you choose to use it in combination with a remaining products countdown timer some serious scarcity to help drive sales!

Assuming you’re using Shopify and the Brooklyn theme you would add this code into your product-template.liquid file.

We suggest experimenting to see where you think it will work best when it comes to your theme.

<p class="browsing-users">🔥 There are <b class="num"></b> people looking at this 🔥</p>


Edit:

WordPress automatically added extra code into this so there’s a fallback image if people don’t have emojis on their browsers which is a very good idea for everyone to have them show up.

Here is the css code so that the emoji shows up correctly. Add this code into your custom.scss.liquid file which is located in the Assets folder.

.emoji {
    display: inline !important;
    border: none !important;
    box-shadow: none !important;
    height: 1em !important;
    width: 1em !important;
    margin: 0 .07em !important;
    vertical-align: -0.1em !important;
    background: none !important;
    padding: 0 !important;
}

If you don’t have that file, you would have to create it in your Assets folder and make sure you also call it by adding this line of code into your theme.liquid file.

Please Note: If you already have this in your theme.liquid file you don’t need to add it again.

{{ 'custom.scss.css' | asset_url | stylesheet_tag }}

Add this to the bottom of your product-template.liquid file above {% schema %}



Dancing Add To Cart Button

 


 

Here’s a simple little bit of code to make your add to cart button dance!

How is this of any use?
The button moves around and draws attention without being annoying to potential customers.

Assuming you’re using Shopify and the Brooklyn theme you would add this code into your custom.scss.liquid file.

//This is the button ID
#AddToCart {
  //this calls the animation keyframes
  animation: shake 0.82s cubic-bezier(.36,.07,.19,.97) both;
  transform: translate3d(0, 0, 0);
  backface-visibility: hidden;
  perspective: 1000px;

  // How long the animation runs
  animation-duration: 6s;

  // Makes the button animate forever
  -webkit-animation-iteration-count: infinite;
  animation-iteration-count: infinite;
}


//These are the keyframes for all the animation of the button
@keyframes shake {
    from, 16%, to {
        -webkit-transform: translate3d(0, 0, 0);
        transform: translate3d(0, 0, 0);
    }
    1.6%, 4.8% {
        -webkit-transform: translate3d(-1px, 0, 0);
        transform: translate3d(-1px, 0, 0);
    }
    8%, 11.2%, 14.4% {
        -webkit-transform: translate3d(-4px, 0, 0);
        transform: translate3d(-4px, 0, 0);
    }
    9.6%, 12.8% {
        -webkit-transform: translate3d(4px, 0, 0);
        transform: translate3d(4px, 0, 0);
    }
    3.2%, 6.4% {
        -webkit-transform: translate3d(2px, 0, 0);
        transform: translate3d(2px, 0, 0);
    }
}

 

If you don’t have that file you would have to create it in your Assets folder and make sure you also call it by adding this line of code into your theme.liquid file.

{{ 'custom.scss.css' | asset_url | stylesheet_tag }}