keemor.com - Surfin' JavaScript Wave

QR Code from hCard using Sumo! parser and Google Chart API

jane-qrcode

QR Code stands for Quick Response and was created by Japanese corporation in 1994. It became more popular among end users since mobiles have cameras which are able to read those codes. In my Nokia E51 I use I-nigma Reader, but there’re lots of others.

In this post I’d like to present a piece of JavaScript which generates QRCode from hCard using Google Charts API which after scanning by mobile enables easy adding contact to your contacts’ list.

Look at the DEMO to see what’s all about.

I started with generating contact information QR Code by ZXing Generator. Then I used URL decoder to find out how exactly MECARD should look like:

jane-contails-qrcode

MECARD:N:Jane Contails;TEL:+48111222333;URL:http://contails.com/;EMAIL:support@contails.com;ADR:Steet 456 55-444 Sin City Poland;;

After that I created hCard microformat using hCard creator.

The main idea was to find hCards on the page and add QR Codes to each of them on the fly using JavaScript and Google Chart API.

It was easier to accomplish then I could imagine since I found great Sumo! – A Generic Microformats Parser For JavaScript at danwebb.net.


<body onload="QRCodes.init()">
<!-- content goes here -->
</body>


var QRCodes = {
	init: function() {
		var self = this;
		//url to get qr code from Chart API
		var gChartUrl = 'http://chart.apis.google.com/chart?cht=qr&chs=150x150&chld=L|4&chl=';
		var qrImg, qrData, dataLen, chl, divLen;		  		  		
		//parse page to discover hCards
		var people = HCard.discover();		
		//forEach method is implemented in microformat.js so it works cross-browser					 		
		people.forEach(function(person) {
			//create img tag
			qrImg = document.createElement('img');
			//get sting from person JSON object 			
			qrData = self.getQRData(person);
			//get qrData length (Notice that QRcode data length must be less that 132 charaters long to fit into Version 4)
			dataLen = qrData.length;				
			//encode qrData to by compatible with Chart API		
			chl = self.urlEncode(qrData);			
			//set qrImg src		
			qrImg.src = gChartUrl+chl;
			//insert qrImg after hCard div			
			self.insertAfter(qrImg,person.parentElement)
			//create and add summary
			divLen = document.createElement('div');						
			divLen.innerHTML = 'QRcode data length:' + dataLen + '<br />Data: ' + qrData;
			self.insertAfter(divLen,qrImg);	
		});						
	},	
	/*
	 * Encode data
	 */
	urlEncode: function(str) {				
		return encodeURIComponent(str).replace(/%20/g, '+');
	},
	/*
	 * From Mootools
	 */
	insertAfter: function(context, element) {
		if (!element.parentNode) return;
		var next = element.nextSibling;
		(next) ? element.parentNode.insertBefore(context, next) : element.parentNode.appendChild(context);
	},
	getQRData: function(p) {
		var qrData = 'MECARD:';		 	
		if (p.n) {
			qrData += 'N:'+p.n.givenName+' '+p.n.familyName+';';	
		}
		if (p.telList) {
			qrData += 'TEL:'+p.telList[0]+';';	
		}
		if (p.urlList) {
			qrData += 'URL:'+p.urlList[0]+';';	
		}		
		if (p.emailList) {
			qrData += 'EMAIL:'+p.emailList[0]+';';	
		}		
		if (p.adrList) {
			qrData += 'ADR:';
			if (p.adrList[0].streetAddress) {
				qrData += p.adrList[0].streetAddress+' ';	
			}
			if (p.adrList[0].postalCode) {
				qrData += p.adrList[0].postalCode+' ';	
			}
			if (p.adrList[0].locality) {
				qrData += p.adrList[0].locality+' ';	
			}
			if (p.adrList[0].countryName) {
				qrData += p.adrList[0].countryName;	
			}
			qrData += ';';		
		}	
		qrData += ';'
		return qrData; 
	}
}

Notice that QRcode data length must be less that 133 charaters long (due to my tests) to fit into QR Code Version 4.

Thanks for reading!