├── .gitignore ├── README.md ├── examples ├── example.htm └── load.htm └── src └── jquery.jsonify-0.1.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .buildpath 3 | .settings 4 | .project -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | With jsonify you are able to convert a DOM Tree into a serialized JSON object by just 4 | adding [HTML5 data attributes](http://ejohn.org/blog/html-5-data-attributes/) to your HTML. The current version is still very basic, but it covers the most parts I need to use at the moment. 5 | 6 | ## Data attributes 7 | 8 | - **data-jsonify-name**: Use the JavaScript dot-notation for the element 9 | - **data-jsonify-getter**: The name of a custom renderer, specified by the plugin getters-object. 10 | 11 | ## Example 12 | 13 | ```javascript 14 | $('.submit').click(function () { 15 | var object, json; 16 | 17 | object = $('form').jsonify(); 18 | json = JSON.stringify(object, null, 4); 19 | 20 | alert(json); 21 | 22 | return false; 23 | }); 24 | ``` 25 | 26 | ```html 27 |
28 |
29 | Person: 30 | 31 | 32 |
33 | 34 | 35 |
36 | 37 |
38 | 39 |
40 | Favorite food 41 | 42 |
43 | 44 | Orange: 45 |
46 | 47 | Banana: 48 |
49 | 50 | Strawberry: 51 |
52 | 53 |
54 | 55 | 56 | 57 |
58 | ``` 59 | 60 | ## JSFiddle examples 61 | 62 | Want to see live examples? 63 | 64 | - [Multiple contacts](http://jsfiddle.net/jorgen/K36Er/) 65 | - [Getters and casting explained](http://jsfiddle.net/jorgen/wJqzU/) 66 | 67 | ## Author 68 | 69 | Jorgen Horstink (jorgenhorstink [at] gmail [dot] com) 70 | 71 | ## TODO 72 | 73 | TBD 74 | 75 | ## Licence 76 | 77 | TBD -------------------------------------------------------------------------------- /examples/example.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 38 | 39 | 40 | 41 |
42 | 43 |
44 | Person: 45 | 46 | 47 |
48 | 49 | 50 |
51 | 52 | 53 |
58 | 59 | 60 | 71 |
72 | 73 |
74 | Which of the following fruit do you like? 75 | 76 | Orange: 77 |
78 | 79 | Banana: 80 |
81 | 82 | Strawberry: 83 |
84 | 85 |
86 | 87 |
88 | Which of the following drinks do you like? 89 | 90 | 91 | Beer: 92 |
93 | 94 | Wine: 95 |
96 | 97 | Lemonade: 98 |
99 | 100 |
101 | 102 | 118 | 128 | 129 | 130 | 131 |
132 | 133 | 134 | -------------------------------------------------------------------------------- /examples/load.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 34 | 35 | 36 | JSON input: 37 |
38 |     {
39 |         "person" : {
40 |             "name" : "Jorgen Horstink",
41 |             "city" : "UTRECHT"
42 |         },
43 |         
44 |         "fruit" : [
45 |             { "name" : "Orange",     "like" : true },
46 |             { "name" : "Banana",     "like" : true },
47 |             { "name" : "Strawberry", "like" : true }
48 |         ]
49 |     }
50 |             
51 | 52 |
53 | 54 |
55 | Person: 56 | 57 | 58 |
59 | 60 | 61 |
62 |
63 | 64 |
65 | Which of the following fruit do you like? 66 | 67 | Orange: 68 |
69 | 70 | Banana: 71 |
72 | 73 | Strawberry: 74 |
75 | 76 |
77 |
78 | 79 | -------------------------------------------------------------------------------- /src/jquery.jsonify-0.1.js: -------------------------------------------------------------------------------- 1 | (function ($) { 2 | 3 | "use strict"; 4 | 5 | var getters = { 6 | "default" : function () { 7 | if (this.is('input[type="checkbox"],input[type="radio"]')) { 8 | return this.is(':checked'); 9 | } else if (this.is('select')) { 10 | return this.val() === '' ? null : this.val(); 11 | } else { 12 | return this.val(); 13 | } 14 | } 15 | }; 16 | 17 | function jsonify(element, options) { 18 | 19 | var json, root, getPath, getValue, getCastedValue; 20 | 21 | root = json = {}; 22 | 23 | getPath = (function () { 24 | // Performance tuning: If there is no descendent with data-jsonify-array attribute, we can just return the simple jsonify-name 25 | if (element.find('[data-jsonify-array]').length > 0) { 26 | 27 | // Usefull for repeatable UI components 28 | return function (item) { 29 | var parts = [item.data('jsonify-name')], i, parents; 30 | 31 | parents = item.parents('[data-jsonify-array-item],[data-jsonify-array]').each(function () { 32 | 33 | var $this = $(this), item = $this.data('jsonify-array-item'), array = $this.data('jsonify-array'); 34 | 35 | if (item !== undefined) { 36 | i = $this.prevAll('[data-jsonify-array-item]').length; 37 | } else if (array !== undefined) { 38 | parts.push(array + '[' + i + ']'); 39 | } 40 | }); 41 | 42 | return parts.reverse().join('.'); 43 | }; 44 | } else { 45 | return function (item) { 46 | return item.data('jsonify-name'); 47 | }; 48 | } 49 | }()); 50 | 51 | getValue = function (item) { 52 | var getter, type, value; 53 | 54 | if (item.data('jsonify-getter')) { 55 | 56 | var parts = item.data('jsonify-getter').split(':'); 57 | 58 | getter = parts[0] === "" ? "default" : parts[0]; 59 | type = parts[1] || null; 60 | 61 | } else { 62 | getter = "default"; 63 | } 64 | 65 | if (getters[getter]) { 66 | value = getters[getter].apply(item) 67 | } else { 68 | options.getters[getter].apply(item); 69 | } 70 | 71 | if (type !== null) { 72 | value = getCastedValue(type, value); 73 | } 74 | 75 | return value; 76 | }; 77 | 78 | getCastedValue = function (type, value) { 79 | if (type === 'int') { 80 | return parseInt(value, 10); // radix paramenter = 10 81 | } else if (type === 'float') { 82 | return parseFloat(value, 10); // radix paramenter = 10 83 | } else if (type === 'boolean' || type === 'bool') { 84 | return value === 1 || value === "1" || value === true || value === "true" || value === "yes"; 85 | } else { 86 | return value; 87 | } 88 | }; 89 | 90 | element.find('[data-jsonify-name]').each(function () { 91 | 92 | var path = getPath($(this)), parts = path.split('.'), i = 0, l = parts.length, part, name, ai, value; 93 | 94 | json = root; 95 | 96 | for (i; i < l; i += 1) { 97 | part = parts[i]; 98 | 99 | if (i === l - 1) { 100 | value = getValue($(this)); 101 | } else { 102 | value = {}; 103 | } 104 | 105 | if (part.substr(-1) === ']') { 106 | // array 107 | 108 | name = part.split('[')[0]; 109 | // array index 110 | ai = part.match(/([0-9]+)\]$/)[1]; 111 | 112 | // create the empty array if it does not exist yet 113 | if (!json[name]) { 114 | json[name] = []; 115 | } 116 | 117 | // create the array index if it does not exist yet 118 | if (!json[name][ai]) { 119 | json[name][ai] = value; 120 | } 121 | 122 | json = json[name][ai]; 123 | } else { 124 | // no array 125 | 126 | name = part; 127 | 128 | if (!json[name]) { 129 | json[name] = value; 130 | } 131 | 132 | json = json[name]; 133 | } 134 | } 135 | }); 136 | 137 | return root; 138 | } 139 | 140 | $.fn.jsonify = function (options) { 141 | var ret = null; 142 | 143 | this.each(function () { 144 | ret = jsonify($(this), options); 145 | }); 146 | 147 | return ret; 148 | }; 149 | 150 | $.jsonify = function (options) { 151 | $.extend(getters, options.getters || {}); 152 | }; 153 | 154 | }(window.jQuery)); --------------------------------------------------------------------------------