Conditional click events on a Youtube Video (check state if playing or stopped)

I wanted to create on click events:

  • When the video playing send user to another page
  • When the video is stopped, re-start the video

Requried javascript API:

<script src="https://www.youtube.com/iframe_api"></script>

HTML mark-up

<div class="herovideo"> <!-- this is the wrapper //-->
  <div class="herovideo-clicker"></div> <!-- this is the clicker //-->
  <div class="video-wrapper"> <!-- this is a responsive wrapper //-->
    <div id="video-placeholder"></div> <!-- this gets replaced with iframe //-->
  </div>
</div>

CSS:

<style>
	.video-wrapper {   }
	.herovideo { position:relative;  }
	.herovideo-clicker { z-index:99; position:absolute; width: 100%; height: 100%; cursor:pointer;}
	.herovideo .video-wrapper { position:relative; z-index:9; }
</style>

Javascript that will:

  • Initialise the player and define it’s appearance
  • Do the responsive resizing
  • On stae change, set the click event
<script>

var player;
function onYouTubeIframeAPIReady() {
	player = new YT.Player('video-placeholder', {
		width: 1280,
		height: 720,
		videoId: 'Write your Youtube Video ID here',
		playerVars: {
			modestbranding: 1,
			autoplay: 1,
			controls: 0,
			enablejsapi: 1,
			fs: 0,
			rel: 0,
			showinfo: 0,
			color: 'white'
		},
		events: {
			onReady: initialize,
			onStateChange: onytplayerStateChange
		}
	});
}

function initialize(){

	var $allVideos = $("iframe[src*='//player.vimeo.com'], iframe[src*='//www.youtube.com'], object, embed"),
		$fluidEl = $(".video-wrapper");

	$allVideos.each(function() {
	  $(this)
	  .attr('data-aspectRatio', this.height / this.width)
	  .removeAttr('height')
	  .removeAttr('width');
	});

	var newWidth = $fluidEl.width();
	  $allVideos.each(function() {
		var $el = $(this);
		$el
		.width(newWidth)
		.height(newWidth * $el.attr('data-aspectRatio'));
	  });

}
  
function onytplayerStateChange(newState) {

  if(newState.data == 1) {
	 // take the user to a new page while the video is playing
	 $( ".herovideo-clicker").unbind( "click" );
	 $('.herovideo-clicker').on('click', function(){
		window.location.href = 'write your URL here'; 
		return false;
	 });
  } else  {
	// restart the video if it is not playing
	$( ".herovideo-clicker").unbind( "click" );
	$('.herovideo-clicker').on('click', function(){
		player.playVideo();
		return false;
	});
  }
}

</script>

References:

  • https://github.com/chriscoyier/Fluid-Width-Video
  • https://developers.google.com/youtube/iframe_api_reference

Sneak Peek: Mailchimp ABANDONED_CART merge tags for custom HTML email

You can use ABANDONED_CART blocks similar to PRODUCT_RECOMMENDATIONS

For example, you can display a list of items in the cart:

*|ABANDONED_CART:[$total=3]|*
<a href="*|CART:URL|*">
<img src="*|PRODUCT:IMAGE_URL|*" />
<br />*|PRODUCT:TITLE|*
<br />*|PRODUCT:PRICE|*
</a>
*|END:ABANDONED_CART|*

Or create a button:

*|ABANDONED_CART:[$total=1]|*
<a href="*|CART:URL|*">Complete your order</a>
*|END:ABANDONED_CART|*

Search suggestions for Shopify

Add a search form to your theme:

<form action="/search" method="get" role="search" id="header-search">
<input type="hidden" name="type" value="product">
<label for="q">{{ 'general.search.placeholder' | t }}</label>
<input type="search" id="q" name="q" value="{{ search.terms | escape }}" class="input-group-field" />
<input type="submit" value="{{ 'general.search.submit' | t }}" class="input-group-field" />
</form>

Create a template called search.json.liquid

{% layout none %}
{% capture results %}
  {% for item in search.results %}
    {% assign product = item %}
    { 
      "vendor"    : {{ product.vendor | json }},
      "title"    : {{ product.title | json }},
      "url"      : {{ product.url | within: product.collections.last | json }},
      "thumbnail": {{ product.featured_image.src | product_img_url: 'thumb' | json }}
    }
    {% unless forloop.last %},{% endunless %}
  {% endfor %}
{% endcapture %}
{
  "results_count": {{ search.results_count }},
  "results": [{{ results }}]
}

Create this snippet and add to theme layout.

<script>
$(function() {
  // Current Ajax request.
  var currentAjaxRequest = null;
  // Grabbing all search forms on the page, and adding a .search-results list to each.
  var searchForms = $('form[action="/search"]').css('position','relative').each(function() {
    // Grabbing text input.
    var input = $(this).find('input[name="q"]');
    // Adding a list for showing search results.
    var offSet = input.position().top + input.innerHeight();
    $('<ul class="search-results"></ul>').appendTo($(this)).hide();    
    // Listening to keyup and change on the text field within these search forms.
    input.attr('autocomplete', 'off').bind('keyup change input propertychange', function() {
      // What's the search term?
      var term = $(this).val();
      // What's the search form?
      var form = $(this).closest('form');
      // What's the search URL?
      var searchURL = '/search?type=product&q=' + term;
      // What's the search results list?
      var resultsList = form.find('.search-results');
      // If that's a new term and it contains at least 3 characters.
      if (term.length > 3 && term != $(this).attr('data-old-term')) {
        // Saving old query.
        $(this).attr('data-old-term', term);
        // Killing any Ajax request that's currently being processed.
        if (currentAjaxRequest != null) currentAjaxRequest.abort();
        // Pulling results.
        currentAjaxRequest = $.getJSON(searchURL + '&view=json', function(data) {
          // Reset results.
          resultsList.empty();
          // If we have no results.
          if(data.results_count == 0) {
            // resultsList.html('<li><span class="title">No results.</span></li>');
            // resultsList.fadeIn(200);
            resultsList.hide();
          } else {
            // If we have results.
            $.each(data.results, function(index, item) {
              var link = $('<a></a>').attr('href', item.url);
              link.append('<span class="thumbnail"><img src="' + item.thumbnail + '" /></span>');
              link.append('<span class="title"><strong>' + item.vendor + '</strong><br >' + item.title + '</span>');
              link.wrap('<li></li>');
              resultsList.append(link.parent());
            });
            // The Ajax request will return at the most 10 results.
            // If there are more than 10, let's link to the search results page.
            if(data.results_count > 10) {
              resultsList.append('<li><span class="title"><a href="' + searchURL + '">See all results (' + data.results_count + ')</a></span></li>');
            }
            resultsList.fadeIn(200);
          }        
        });
      }
    });
  });
  // Clicking outside makes the results disappear.
  $('body').bind('click', function(){
    $('.search-results').hide();
  });
});
</script>

Reference: https://help.shopify.com/themes/customization/store/enable-autocomplete-for-search-boxes

Custom Addthis Social Media Sharing Buttons for Shopify (for free)

The process is:

  1. Create a Google Analtyics account and get your site ID
  2. Sign-up to Addthis and get your profile ID
  3. Sign-up to Bitly for URL shortening on Tweets (and get your API username and key)
  4. Add the Shopify Theme settings to your settings_schema.js
  5. Add the javascript to your Shopify theme layout file
  6. Add HTML for sharing buttons to your Shopify pages
  7. Add custom icon font and CSS to style your buttons
  8. Configure the Addthis Custom HTML Email Template
  9. Create a Facebook App and add the id to the settings

Addthis theme settings

Add this code to your Shopify settings_schema.json then click on “customise theme” to enter the right values.

  {
    "name": "Addthis Sharing Settings",
    "settings": [
      {
        "type": "checkbox",
        "id": "addthis_use",
        "label": "Use Addthis?"
      },
      {
        "type": "text",
        "id": "addthis_id",
        "label": "AddThis ID"
      },
      {
        "type": "text",
        "id": "google_analytics_id",
        "label": "Google Analytics ID"
      },
      {
        "type": "text",
        "id": "addthis_twitter_id",
        "label": "Twitter name"
      },
      {
        "type": "text",
        "id": "addthis_twitter_string",
        "label": "Twitter string",
        "default": "*title* Coming Soon. #signup #exclusiveaccess"
      },
      {
        "type": "checkbox",
        "id": "addthis_bitly_use",
        "label": "Use Bitly?"
      },
      {
        "type": "checkbox",
        "id": "addthis_email_template_use",
        "label": "Use custom email template?"
      },
      {
        "type": "text",
        "id": "addthis_email_template_name",
        "label": "Add this email template name",
        "default": "product_template"
      },
      {
        "type": "text",
        "id": "addthis_facebook_app_id",
        "label": "Facebook App ID"
      },
      {
        "type": "text",
        "id": "addthis_facebook_redirect_url",
        "label": "Facebook Redirect URL"
      }
    ]
  }

Addthis Javascript

Create a new snippet called “addthis.liquid” and add it to the end of your theme (before end of body tags) using {% include ‘addthis’ %}

{% if settings.addthis_use %}
<script>
  jQuery(function($) {
    initAddThis();
    jQuery('.sharenulify').on('click', function (e) {
      return false;
    });
  });
  function initAddThis() 
  {
    if ( typeof( window[ 'addthis' ] ) != "undefined" ) {
      addthis.init()
    } 
  }
</script> 

{% capture addthis_title %}{% endcapture %}
{% capture addthis_description %}{% endcapture %}
{% capture addthis_image %}{% endcapture %}
{% if template contains 'product' %}
  {% capture addthis_title %}{{ product.title | strip_html | escape }}{% endcapture %}
  {% capture addthis_description %}{{ product.description | strip_html | strip_newlines | truncatewords: 30, '' | escape }}{% endcapture %}
  {% capture addthis_image %}https:{{ product.featured_image | img_url: 'large' }}{% endcapture %}
{% elsif template contains 'article' %}
  {% capture addthis_title %}{{ article.title | strip_html | escape }}{% endcapture %}
  {% capture addthis_description %}{{ article.excerpt_or_content | strip_html | strip_newlines | truncatewords: 30, '' | escape }}{% endcapture %}
  {% if article.image %}
    {% capture addthis_image %}https:{{ article.image.src | img_url: 'large' }}{% endcapture %}
  {% endif %}
{% elsif template contains 'page' %}
  {% capture addthis_title %}{{ page.title | strip_html | escape }}{% endcapture %}
  {% capture addthis_description %}{{ page.content | strip_html | strip_newlines | truncatewords: 30, '' | escape }}{% endcapture %}
  {% assign img_tag = '<' | append: 'img' %}
  {% if page.content contains img_tag %}
    {% assign src = page.content | split: 'src="' %}
    {% assign src = src[1] | split: '"' | first | remove: 'https:' | remove: 'http:' | replace: '_small.', '_large.' %}
    {% capture addthis_image %}https:{{ src }}{% endcapture %}
  {% endif %}
{% else %}
  {% capture addthis_title %}{{ page_title | escape }}{% endcapture %}
  {% if page_description %}{% capture addthis_description %}{{ page_description | escape }}{% endcapture %}{% endif %}
{% endif %}

{% capture addthis_twitter_string_calculated %}{{ settings.addthis_twitter_string | replace: '*title*', addthis_title }}{% endcapture %}  
<script type="text/javascript">
  var addthis_config = {
    {% if settings.google_analytics_id.size > 0 %}
    data_ga_property: '{{ settings.google_analytics_id }}',
    data_ga_social : true,
    {% endif %}
    "data_track_addressbar":false,
    ui_use_css : true,
    image_include: "at_include",
    image_exclude: "at_exclude"
  };
  addthis_share = {
    {% if settings.addthis_bitly_use %}
    url_transforms : {
      shorten: {
        twitter: 'bitly',
        facebook: 'bitly'
      }
    }, 
    shorteners : {
      bitly : {} 
    },
    {% endif %}
    url: "{{ canonical_url }}",
    title: "{{ addthis_title }}",
    description: "{{ addthis_description }}",
    passthrough : {
      twitter: {
        {% if settings.addthis_twitter_id.size > 0 %}via: "{{ settings.addthis_twitter_id }}",{% endif %}
        text: "{{ addthis_twitter_string_calculated }}"
      }{% if settings.addthis_facebook_app_id.size > 0 %},
      facebook: {
        app_id: '{{ settings.addthis_facebook_app_id }}',
        redirect_uri: '{{ settings.addthis_facebook_redirect_url }}',
      }{% endif %}
    }
    {% if settings.addthis_email_template_use and addthis_image.size > 0 %},
    email_template: "{{ settings.addthis_email_template_name }}",
    email_vars: { 
      thisTitle: "{{ addthis_title }}" ,
      thisDescription: "{{ addthis_description }}", 
      thisImage: "{{ addthis_image }}" ,
    }
    {% endif %}
  }
</script>        
<script type="text/javascript" src="https://s7.addthis.com/js/300/addthis_widget.js#pubid={{ settings.addthis_id }}" async="async"></script>
{% endif %}

HTML for share buttons

Create a new snippet called “addthis-share-buttons.liquid” and add it on any page you like using {% include ‘addthis-share-buttons’ %}

<div class="product-share">
  <a class="product-share-button" href="#">Share</a>
  <div class="share">
    <ul>
      <li><a class="tooltip sharebutton addthis_button_facebook" id="share_facebook" title="Share {{ mysharetitle }} on Facebook"><i class="fa fa-facebook"></i></a></li>
      <li><a class="tooltip sharebutton addthis_button_twitter" id="share_twitter" title="Share {{ mysharetitle }} on Twitter"><i class="fa fa-twitter"></i></a></li>
      <li><a class="tooltip sharebutton addthis_button_tumblr" id="share_tumblr" title="Share {{ mysharetitle }} on Tumblr"><i class="fa fa-tumblr"></i></a></li>
      <li><a class="tooltip sharebutton sharenulify addthis_button_pinterest_share" id="share_pinterest" title="Share {{ mysharetitle }} on Pinterest"><i class="fa fa-pinterest"></i></a></li>
      <li><a class="tooltip sharebutton addthis_button_email" id="share_email" title="Send  {{ mysharetitle }} to a friend by Email"><i class="fa fa-envelope-o"></i></a></li>
      <li><a class="tooltip sharebutton addthis_button_compact" id="share_other" title="More share options"><i class="fa fa-bookmark"></i></a></li>
    </ul>
  </div>
</div>

Use CSS to style your buttons

For Fontawesome icons, remember to add the font css to your theme file.

.product-share-button, .share { display:inline-block; }
.share ul { display:inline-block; list-style:none; margin:0; padding:0; }
.share li {  margin:0; padding:0; display:inline-block; }
.share li a { display:inline-block; margin:0; padding:10px; font-size:18px; line-height: 38px;}

HTML output for Mailchimp *|LIST_ADDRESS_HTML|* tag

<div class="vcard">
                                    <span class="org fn">Ocean Collection</span>
                                    <div class="adr">
                                        <div class="street-address">9 Applebee St</div>
                                        <span class="locality">St Peters</span>, 
                                        <span class="region">NSW</span>  
                                        <span class="postal-code">2044</span> 
                                        <div class="country-name">Australia</div>
                                    </div>
                                    <br><a href="http://oceancollection.us11.list-manage.com/vcard?u=xxx" class="hcard-download">Add us to your address book</a>
                                </div>  

AddThis to Shopify Theme with Configuration Variables

Setup a Google Analytics account and record the profile ID.

Setup an AddThis Sharing account, add a new profile and record the profile ID.

Setup a Bitly account, go to Advanced Settings and record your “login” and “API Key”

Add the following configuration settings to your Shopify theme ‘settings/settings_data.json’ file:

{
  "current": {
    ....
    "addthis_profile_id":"PUT YOUR ADDTHIS PROFILE ID HERE",
    "google_profile_id":"PUT YOUR GOOGLE PROFILE ID HERE",
    "enable_bitly":true,
    ....
  }
}

Add the following fields to your Shopify theme ‘settings/settings.html’ file:

<fieldset>
  <legend>Sharing Settings</legend>
  <table>
    <tr>
      <td><label for="addthis_profile_id">Addthis Profle ID</label></td>
      <td><input id="addthis_profile_id" name="addthis_profile_id" class="text" /></td>
    </tr>
    <tr>
      <td><label for="enable_bitly">Enable Bitly URL Shortener for Addthis</label></td>
      <td><input type="checkbox" id="enable_bitly" name="enable_bitly" /></td>
    </tr>
    <tr>
      <td><label for="google_profile_id">Google Profle ID</label></td>
      <td><input id="google_profile_id" name="google_profile_id" class="text" /></td>
    </tr>
  </table>
  
</fieldset>

Add the following at the bottom of your Shopify theme ‘layouts/theme.liquid’ file (before the </body> tag):

NOTE: I set ‘data_track_addressbar’ to ‘false’ because it adds hashed variables to URLs which can screw with someJavascript dependant themes.

{% if settings.addthis_profile_id.size > 0 %}
<!-- AddThis Button  -->
<script type='text/javascript'>
var addthis_product = 'mag-1.0';
{% if settings.enable_bitly %}var addthis_share = { url_transforms : { shorten: { twitter: 'bitly' } }, shorteners : { bitly : {} }  }{% endif %}
var addthis_config = {data_track_addressbar:false{% if settings.google_profile_id.size > 0 %}, data_ga_property:'{{ settings.google_profile_id }}'{% endif %}};
</script>
<script type="text/javascript" src="https://s7.addthis.com/js/300/addthis_widget.js#pubid={{ settings.addthis_profile_id }}"></script>
<!-- AddThis Button  -->
{% endif %}

Then you can simply add the code to any page/liquid template like this:

{% if settings.addthis_profile_id.size > 0 %}
<!-- AddThis Button BEGIN -->
<div class="addthis_toolbox addthis_default_style addthis_32x32_style">
<a class="addthis_button_preferred_1"></a>
<a class="addthis_button_preferred_2"></a>
<a class="addthis_button_preferred_3"></a>
<a class="addthis_button_preferred_4"></a>
<a class="addthis_button_compact"></a>
<a class="addthis_counter addthis_bubble_style"></a>
</div>
<!-- AddThis Button END -->
{% endif %}

Then add Facebook open graph tags to your page like this:

NOTE: Save a coming soon image called “my-coming-soon-image.jpg” in your assets for collections that do not have images.

{% if template contains 'product' %}
  <meta property="og:url" content="{{ shop.url }}{{ current_url }}" />
  <meta property="og:title" content="{{ product.title }}" />
  <meta property="og:description" content="{{ product.description | newline_to_br | strip_html | truncatewords: 100, '' | escape  }}" />
  <meta property="og:image" content="{{ product.featured_image | product_img_url: 'medium' }}" />
{% elsif template contains 'article' %}
  <meta property="og:url" content="{{ shop.url }}{{ current_url }}" />
  <meta property="og:title" content="{{ article.title }}" />
  <meta property="og:description" content="{{ article.excerpt_or_content | newline_to_br | strip_html | truncatewords: 100, '' | escape  }}" />
  {% if article.content contains "<img" %}
    {% assign src = article.content | split: 'src="' %}
    {% assign src = src[1] | split: '"' | first | replace: '//cdn', 'http://cdn' | replace: 'http:http://', 'http://' | remove: 'https:'  %}
    {% if src %}<meta property="og:image" content="{{ src }}" />{% endif %}
 {% endif %}
{% elsif template contains 'collection' %}
	{% if collection.all_products_count > 0 %}
            {% if collection.image %}
                {% capture meta_img_src %}{{ collection.image.src | collection_img_url: 'medium' }}{% endcapture %}
            {% else %}
                {% capture meta_img_src %}{{ collection.products.first.featured_image.src | product_img_url: 'medium' }}{% endcapture %}
            {% endif %}
            {% if meta_img_src contains "no-image" %}
                {% capture meta_img_src %}{{ 'my-coming-soon-image.jpg' | asset_url }}{% endcapture %}
            {% endif %}
        {% else %}
            {% capture MybadUrl %}{{ collection.image.src | collection_img_url: 'medium' }}{% endcapture %}
            {% if MybadUrl contains "no-image" %}
                {% capture meta_img_src %}{{ 'my-coming-soon-image.jpg' | asset_url }}{% endcapture %}
            {% else %}
                {% capture meta_img_src %}{{ MybadUrl }}{% endcapture %}
            {% endif %}  
        {% endif %}
      	<meta property="og:title" content="{{ current_title }}" />
  	<meta property="og:image" content="{{ meta_img_src }}" />
  	<meta property="og:url" content="{{ shop.url }}{{ current_url }}" />
{% else %}
  {% if settings.use_logo %}
    <meta property="og:image" content="{{ 'logo.png' | asset_url }}" />
  {% endif %}
{% endif %}

Center a popup with jQuery, CSS, HTML

A simple horizontally and vertically centered popup. Allows you to create several on one page.

Add this jQuery:

jQuery(".popupopen").click(function() {
  box = jQuery(this).attr('rel);
  jQuery('#'+box).show();
  width = -1 * parseInt((jQuery('#'+box).width()/2));
  height = -1 * parseInt((jQuery('#'+box).height()/2));
  jQuery('#'+box).css('margin-left',width).css('margin-top',height);
  return false;
});
jQuery(".popupclose").click(function() {
  jQuery(this).parent().hide();
  return false;
});

Add this HTML:

<p><a title="Open this popup" href="#" class="popupopen" rel="popup1">open a popup</a></p>
<div class="popup" id="popup1">
  <p>My popup insides</p>
  <a title="Close this popup" href="#" class="popupclose">close</a>
</div>

Add this CSS:

.popup { 
  z-index:999; 
  position:fixed; 
  top:50%; 
  left:50%; 
  width:66%;
  max-width:300px;
  padding:20px; 
  display:none;
  text-align:center;  
}

References: