-
-
Save dun4n/9353031 to your computer and use it in GitHub Desktop.
| <!doctype html> | |
| <html> | |
| <head> | |
| <script type="text/javascript" src="vcard2.js"></script> | |
| </head> | |
| <body> | |
| <script type="text/javascript"> | |
| // With helper methods | |
| var fooBar = vCard.create(vCard.Version.FOUR) | |
| fooBar.addFormattedname("Mr Foo Bar") | |
| fooBar.addEmail("foor@bar.com", vCard.Type.HOME) | |
| fooBar.addAddress("street", "code", "city", "country", vCard.Type.HOME) | |
| var link = vCard.export(fooBar, "Foo Bar", false) // use parameter true to force download | |
| document.body.appendChild(link) | |
| </script> | |
| <br/> | |
| <script type="text/javascript"> | |
| // Without helper methods | |
| var johnDoe = vCard.create(vCard.Version.FOUR) | |
| johnDoe.add(vCard.Entry.NAME, "DOE;John;;") | |
| johnDoe.add(vCard.Entry.FORMATTEDNAME, "John Doe") | |
| johnDoe.add(vCard.Entry.NICKNAME, "jd") | |
| johnDoe.add(vCard.Entry.TITLE, "Missing man") | |
| johnDoe.add(vCard.Entry.PHONE, "555-555-555", vCard.Type.CELL) | |
| johnDoe.add(vCard.Entry.EMAIL, "john.doe@work.com", vCard.Type.WORK) | |
| johnDoe.add(vCard.Entry.EMAIL, "john.doe@home.com", vCard.Type.HOME) | |
| johnDoe.add(vCard.Entry.ORGANIZATION, "JohnDoe Corp.") | |
| johnDoe.add(vCard.Entry.ADDRESS, ";;street;city;state;zip code;country", vCard.Type.HOME) | |
| johnDoe.add(vCard.Entry.URL, "http://john.doe") | |
| var link = vCard.export(johnDoe, "John Doe", false) // use parameter true to force download | |
| document.body.appendChild(link) | |
| </script> | |
| <br/> | |
| <script type="text/javascript"> | |
| // From JSON | |
| var johnSmith = { | |
| "version": "4.0", | |
| "n": "SMITH;John;;", | |
| "fn": "John Smith", | |
| "nickname":"js", | |
| "title": "Missing man too", | |
| "tel": [ | |
| {"value": "555-555-555", "type": "cell"} | |
| ], | |
| "email": [ | |
| { "value": "john.smith@work.com", "type": "work" }, | |
| { "value": "john.smith@home.com", "type": "home" } | |
| ] | |
| } | |
| var link = vCard.export(johnSmith, "John Smith", false) // use parameter true to force download | |
| document.body.appendChild(link) | |
| </script> | |
| </body> | |
| </html> |
| (function(context) { | |
| var version = { | |
| "TWO": "2.1", | |
| "THREE": "3.0", | |
| "FOUR": "4.0" | |
| } | |
| var vCard = { | |
| Version: version, | |
| Entry: { | |
| "ADDRESS": {"version": [version.TWO, version.THREE, version.FOUR], "key": "ADR", "format": ";;{0};{2};{4};{1};{3}", "@comment": "usage: addAdr(street, code, city, country, state)"}, | |
| "AGENT": {"version": [version.TWO, version.THREE], "key": "AGENT"}, | |
| "ANNIVERSARY": {"version": [version.FOUR], "key": "ANNIVERSARY"}, | |
| "BIRTHDAY": {"version": [version.TWO, version.THREE, version.FOUR], "key": "BDAY"}, | |
| "CALENDARADDURI": {"version": [version.FOUR], "key": "CALADRURI"}, | |
| "CALENDARURI": {"version": [version.FOUR], "key": "CALURI"}, | |
| "CATEGORIES": {"version": [version.TWO, version.THREE, version.FOUR], "key": "CATEGORIES"}, | |
| "CLASS": {"version": [version.THREE], "key": "CLASS"}, | |
| "CLIENTPIDMAP": {"version": [version.FOUR], "key": "CLIENTPIDMAP"}, | |
| "EMAIL": {"version": [version.TWO, version.THREE, version.FOUR], "key": "EMAIL"}, | |
| "FBURL": {"version": [version.FOUR], "key": "FBURL"}, | |
| "FORMATTEDNAME": {"version": [version.TWO, version.THREE, version.FOUR], "key": "FN"}, | |
| "GENDER": {"version": [version.FOUR], "key": "GENDER"}, | |
| "GEO": {"version": [version.TWO, version.THREE, version.FOUR], "key": "GEO"}, // FIXME two differents formats | |
| "IMPP": {"version": [version.THREE, version.FOUR], "key": "IMPP"}, | |
| // TODO: KEY | |
| "KIND": {"version": [version.FOUR], "key": "KIND"}, | |
| "LABEL": {"version": [version.TWO, version.THREE], "key": "LABEL"}, | |
| // TODO: LOGO | |
| "MAILER": {"version": [version.TWO, version.THREE], "key": "MAILER"}, | |
| "MEMBER": {"version": [version.FOUR], "key": "MEMBER"}, | |
| "NAME": {"version": [version.TWO, version.THREE, version.FOUR], "key": "N", "format": "{1};{0};;{2}", "@comment": "usage: addName(firstname, lastname, title)"}, | |
| "NICKNAME": {"version": [version.THREE, version.FOUR], "key": "NICKNAME"}, | |
| "NOTE": {"version": [version.TWO, version.THREE, version.FOUR], "key": "NOTE"}, | |
| "ORGANIZATION": {"version": [version.TWO, version.THREE, version.FOUR], "key": "ORG"}, | |
| // TODO: PHOTO | |
| "PRODID": {"version": [version.THREE, version.FOUR], "key": "PRODID"}, | |
| "PROFILE": {"version": [version.TWO, version.THREE], "key": "PROFILE"}, | |
| "RELATED": {"version": [version.FOUR], "key": "RELATED"}, | |
| "REVISION": {"version": [version.TWO, version.THREE, version.FOUR], "key": "REV"}, | |
| "ROLE": {"version": [version.TWO, version.THREE, version.FOUR], "key": "ROLE"}, | |
| "SORTSTRING": {"version": [version.TWO, version.THREE, version.FOUR], "key": "SORT-STRING"}, | |
| // TODO: SOUND | |
| "SOURCE": {"version": [version.TWO, version.THREE, version.FOUR], "key": "SOURCE"}, | |
| "PHONE": {"version": [version.TWO, version.THREE, version.FOUR], "key": "TEL"}, | |
| "TITLE": {"version": [version.TWO, version.THREE, version.FOUR], "key": "TITLE"}, | |
| "TIMEZONE": {"version": [version.TWO, version.THREE, version.FOUR], "key": "TZ"}, // FIXME: two differents formats | |
| "UID": {"version": [version.TWO, version.THREE, version.FOUR], "key": "UID"}, | |
| "URL": {"version": [version.TWO, version.THREE, version.FOUR], "key": "URL"}, | |
| "XML": {"version": [version.FOUR], "key": "XML"} | |
| }, | |
| Type: { | |
| "HOME": "HOME", | |
| "WORK": "WORK", | |
| "CELL": "CELL", | |
| "MAIN": "MAIN", | |
| "OTHER":"OTHER" | |
| }, | |
| create: function(version) { | |
| for(var key in this.Version) { | |
| if(this.Version[key] === version) | |
| return new Card(version) | |
| } | |
| throw new Error("Unknown vCard version") | |
| }, | |
| dump: function(card) { | |
| var str = "BEGIN:VCARD\n" | |
| for(var key in card) { | |
| var entry = card[key] | |
| if(typeof entry === "function") | |
| continue | |
| if(Object.prototype.toString.call(entry) === "[object Array]") { | |
| for(var i = 0, l = entry.length; i < l; i++) { | |
| var e = entry[i] | |
| str += key.toUpperCase() + (e.type ? ";TYPE=" + e.type.toUpperCase() + ":" : ":") + e.value + "\n" | |
| } | |
| } else if(typeof entry === "object") { | |
| str += key.toUpperCase() + (entry.type ? ";TYPE=" + entry.type.toUpperCase() + ":" : ":") + entry.value + "\n" | |
| } else { | |
| str += key.toUpperCase() + ":" + entry + "\n" | |
| } | |
| } | |
| str += "END:VCARD" | |
| return str | |
| }, | |
| export: function(card, name, force) { | |
| var a = document.createElement('a') | |
| a.download = name + ".vcf" | |
| a.textContent = name | |
| if(Blob) { | |
| var blob = new Blob([this.dump(card)], {"type": "text/vcard"}) | |
| a.href = URL.createObjectURL(blob) | |
| } else { | |
| a.href = "data:text/vcard;base64," + this.btoa(this.dump(card)) | |
| } | |
| force && a.click() | |
| return a | |
| }, | |
| btoa: function(str) { | |
| str = unescape(encodeURIComponent(str)) | |
| if(!btoa) { | |
| var b64c = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | |
| var i, res = "", length = str.length; | |
| for (i = 0; i < length - 2; i += 3) { | |
| res += b64c[str.charCodeAt(i) >>> 2]; | |
| res += b64c[((str.charCodeAt(i) & 3) << 4) | (str.charCodeAt(i + 1) >>> 4)]; | |
| res += b64c[((str.charCodeAt(i + 1) & 15) << 2) | (str.charCodeAt(i + 2) >>> 6)]; | |
| res += b64c[str.charCodeAt(i + 2) & 63]; | |
| } | |
| if (length % 3 === 2) { | |
| res += b64c[str.charCodeAt(i) >>> 2]; | |
| res += b64c[((str.charCodeAt(i) & 3) << 4) | (str.charCodeAt(i + 1) >>> 4)]; | |
| res += b64c[((str.charCodeAt(i + 1) & 15) << 2)]; | |
| res += "="; | |
| } else if (length % 3 === 1) { | |
| res += b64c[str.charCodeAt(i) >>> 2]; | |
| res += b64c[((str.charCodeAt(i) & 3) << 4)]; | |
| res += "=="; | |
| } | |
| return res; | |
| } else { | |
| return btoa(str) | |
| } | |
| } | |
| } | |
| var Card = function(version) { | |
| this.version = version | |
| for(var key in vCard.Entry) { | |
| var property = vCard.Entry[key] | |
| if(!property.version || property.version.indexOf(version) < 0) | |
| continue | |
| var fn = "add" + key[0].toUpperCase() + key.slice(1).toLowerCase() | |
| Card.prototype[fn] = (function(key, format) { | |
| return (function() { | |
| var args = Array.prototype.slice.call(arguments) | |
| var lastArg = args.length > 0 ? args[args.length - 1] : undefined | |
| var model = vCard.Type.hasOwnProperty(lastArg) ? args.slice(0, args.length - 1) : args | |
| var value = format && format.replace(/\{([0-9]*)\}/g, function(match, parameter) { | |
| return model[parseInt(parameter)] || '' | |
| }) || model[0] | |
| this.add(key, value, vCard.Type.hasOwnProperty(lastArg) && lastArg) | |
| }) | |
| })(property.key, property.format) | |
| } | |
| this.add = function(entry, value, type) { | |
| var key = (typeof entry === "object" && entry.key) ? entry.key : entry | |
| !this[key] && (this[key] = []) | |
| var e = {"value": value} | |
| type && (e.type = type) | |
| this[key].push(e) | |
| } | |
| } | |
| context.vCard = vCard | |
| })(this) |
Thanks for this. 👍
This works well. The helper methods are cleverly created in the Card object.
Thanks for sharing brother.
how i attach image in vcard using your code??
Thanks for the code! Is it possible to create custom labels, for instance for the Work phone currently it just generates "phone:", how would i make it generate "office:" or "mobile:"?
Yes. I could achieve this by using version 3.0 instead of 4.0. I could then construct it like so
tel: [
{ value: '555-555-555', type: 'Group office' },
{ value: '111-111-2222', type: 'General Office' },
{ value: '111-223-2222', type: 'Another department' }
],
I want to add new line in NOTE section of vcard. i tried doing it with \n and ; . but none of them is working
Thanks for the code is very useful, could you guide me in how I can do to attach images?
any update
how to attach the image in card
card can't download in chrome iphone
hi
any way for UTF-8 ?
Check this "https://www.geeksforgeeks.org/how-to-convert-image-into-base64-string-using-javascript/" to convert the image to base64 string then add it to vcf card with PHOTO;TYPE=PNG;ENCODING=b:
example
BEGIN:VCARD
VERSION:4.0
N:SMITH;John;;
FN:John Smith
NICKNAME:js
TITLE:Missing man too
TEL;TYPE=CELL:555-555-555
EMAIL;TYPE=WORK:john.smith@work.com
EMAIL;TYPE=HOME:john.smith@home.com
PHOTO;TYPE=PNG;ENCODING=b:base64 string
END:VCARD
Thanks for the code! Is it possible to create custom labels, for instance for the Work phone currently it just generates "phone:", how would i make it generate "office:" or "mobile:"?