18mar QR Code from hCard using Sumo! parser and Google Chart API
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:

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!





Wrzesień 1st, 2010 at 12:44
Very cool!
How would I have the QR code insert before the hcard and float to the right?
So far I’ve got:
qrImg.style.float=”right”; person.parentElement.insertBefore(qrImg,self);
But that isn’t right
Wrzesień 1st, 2010 at 12:53
Hi,
Proper syntax is:
qrImg.style.cssFloat = ‘right’;
http://www.w3schools.com/css/pr_class_float.asp
Wrzesień 1st, 2010 at 13:14
Ah ok
I’m not sure I’m getting the change from insertAfter to insertBefore working correctly. Floating to the right, but still below the hCard data.
Wrzesień 2nd, 2010 at 8:37
Yeah sorry to be a bother, but how would I have the QR code inserted before the hCard?
Wrzesień 2nd, 2010 at 9:17
Add method like this and use it instead insertAfter
insertBefore: function(context, element) {
if (!element.parentNode) return;
element.parentNode.appendChild(context);
},
Wrzesień 2nd, 2010 at 11:01
Thanks dude!