Lions Den

The Code and Times of Hanan Schwartzberg

About Hanan | Hanan's CV | Contact Hanan

August 2, 2016

How to track embeded Youtube videos with Google Universal Analytics event

Filed under: Google,JavaScript — Tags: , , , , — Hanan Schwartzberg @ 10:22 am

The problem

You have a Youtube video embedded in an iframe and you need to track it via Google Analytics

The Solution

Since it’s in an iframe you need to use the Youtube API to handle the different events. This requires a few steps.

  1. Include this parameter in the src of the iframe
    ?enablejsapi=1
  2. Include the Youtube API script file
    var tag = document.createElement('script');
    tag.id = 'iframe-demo';
    tag.src = 'https://www.youtube.com/iframe_api';
    var firstScriptTag = document.getElementsByTagName('script')[0];
    firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
  3. Assign the event handler to the required events. In this case the iframe’s ID is frmVideo.
    var player;
    function onYouTubeIframeAPIReady(event) {
        player = new YT.Player((event ? event.id : 'frmVideo')), {
            events: {
                'onStateChange': onPlayerStateChange
            }
        });
    }
  4. Actually handle the events
    var pauseFlag = false;
    function onPlayerStateChange(event) {
        // track when user clicks to Play
        if (event.data == YT.PlayerState.PLAYING) {
            ga('send', 'event', 'Video', 'Play', event.target.getVideoData()["title"]);
            pauseFlag = true;
        }
        // track when user clicks to Pause
        if (event.data == YT.PlayerState.PAUSED && pauseFlag) {
            ga('send', 'event', 'Video', 'Pause', event.target.getVideoData()["title"]);
            pauseFlag = false;
        }
        // track when video ends
        if (event.data == YT.PlayerState.ENDED) {
            ga('send', 'event', 'Video', 'End', event.target.getVideoData()["title"]);
        }
    }
  5. On my site the API continuously loaded before the video resulting in it not finding the video in step 3. The other problem was that it needed to have the same name for ever video and would only work for one video on a page. Instead, include an onload event on the iframe and pass the iframe itself in as the event and just default to ‘frmVideo’ if no video was passed in

    onload="onYouTubeIframeAPIReady(this)"

    Downloads

    Right click here and select 'Save link as...' to download this code.

    References

January 16, 2016

ASP.NET – Invalid postback or callback argument (An unexpected cause)

Filed under: ASP.NET,C# — Tags: , , , — Hanan Schwartzberg @ 9:20 pm

The Issue

Causing a postback (full or partial) causes the error

Invalid postback or callback argument.  Event validation is enabled using <pages enableEventValidation=”true”/> in configuration or <%@ Page EnableEventValidation=”true” %> in a page.  For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them.  If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.

With nothing added to the page on the client side, it’s not clear what data is causing the error.

(more…)

December 15, 2015

Responsively embed a YouTube video

Filed under: CSS — Tags: , , , , , — Hanan Schwartzberg @ 9:35 am

The Issue

The default YouTube embedding code sets the video to a fixed size.

The Solution

Add these classes to your css:

.divVideoContainer {
    position: relative;
    padding-bottom: 56.25%;
    height: 0;
    overflow: hidden;
    max-width: 100%;
}
 
    .divVideoContainer iframe, .divVideoContainer object, .divVideoContainer embed {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
    }

Now wrap your embedding code in a div with the class defined above.

<div class="divVideoContainer">
    <iframe width="640" height="360" src="https://www.youtube.com/embed/MtN1YnoL46Q?controls=0"
        frameborder="0" allowfullscreen></iframe>
</div>

December 5, 2015

Row numbering for ui-grid in Angular JS

Filed under: AngularJS,JavaScript — Tags: , , , — Hanan Schwartzberg @ 9:46 pm

The Issue

You want to display row numbers in a ui-grid. The numbers should should stay sequential regardless of the sorting

The Solution

Add this column to the grid’s columnDefs

{ name: 'rowNum', displayName: 'Row Number', cellTemplate: 
'<div class="ui-grid-cell-contents">{{grid.renderContainers.body.visibleRowCache.indexOf(row) + 1}}</div>' }

November 12, 2015

Default sort for ui-grid in Angular JS

Filed under: AngularJS,JavaScript — Tags: , , , — Hanan Schwartzberg @ 6:12 am

The Issue

You want to use the internal sorting for an ui-grid, but want to have it sort by default by a specific column.

What didn’t work

Including

sortInfo: {fields:['Title'],directions:['asc']},

in the grid definition didn’t work because it requires using external sorting.

The Solution

The default sort order isn’t declared on the grid level. It’s declared in the definition of the column itself. For example:

columnDefs: [
    {
       field: 'Title', displayName: 'Title', width: 160,
       sort: { direction: uiGridConstants.ASC, priority: 1 }
    },
    {
       field: 'Description', displayName: 'Description', width: 160
    }
]

January 23, 2015

WordPress blog on Windows not found

Filed under: IIS7,IIS8 — Tags: , , , — Hanan Schwartzberg @ 6:49 am

The Issue

When migrating an existing WordPress blog, instead of creating a new one, the admin section of the blog works fine, but the front-end throws a 404 error.

The Solution

First step is to make sure everything is setup correctly. Japinator has an excellent step by step explanation of how to Create a WordPress blog on Windows Server 2008 R2, IIS 7.5 and MySQL. The tutorial is written for Windows 2008 and IIS7, but it works just as well with Windows 2012 and IIS8.

Once everything is setup correctly, if it’s an existing blog from a Linux environment, the problem will still persist.

Amrit Ray has a WordPress on Windows – Issues & Solutions. He explains that you need to use the Url Rerwiting module for IIS, available here http://www.iis.net/downloads/microsoft/url-rewrite because Linux creates the .htaccess file with the required permalink settings automatically, but in Windows you have to set it up manually.

To do this, after the Url Rewrite module is installed add the following web.config file to folder containing the WordPress blog.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <defaultDocument>
      <files>
        <clear/>
        <add value="Default.htm"/>
        <add value="Default.asp"/>
        <add value="index.htm"/>
        <add value="index.html"/>
        <add value="iisstart.htm"/>
        <add value="default.aspx"/>
        <add value="index.php"/>
      </files>
    </defaultDocument>
    <rewrite>
      <rules>
        <rule name="wordpress" patternSyntax="Wildcard">
        <match url="*"/>
          <conditions>
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true"/>
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true"/>
          </conditions>
          <action type="Rewrite" url="index.php"/>
        </rule></rules>
    </rewrite>
  </system.webServer>
</configuration>

February 12, 2014

Resize an iFrame to match its contents

Filed under: JavaScript — Tags: , , , — Hanan Schwartzberg @ 9:52 am

The Issue

You need to load content into an iFrame, but you don’t know the height of the content ahead of time.

The Solution

Catch the lonload event of the iFrame and resize it to the height of the body of the content

&lt;iframe id="ifArtworkDetails" width="650px" height="420px" scrolling="no" 
        src="someDynamicContent.html" marginheight="0" marginwidth="0" 
        frameborder="0" onload="resizeIframe(this)">&lt;/iframe>
    function resizeIframe(objIframe) {
        objIframe.style.height = 
            objIframe.contentWindow.document.body.scrollHeight + 50 + 'px';
    }

November 18, 2013

ASP.NET Relative Urls (~/) Not Rendering Correctly in a HyperLink ImageUrl

Filed under: ASP.NET,C# — Tags: , , , , , , , , , — Hanan Schwartzberg @ 2:47 pm

The Issue

When using a HyperLink object on masterpage the relative url assigned to the ImageUrl property is not resolving correctly on certain pages. The problem appears to only affect pages where a url rewrite has been used and the level of directories does not match the actual level of directories of the page. For instance, if the url “http://www.mysite.com/categories/book.aspx” actually loads “http://www.mysite.com/products/categories/default.aspx?type=books”, the the below hyperlink will resolve as “../products/images/bbb_logo.gif”. On all other pages it will correctly resolve as “../images/bbb_logo.gif”.

<asp:HyperLink runat="server" ID="hlBBB" Target="_blank" 
        NavigateUrl="http://www.bbb.org" ImageUrl="~/Images/bbb_logo.gif" />

Attempting to resolve the url manually in the code behind doesn’t work either. The following code results in the same incorrect url.

hlBBB.ImageUrl = ResolveClientUrl("~/images/bbb_logo.gif");

The Solution

There are two ways to work around this.

  1. This bug seems to be exclusive to the HyperLink object. Remove the image from the HyperLink and the ImageUrl will resolve correctly. For instance, the above HyperLink should be rewritten as:
    <asp:HyperLink runat="server" ID="hlBBB"
        NavigateUrl="http://www.bbb.org">
        <asp:Image runat="server" ID="imgBBB" ImageUrl="~/Images/bbb_logo.gif" />
    </asp:HyperLink>
  2. If you really want to leave the image in the HyperLing object. You can work around the problem in the code behind. The ResolveClientUrl method doesn’t work because takes into account the page’s location in the site, which between the rewrite and the actual location of the page seems to be inaccurate. Instead use VirtualPathUtility.ToAbsolute to resolve the url. This method can be used anywhere on the site, not just on pages and user controls and will resolve the url with an absolute path (“/images/bbb_logo.gif”).

July 17, 2012

Google Custom Search Engine – Error: ‘this.zd’ is null or not an object

Filed under: Google,JavaScript — Tags: , , , — Hanan Schwartzberg @ 4:36 pm

The Issue

When using the Google Custom Search Engine control and executing a default query it throws a JavaScript error “Error: ‘this.zd’ is null or not an object”.


Error: 'this.zd' is null or not an object

The Problem Code

google.load('search', '1');
 
function OnLoad() {
  // Create a custom search control that uses a CSE restricted to code.google.com
  var customSearchControl = new google.search.CustomSearchControl('012157912978810372049:-cv6ao3zqua');
 
  // run a query
  customSearchControl.execute('ajax api');
 
  // Draw the control in content div
  customSearchControl.draw('content'); 
}
google.setOnLoadCallback(OnLoad);

The Solution

Sometimes the most obvious mistakes are the hardest to find. After several Google searches it started to seem like no one else ever had this problem. Threre was no obvious connection between this error and the Google CSE. After staring at the examples here http://code.google.com/apis/ajax/playground/#custom_search_control for a while the answer became obvious.

Before executing the default query the control must first be drawn. The last two commands in the OnLoad method in the above code need to be flipped. Here is the correct code:

google.load('search', '1');
 
function OnLoad() {
  // Create a custom search control that uses a CSE restricted to code.google.com
  var customSearchControl = new google.search.CustomSearchControl('012157912978810372049:-cv6ao3zqua');
 
  // Draw the control in content div
  customSearchControl.draw('content'); 
 
  // run a query (ONLY AFTER DRAWING THE CONTROL)
  customSearchControl.execute('ajax api');
}
google.setOnLoadCallback(OnLoad);

October 19, 2010

Visual Studio 2008 – ASP.NET “System.Runtime.InteropServices.COMException”

Filed under: ASP.NET,IIS7 — Tags: , — Hanan Schwartzberg @ 4:01 pm

The Issue

When openning an existing ASP.NET project for the first time in Visual Studio 2008 it returns the error “System.Runtime.InteropServices.COMException” without any HRESULT code. The problem I experienced was specificly on a Windows 7 machine, but the same solutions should work on Vista as well.

System.Runtime.InteropServices.COMException

(more…)

Older Posts »
Home | Site Design | Banner Design | Code Den | Offsite Posts | Downloads | Photography | About Hanan | Hanan's CV | Contact Hanan
Copyright © 2009 Hanan Schwartzberg. All rights reserved.