David Corbacho

QR Codes on the fly with JavaScript

Let's go through some steps to create dynamically a QR Code of the current URL a user is visiting.

I will use the Google API to generate the QR code, and then (optionally) Google Analytics to track the use of the QR Code.

I wanted a simple quick-and-dirty solution to generate a QR Code of the URL of the current page. Why? Just in case a visitor wants to load the current page in his mobile. Probably is not very useful, but it made my life easier while developing a responsive design theme for this site.

There are already Drupal modules that create QR code, but they are generated in the server side. How many users are really going to use the QR Code? About 2% of the visitors? Then, generating the QR Code in the server is a waste of resources and bandwidth. Better, just generate the QR Code 'on the fly' with JavaScript, after clicking a button.

This is the main part of the JavaScript used, where it's created a img element on the fly with the src attribute as a GET call to the the Google API that will generate the image.

    var $qrButton = $('#qr_icon');
    $qrButton.click(function(e){
        e.preventDefault();
        var currentURL = window.location.hostname + window.location.pathname;
        var src="http://chart.googleapis.com/chart?cht=qr&chl=http://" + currentURL + "&chs=250x250";
        var qrImg=document.createElement("img");
        qrImg.setAttribute('src', src);
        qrImg.setAttribute('alt', 'QR Code');
        qrImg.setAttribute('height', 250);
        qrImg.setAttribute('width', 250);

       // Insert qrImg whatever you want.
    });

Sorry for not providing a complete solution. But the code above is doing all the heavy lifting, you just need to insert the qrImg element wherever you want. In my case drupalmotion.com was using already the qTip 2 library so it was a matter to create a new qTip:

var qtipContent = {content: {
                           text : $(qrImg),
                           title: { 'text' : 'QR Code', button: 'Close'}
                           },
                         hide: {
                           event: false
                           }
                         };

$(this).qtip($.extend({}, qtip_shared, qtipContent)).qtip('show');

You can see a demo in the header, clicking the small button of the QRCode.

Tracking with Google Analytics

As I said, to use QR Codes as links it' not that useful in a website, because you are already in a browser, so I want to track how many people will use it. Just out of curiosity.

If you are using in your site Google Analytics, it will be very easy to track the visits from the QR Code. You just need to add some campaign parameters to the URL and Google will take care of the rest. Use the URL builder tool to build it. In my case this is the result:

http://drupalmotion.com/?utm_source=drupalmotion&utm_medium=web&utm_campaign=qr

Quite long URL, and the problem is that the size and complexity of the QR Code is proportional to the length of the string. It will be even longer when is a node path, in the example I was just using the frontpage URL.

A way to make it shorter, if you are using Apache with mod_rewrite enabled, it's using a Rewrite rule in the Drupal .htaccess:

RewriteCond %{QUERY_STRING} ^qr$
RewriteRule .* %{REQUEST_URI}?utm_source=drupalmotion&utm_medium=web&utm_campaign=qr [L,R=302]

It's important where you place it. Just before the Rewrite Rule for the index.php it's fine. Basically this rule will take whatever URL that is not a filepath and has the query string ?qr (no ?qra, no /qr?foo, no ?aqr). It will be replaced with the campaign parameters.

You don't need a redirection [L,R=301], it's enough that the server

By default mod_rewrite replaces the query string (unless you use the QSA flag), so you don't need to worry about redirection looping.

Probably also you will need to un-comment the next line in your .htaccess to make it work, depending of your apache configuration.

RewriteBase /

So now you can use a URL like this:

http://drupalmotion.com/?qr

FYI. If you enable the do-not-track-me feature in your Firefox, the G.A. tracking won't work, as it should be :)

Update. May 2013

I switched to Twitter bootstrap tooltip (only that component not the whole library). It's lightweight and can be used as an independent plugin, although you have to go pick the CSS manually. The plugin doesn't accept DOM elements, only strings. So now I'm creating the image in a more rudimentary way, just concatenating. Sigh

var $qrButton = $('#qr_icon');
$qrButton.on('click', function(e){
  e.preventDefault();
  var trackUrl = window.location.hostname + window.location.pathname + '?qr';
  var src="http://chart.googleapis.com/chart?cht=qr&chl=http://" + trackUrl + "&chs=180x180";
  $qrButton.tooltip('destroy').tooltip({ html: true,  container: 'body', placement: 'left', title:'<img src="' + src + '" style="height:180px;width:180px" alt="QR Code"/>' }).tooltip('show');
});

And that's all. Share it if you find it useful.