From 9688c5579c3385dd08941de21a641a5f2ed9324e Mon Sep 17 00:00:00 2001 From: Phil Mottin Date: Tue, 27 Jul 2021 18:52:50 -0300 Subject: [PATCH 1/5] Fix selector bug. Add parse title, footer +options Bug fix - selector with no class. Improve performance - only call parseTableData() once - Removed getHighestColumnCount () and getObjectLength() functions. Using Object.keys(data).length property. Features: - toggle table header, row numbers - set initial row number value - set table width - custom parser function - toggle parse headers, row numbers - choose columns to parse - added title and footer - debug parameter, show all indexes on all cells --- Example/Example parse function.html | 127 ++++++++++++++++++ Example/{example.html => Example.html} | 42 ++---- Example/External JSON Example.html | 76 +++++++++++ JSON-to-Table-1.0.0.js | 157 ----------------------- JSON-to-Table-1.0.1.js | 171 +++++++++++++++++++++++++ JSON-to-Table.min.1.0.0.js | 2 - JSON-to-Table.min.1.0.1.js | 1 + README.md | 165 +++++++++++++++++++++++- screenshot parser.png | Bin 0 -> 19417 bytes 9 files changed, 545 insertions(+), 196 deletions(-) create mode 100644 Example/Example parse function.html rename Example/{example.html => Example.html} (71%) create mode 100644 Example/External JSON Example.html delete mode 100644 JSON-to-Table-1.0.0.js create mode 100644 JSON-to-Table-1.0.1.js delete mode 100644 JSON-to-Table.min.1.0.0.js create mode 100644 JSON-to-Table.min.1.0.1.js create mode 100644 screenshot parser.png diff --git a/Example/Example parse function.html b/Example/Example parse function.html new file mode 100644 index 0000000..5c3cec3 --- /dev/null +++ b/Example/Example parse function.html @@ -0,0 +1,127 @@ + + + + + JSON-to-Table parser example + + + + +

JSON Data To HTML Table - An Example of Lightweight jQuery Plugin for Beginners

+

Custom parse function Example

+
+ + + + + + \ No newline at end of file diff --git a/Example/example.html b/Example/Example.html similarity index 71% rename from Example/example.html rename to Example/Example.html index 5419ebf..653232a 100644 --- a/Example/example.html +++ b/Example/Example.html @@ -5,8 +5,6 @@ JSON Data To HTML Table - jQuery Plugin - - +

JSON Data To HTML Table - An Example of Lightweight jQuery Plugin for Beginners

-

External JSON data file Example

-

JSON Object variable Example

-
- + +
- // Table Body/Row Style - trBg: '#FFFFFF', - trColor: '#0E0E0E', - trHeight: '25px', - trFontFamily: '"Open Sans", sans-serif', - trFontSize: '13px', - - // Table Body's Column Style - tdPaddingLeft: '10px', - tdPaddingRight: '10px' - }); - }); + diff --git a/Example/External JSON Example.html b/Example/External JSON Example.html new file mode 100644 index 0000000..e286a1a --- /dev/null +++ b/Example/External JSON Example.html @@ -0,0 +1,76 @@ + + + + + JSON Data To HTML Table - jQuery Plugin + + + + +

JSON Data To HTML Table - An Example of Lightweight jQuery Plugin for Beginners

+

External JSON data file Example

+

⚠ Must run vai web server. CORS policy won't allow to load data locally.

+
+ + + + + + \ No newline at end of file diff --git a/JSON-to-Table-1.0.0.js b/JSON-to-Table-1.0.0.js deleted file mode 100644 index 2b9adab..0000000 --- a/JSON-to-Table-1.0.0.js +++ /dev/null @@ -1,157 +0,0 @@ -(function ($) { - - $.fn.createTable = function (data, options) { - - var element = this; - var settings = $.extend({}, $.fn.createTable.defaults, options); - var selector; - - if (element[0].className !== undefined) { - var split = element[0].className.split(' '); - selector = '.' + split.join('.') + ' '; - } else if (element[0].id !== undefined) { - selector = '#' + element[0].id + ' '; - } - - var table = ''; - - table += ''; - table += $.fn.createTable.parseTableData(data, true); - table += ''; - table += ''; - table += $.fn.createTable.parseTableData(data, false); - table += ''; - table += '
'; - - element.html(table); - - return function () { - - $(selector + '.json-to-table').css({ - borderCollapse: 'collapse', - width: '100%', - border: settings.borderWidth + ' ' + settings.borderStyle + ' ' + settings.borderColor, - fontFamily: settings.fontFamily - }); - - $(selector + '.jsl').css({ - minWidth: '18px', - width: '18px', - padding: '0 10px 0 10px' - }); - - $(selector + '.json-to-table thead th:not(:first-child), .json-to-table tbody td:not(:first-child)').css({ - width: (100 / $.fn.createTable.getHighestColumnCount(data).max) + '%' - }); - - $(selector + '.json-to-table thead th, .json-to-table tbody td').css({ - border: settings.borderWidth + ' ' + settings.borderStyle + ' ' + settings.borderColor - }); - - $(selector + '.json-to-table thead th').css({ - backgroundColor: settings.thBg, - color: settings.thColor, - height: settings.thHeight, - fontFamily: settings.thFontFamily, - fontSize: settings.thFontSize, - textTransform: settings.thTextTransform - }); - - $(selector + '.json-to-table tbody td').css({ - backgroundColor: settings.trBg, - color: settings.trColor, - paddingLeft: settings.tdPaddingLeft, - paddingRight: settings.tdPaddingRight, - height: settings.trHeight, - fontSize: settings.trFontSize, - fontFamily: settings.trFontFamily - }); - - }(); - }; - - $.fn.createTable.getHighestColumnCount = function (data) { - - var count = 0, temp = 0, column = {max: 0, when: 0}; - - for (var i = 0; i < data.length; i++) { - count = $.fn.getObjectLength(data[i]); - if (temp <= count) { - temp = count; - column.max = count; - column.when = i; - } - } - - return column; - }; - - $.fn.createTable.parseTableData = function (data, thead) { - - var row = ''; - - for (var i = 0; i < data.length; i++) { - if (thead === false) row += '' + (i + 1) + ''; - $.each(data[i], function (key, value) { - if (thead === true) { - if (i === $.fn.createTable.getHighestColumnCount(data).when) { - row += '' + $.fn.humanize(key) + ''; - } - } else if (thead === false) { - row += '' + value + ''; - } - }); - if (thead === false) row += ''; - } - - return row; - }; - - $.fn.getObjectLength = function (object) { - - var length = 0; - - for (var key in object) { - if (object.hasOwnProperty(key)) { - ++length; - } - } - - return length; - }; - - $.fn.humanize = function (text) { - - var string = text.split('_'); - - for (i = 0; i < string.length; i++) { - string[i] = string[i].charAt(0).toUpperCase() + string[i].slice(1); - } - - return string.join(' '); - }; - - $.fn.createTable.defaults = { - borderWidth: '1px', - borderStyle: 'solid', - borderColor: '#DDDDDD', - fontFamily: 'Verdana, Helvetica, Arial, FreeSans, sans-serif', - - thBg: '#F3F3F3', - thColor: '#0E0E0E', - thHeight: '30px', - thFontFamily: 'Verdana, Helvetica, Arial, FreeSans, sans-serif', - thFontSize: '14px', - thTextTransform: 'capitalize', - - trBg: '#FFFFFF', - trColor: '#0E0E0E', - trHeight: '25px', - trFontFamily: 'Verdana, Helvetica, Arial, FreeSans, sans-serif', - trFontSize: '13px', - - tdPaddingLeft: '10px', - tdPaddingRight: '10px' - } - -}(jQuery)); \ No newline at end of file diff --git a/JSON-to-Table-1.0.1.js b/JSON-to-Table-1.0.1.js new file mode 100644 index 0000000..bf6e946 --- /dev/null +++ b/JSON-to-Table-1.0.1.js @@ -0,0 +1,171 @@ +(function ($) { + $.fn.createTable = function (data, options) { + var element = this; + var settings = $.extend({}, $.fn.createTable.defaults, options); + var selector; + + if (element[0].className !== undefined && element[0].className.length > 0) { + var split = element[0].className.split(' '); + selector = '.' + split.join('.') + ' '; + } else if (element[0].id !== undefined) { + selector = '#' + element[0].id + ' '; + } + + var table = $.fn.createTable.parseTableData(data, settings.showTableHeader, settings); + element.html(table); + + return function () { + $(selector + '.json-to-table').css({ + borderCollapse: 'collapse', + width: settings.width, + border: settings.borderWidth + ' ' + settings.borderStyle + ' ' + settings.borderColor, + fontFamily: settings.fontFamily + }); + + $(selector + '.json-to-table caption#title').css({ + captionSide: 'top', + textAlign: settings.titleAlign + }); + $(selector + '.json-to-table caption#footer').css({ + captionSide: 'bottom', + textAlign: settings.footerAlign, + fontSize: '12px' + + }); + + $(selector + '.jsl').css({ + minWidth: '18px', + width: '18px', + padding: '0' + }); + + if (settings.colsSameWidh) { + $(selector + '.json-to-table thead th:not(:first-child), .json-to-table tbody td:not(:first-child)').css({ + width: (100 / Object.keys(data[0]).length ) + '%' + }); + } + + $(selector + '.json-to-table thead th, .json-to-table tbody td').css({ + border: settings.borderWidth + ' ' + settings.borderStyle + ' ' + settings.borderColor + }); + + $(selector + '.json-to-table thead th').css({ + backgroundColor: settings.thBg, + color: settings.thColor, + height: settings.thHeight, + fontFamily: settings.thFontFamily, + fontSize: settings.thFontSize, + textTransform: settings.thTextTransform + }); + + $(selector + '.json-to-table tbody td').css({ + backgroundColor: settings.trBg, + color: settings.trColor, + paddingLeft: settings.tdPaddingLeft, + paddingRight: settings.tdPaddingRight, + height: settings.trHeight, + fontSize: settings.trFontSize, + fontFamily: settings.trFontFamily + }); + }(); + }; + + $.fn.createTable.isFunction = function (functionToCheck) { + return functionToCheck && {}.toString.call(functionToCheck) === '[object Function]'; + } + + $.fn.createTable.parseTableData = function (data, thead, settings) { + + if (settings.debug) { + settings.parser = function(rowIdx, colIdx, value, isHead){ return (rowIdx+':'+colIdx); }; + settings.parseHeader = true; + settings.parseRowNumber = true; + settings.showTitle = true; + settings.showFooter = true; + } + + var table = ''; + table = ''; + + title = settings.titleText? settings.titleText : data.length+' records'; + footer = settings.footerText? settings.footerText : data.length+' records'; + if (settings.showTitle) table += ''; + if (settings.showFooter) table += ''; + + var iColHeader = 1; + if (thead === true) { + table += settings.showTableRowNumber ? '' : ''; + + $.each(data[0], function (key, value) { + if ($.fn.createTable.isFunction(settings.parser)) { + settings.parserCols = Array.isArray(settings.parserCols) ? settings.parserCols : []; + key = settings.parseHeader ? settings.parser(0, iColHeader, key, thead) : key; + } + iColHeader++; + table += ''; + }); + table += ''; + } + table += ''; + + for (var i = 0; i < data.length; i++) { + if ($.fn.createTable.isFunction(settings.parser)) { + settings.parserCols = Array.isArray(settings.parserCols) ? settings.parserCols : []; + value = settings.parseRowNumber ? settings.parser(i+1, 0, settings.rowNumberInitialValue + i, thead) : settings.rowNumberInitialValue + i; + } + table += settings.showTableRowNumber ? ('') : ''; + + iCol = 1; + $.each(data[i], function (key, value) { + if ($.fn.createTable.isFunction(settings.parser)) { + settings.parserCols = Array.isArray(settings.parserCols) ? settings.parserCols : []; + value = (settings.parserCols.includes(key) || settings.parserCols.length == 0) ? settings.parser(i+1, iCol, value, thead) : value; + } + iCol++; + table += ''; + }); + if (thead === false) table += ''; + } + table += ''; + table += '
'+title+''+footer+'
' + $.fn.humanize(key) + '
'+(value)+'
' + value + '
'; + return table; + }; + + $.fn.humanize = function (text) { + var string = text.split('_') + for (i = 0; i < string.length; i++) { + string[i] = string[i].charAt(0).toUpperCase() + string[i].slice(1); + } + return string.join(' '); + }; + + $.fn.createTable.defaults = { + width: '100%', + showTableHeader: true, + rowNumberInitialValue: 1, + + titleAlign: 'center', + footerAlign: 'center', + + borderWidth: '1px', + borderStyle: 'solid', + borderColor: '#DDDDDD', + fontFamily: 'Verdana, Helvetica, Arial, FreeSans, sans-serif', + + thBg: '#F3F3F3', + thColor: '#0E0E0E', + thHeight: '30px', + thFontFamily: 'Verdana, Helvetica, Arial, FreeSans, sans-serif', + thFontSize: '14px', + thTextTransform: 'capitalize', + + trBg: '#FFFFFF', + trColor: '#0E0E0E', + trHeight: '25px', + trFontFamily: 'Verdana, Helvetica, Arial, FreeSans, sans-serif', + trFontSize: '13px', + + tdPaddingLeft: '10px', + tdPaddingRight: '10px' + } +}(jQuery)); \ No newline at end of file diff --git a/JSON-to-Table.min.1.0.0.js b/JSON-to-Table.min.1.0.0.js deleted file mode 100644 index 8102ff0..0000000 --- a/JSON-to-Table.min.1.0.0.js +++ /dev/null @@ -1,2 +0,0 @@ - -!function(t){t.fn.createTable=function(e,a){var r,o=this,n=t.extend({},t.fn.createTable.defaults,a);if(void 0!==o[0].className){var i=o[0].className.split(" ");r="."+i.join(".")+" "}else void 0!==o[0].id&&(r="#"+o[0].id+" ");var l='';return l+='',l+=t.fn.createTable.parseTableData(e,!0),l+="",l+="",l+=t.fn.createTable.parseTableData(e,!1),l+="",l+="
",o.html(l),function(){t(r+".json-to-table").css({borderCollapse:"collapse",width:"100%",border:n.borderWidth+" "+n.borderStyle+" "+n.borderColor,fontFamily:n.fontFamily}),t(r+".jsl").css({minWidth:"18px",width:"18px",padding:"0 10px 0 10px"}),t(r+".json-to-table thead th:not(:first-child), .json-to-table tbody td:not(:first-child)").css({width:100/t.fn.createTable.getHighestColumnCount(e).max+"%"}),t(r+".json-to-table thead th, .json-to-table tbody td").css({border:n.borderWidth+" "+n.borderStyle+" "+n.borderColor}),t(r+".json-to-table thead th").css({backgroundColor:n.thBg,color:n.thColor,height:n.thHeight,fontFamily:n.thFontFamily,fontSize:n.thFontSize,textTransform:n.thTextTransform}),t(r+".json-to-table tbody td").css({backgroundColor:n.trBg,color:n.trColor,paddingLeft:n.trPaddingLeft,paddingRight:n.trPaddingRight,height:n.trHeight,fontSize:n.trFontSize,fontFamily:n.trFontFamily})}()},t.fn.createTable.getHighestColumnCount=function(e){for(var a=0,r=0,o={max:0,when:0},n=0;n=r&&(r=a,o.max=a,o.when=n);return o},t.fn.createTable.parseTableData=function(e,a){for(var r="",o=0;o'+(o+1)+""),t.each(e[o],function(n,i){a===!0?o===t.fn.createTable.getHighestColumnCount(e).when&&(r+=""+t.fn.humanize(n)+""):a===!1&&(r+=""+i+"")}),a===!1&&(r+="");return r},t.fn.getObjectLength=function(t){var e=0;for(var a in t)t.hasOwnProperty(a)&&++e;return e},t.fn.humanize=function(t){var e=t.split("_");for(i=0;i0){var i=this[0].className.split(" ");o="."+i.join(".")+" "}else void 0!==this[0].id&&(o="#"+this[0].id+" ");var l=t.fn.createTable.parseTableData(e,a.showTableHeader,a);return this.html(l),t(o+".json-to-table").css({borderCollapse:"collapse",width:a.width,border:a.borderWidth+" "+a.borderStyle+" "+a.borderColor,fontFamily:a.fontFamily}),t(o+".json-to-table caption#title").css({captionSide:"top",textAlign:a.titleAlign}),t(o+".json-to-table caption#footer").css({captionSide:"bottom",textAlign:a.footerAlign,fontSize:"12px"}),t(o+".jsl").css({minWidth:"18px",width:"18px",padding:"0"}),a.colsSameWidh&&t(o+".json-to-table thead th:not(:first-child), .json-to-table tbody td:not(:first-child)").css({width:100/Object.keys(e[0]).length+"%"}),t(o+".json-to-table thead th, .json-to-table tbody td").css({border:a.borderWidth+" "+a.borderStyle+" "+a.borderColor}),t(o+".json-to-table thead th").css({backgroundColor:a.thBg,color:a.thColor,height:a.thHeight,fontFamily:a.thFontFamily,fontSize:a.thFontSize,textTransform:a.thTextTransform}),void t(o+".json-to-table tbody td").css({backgroundColor:a.trBg,color:a.trColor,paddingLeft:a.tdPaddingLeft,paddingRight:a.tdPaddingRight,height:a.trHeight,fontSize:a.trFontSize,fontFamily:a.trFontFamily})},t.fn.createTable.isFunction=function(t){return t&&"[object Function]"==={}.toString.call(t)},t.fn.createTable.parseTableData=function(e,r,o){o.debug&&(o.parser=function(t,e,r,o){return t+":"+e},o.parseHeader=!0,o.parseRowNumber=!0,o.showTitle=!0,o.showFooter=!0);var a="";a='',title=o.titleText?o.titleText:e.length+" records",footer=o.footerText?o.footerText:e.length+" records",o.showTitle&&(a+='"),o.showFooter&&(a+='");var i=1;!0===r&&(a+=o.showTableRowNumber?'':"",t.each(e[0],function(e,l){t.fn.createTable.isFunction(o.parser)&&(o.parserCols=Array.isArray(o.parserCols)?o.parserCols:[],e=o.parseHeader?o.parser(0,i,e,r):e),i++,a+=""}),a+=""),a+="";for(var l=0;l":"",iCol=1,t.each(e[l],function(e,i){t.fn.createTable.isFunction(o.parser)&&(o.parserCols=Array.isArray(o.parserCols)?o.parserCols:[],i=o.parserCols.includes(e)||0==o.parserCols.length?o.parser(l+1,iCol,i,r):i),iCol++,a+=""}),!1===r&&(a+="");return a+="",a+="
'+title+"'+footer+"
"+t.fn.humanize(e)+"
'+value+"
"+i+"
"},t.fn.humanize=function(t){var e=t.split("_");for(i=0;i **Table properties** + +- #### showTableRowNumber + Display the first column as counter. + Default: false + + **Ex:** `showTableHeaderCounter: true` + +- #### rowNumberInitialValue + If you would like start with row number 9 set it. Otherwise let default as 1. + Default: 1 + + **Ex:** `rowNumberInitialValue: 101` + +- #### parser + Custom function to parse data values. + Default: none + + **Ex:** `parser: function(rowIdx, colIdx, value, isHead) { /* function scope */ return value; }` + +- #### parserCols + Array of columns names to execute the parser function. If ommited, the parser run on all fields. + Default: all cells, except header and rowNumbers. + + **Ex:** `parserCols: ['column1','column2']` + +- #### parseHeader + Enable parsing on header cells + Default: false + + **Ex:** `parseHeader: true` + +- #### parseRowNumber + Enable parsing on rowNumber cells + Default: false + + **Ex:** `parseRowNumber: true` + +- #### showTitle + Enable table title at the top + Default: false + + **Ex:** `showTitle: true` + +- #### titleText + Text to display in the title + Default: Will show the number of records. `'n records'` + + **Ex:** `titleText: 'My awesome table title'` + +- #### titleAlign + Set the alignment of the title. `('left' | 'center' | 'right')` + Default: 'center' + + **Ex:** `titleAlign: 'left'` + +- #### showFooter + Enable table footer at the bottom + Default: false + + **Ex:** `showFooter: true` + +- #### footerText + Text to display in the footer + Default: Will show the number of records. `'n records'` + + **Ex:** `footerText: 'My awesome table footer'` + +- #### footerAlign + Set the alignment of the footer. `('left' | 'center' | 'right')` + Default: 'center' + + **Ex:** `footerAlign: 'left'` -## Property Definition > **Every single value of these properties is similar to CSS property value.** + +- #### colsSameWidh + Set all table columns with same widht + Default: false + + **Ex:** `colsSameWidh: true + +- #### width + Set table width. Any css unit can be used like '%', 'px', 'em' + Default: '100%' + + **Ex:** `width: '1200px'` + - #### borderWidth Defines to control table and it's all rows and columns border width. @@ -117,6 +207,75 @@ Just call `createTable` method in your document ready function with your json `d ## Examples +##### Use custom parser +```javascript +var data = [ + { + "id": 1123, + "first_name": "Alli", + "last_name": "Cassey", + "email": "acassey0@list-manage.com", + "gender": "Female", + "registered": false + }, + { + "id": 1124, + "first_name": "Clyde", + "last_name": "Bromage", + "email": "cbromage1@bbb.org", + "gender": "Male", + "registered": true + }, + { + "id": 1125, + "first_name": "Janeczka", + "last_name": "Trett", + "email": "jtrett2@vistaprint.com", + "gender": "Female", + "registered": null + }, + { + "id": 1126, + "first_name": "Kristoforo", + "last_name": "Duplain", + "email": "kduplain3@vimeo.com", + "gender": "Male", + "registered": true + }, + { + "id": 1127, + "first_name": "Devonna", + "last_name": "Medeway", + "email": "dmedeway4@google.nl", + "gender": "Female", + "registered": false + } + ]; + + var parser = function(value) { + if (String(value) == 'true') + value = '✔'; + else if (String(value) == 'false') + value = '-'; + else if (value == null) + value = ''; + else if (value == 'Female') + value = '👨🏻'; + else if (value == 'Male') + value = '👩🏻'; + return value; + + $('#table').createTable(data, { showTableHeaderCounter: true, + parser: parser, + parserCols: ['gender','registered'], + colsSameWidh: false, + width: '80%' + }); +``` + + + + ##### Using a JSON data from your JS variable. ```javascript var data = [ diff --git a/screenshot parser.png b/screenshot parser.png new file mode 100644 index 0000000000000000000000000000000000000000..5ca07db79b12db9f86e4c814e2fc7a76ccf5664f GIT binary patch literal 19417 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 Date: Tue, 27 Jul 2021 19:12:49 -0300 Subject: [PATCH 2/5] Update readme --- README.md | 23 ++++++++++++------ ...enshot parser.png => screenshot_parser.png | Bin 2 files changed, 15 insertions(+), 8 deletions(-) rename screenshot parser.png => screenshot_parser.png (100%) diff --git a/README.md b/README.md index 0fe0395..d915379 100644 --- a/README.md +++ b/README.md @@ -3,30 +3,37 @@ JSON Data To HTML Table is Example of Lightweight jQuery Plugin for Beginners. Though this is not a datatable, you can modify this plugin and customize it to make your own datatable. This is an example to make an HTML table with JSON data. -![alt text](https://github.com/shahnewazshamim/json-to-table/blob/master/screenshot.png "JSON to HTML Table") +![alt text](https://github.com/philmottin/json-to-table/blob/master/screenshot.png "JSON to HTML Table") +![alt text](https://github.com/philmottin/json-to-table/blob/master/screenshot_parser.png "JSON to HTML Parse Table") ## Download #### Current Version Version 1.0.1 -You can download the [latest or current stable](https://github.com/shahnewazshamim/json-to-table/releases/latest) version +This project was forked from `https://github.com/shahnewazshamim/json-to-table` to include new features. + +You can download the [latest or current stable](https://github.com/philmottin/json-to-table/releases/latest) version from here (***recommended***) or download it form master branch (*not recommended*). -> `https://github.com/shahnewazshamim/json-to-table/archive/master.zip` +> `https://github.com/philmottin/json-to-table/archive/refs/heads/master.zip` Git Clone: -> `https://github.com/shahnewazshamim/json-to-table.git` +> `https://github.com/philmottin/json-to-table.git` ## Installation -Using **Production version** `JSON-to-Table.min.1.0.0.js` +1- Add jQuery > `` -Or **Development version** `JSON-to-Table.1.0.0.js` -> `` +2- Add JSON-to-Table pluging +Using **Production version** `JSON-to-Table.min.1.0.1.js` +> `` + +Or **Development version** `JSON-to-Table-1.0.1.js` +> `` ## How to use Just call `createTable` method in your document ready function with your json `data` object. -`$('your-selector').createTable(data, optionsObject, parserFunction);` +`$('your-selector').createTable(data, optionsObject);` diff --git a/screenshot parser.png b/screenshot_parser.png similarity index 100% rename from screenshot parser.png rename to screenshot_parser.png From 6017e42c66fdf4232eb46a58185bde23a27c815e Mon Sep 17 00:00:00 2001 From: Phil Mottin Date: Tue, 27 Jul 2021 19:20:37 -0300 Subject: [PATCH 3/5] Update readme examples --- README.md | 61 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index d915379..32a90e8 100644 --- a/README.md +++ b/README.md @@ -113,6 +113,12 @@ Just call `createTable` method in your document ready function with your json `d **Ex:** `footerAlign: 'left'` +- #### debug + Show all indexes on all cells + Default: false + + **Ex:** `debug: true` + > **Every single value of these properties is similar to CSS property value.** - #### colsSameWidh @@ -259,25 +265,42 @@ var data = [ } ]; - var parser = function(value) { - if (String(value) == 'true') - value = '✔'; - else if (String(value) == 'false') - value = '-'; - else if (value == null) - value = ''; - else if (value == 'Female') - value = '👨🏻'; - else if (value == 'Male') - value = '👩🏻'; - return value; - - $('#table').createTable(data, { showTableHeaderCounter: true, - parser: parser, - parserCols: ['gender','registered'], - colsSameWidh: false, - width: '80%' - }); + var parser = function(rowIdx, colIdx, value, isHead) { + if (String(value) == 'true') + value = '✔'; + else if (String(value) == 'false') + value = '-'; + else if (value == null) + value = ''; + else if (String(value) == 'Male') + value = '👨🏻'; + else if (String(value) == 'Female') + value = '👩🏻'; + return (value); + } + + $('#table').createTable(data, { + //showTableHeader: false, + showTableRowNumber: true, + //rowNumberInitialValue: 101, + colsSameWidth: false, + width: '80%', + + parser: parser, + //parseHeader: true, + //parseRowNumber: true, + //parserCols: ['registered'], + + showTitle: true, + titleText: 'My awesome table', + //titleAlign: 'left', + + showFooter: true, + //footerText: 'My awesome footer', + footerAlign: 'right', + + //debug: true + }); ``` From 4749b38f140765d4e4944bb8b49c9c2dc5d65b42 Mon Sep 17 00:00:00 2001 From: Phil Mottin Date: Wed, 28 Jul 2021 13:35:07 -0300 Subject: [PATCH 4/5] Small Fixes - Close tr tag - isHead flag inside parser function was wrong --- JSON-to-Table-1.0.1.js | 8 ++++---- JSON-to-Table.min.1.0.1.js | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/JSON-to-Table-1.0.1.js b/JSON-to-Table-1.0.1.js index bf6e946..33a026b 100644 --- a/JSON-to-Table-1.0.1.js +++ b/JSON-to-Table-1.0.1.js @@ -99,7 +99,7 @@ $.each(data[0], function (key, value) { if ($.fn.createTable.isFunction(settings.parser)) { settings.parserCols = Array.isArray(settings.parserCols) ? settings.parserCols : []; - key = settings.parseHeader ? settings.parser(0, iColHeader, key, thead) : key; + key = settings.parseHeader ? settings.parser(0, iColHeader, key, true) : key; } iColHeader++; table += '' + $.fn.humanize(key) + ''; @@ -111,7 +111,7 @@ for (var i = 0; i < data.length; i++) { if ($.fn.createTable.isFunction(settings.parser)) { settings.parserCols = Array.isArray(settings.parserCols) ? settings.parserCols : []; - value = settings.parseRowNumber ? settings.parser(i+1, 0, settings.rowNumberInitialValue + i, thead) : settings.rowNumberInitialValue + i; + value = settings.parseRowNumber ? settings.parser(i+1, 0, settings.rowNumberInitialValue + i, false) : settings.rowNumberInitialValue + i; } table += settings.showTableRowNumber ? (''+(value)+'') : ''; @@ -119,12 +119,12 @@ $.each(data[i], function (key, value) { if ($.fn.createTable.isFunction(settings.parser)) { settings.parserCols = Array.isArray(settings.parserCols) ? settings.parserCols : []; - value = (settings.parserCols.includes(key) || settings.parserCols.length == 0) ? settings.parser(i+1, iCol, value, thead) : value; + value = (settings.parserCols.includes(key) || settings.parserCols.length == 0) ? settings.parser(i+1, iCol, value, false) : value; } iCol++; table += '' + value + ''; }); - if (thead === false) table += ''; + table += ''; } table += ''; table += ''; diff --git a/JSON-to-Table.min.1.0.1.js b/JSON-to-Table.min.1.0.1.js index 7482916..2c24627 100644 --- a/JSON-to-Table.min.1.0.1.js +++ b/JSON-to-Table.min.1.0.1.js @@ -1 +1 @@ -!function(t){t.fn.createTable=function(e,r){var o,a=t.extend({},t.fn.createTable.defaults,r);if(void 0!==this[0].className&&this[0].className.length>0){var i=this[0].className.split(" ");o="."+i.join(".")+" "}else void 0!==this[0].id&&(o="#"+this[0].id+" ");var l=t.fn.createTable.parseTableData(e,a.showTableHeader,a);return this.html(l),t(o+".json-to-table").css({borderCollapse:"collapse",width:a.width,border:a.borderWidth+" "+a.borderStyle+" "+a.borderColor,fontFamily:a.fontFamily}),t(o+".json-to-table caption#title").css({captionSide:"top",textAlign:a.titleAlign}),t(o+".json-to-table caption#footer").css({captionSide:"bottom",textAlign:a.footerAlign,fontSize:"12px"}),t(o+".jsl").css({minWidth:"18px",width:"18px",padding:"0"}),a.colsSameWidh&&t(o+".json-to-table thead th:not(:first-child), .json-to-table tbody td:not(:first-child)").css({width:100/Object.keys(e[0]).length+"%"}),t(o+".json-to-table thead th, .json-to-table tbody td").css({border:a.borderWidth+" "+a.borderStyle+" "+a.borderColor}),t(o+".json-to-table thead th").css({backgroundColor:a.thBg,color:a.thColor,height:a.thHeight,fontFamily:a.thFontFamily,fontSize:a.thFontSize,textTransform:a.thTextTransform}),void t(o+".json-to-table tbody td").css({backgroundColor:a.trBg,color:a.trColor,paddingLeft:a.tdPaddingLeft,paddingRight:a.tdPaddingRight,height:a.trHeight,fontSize:a.trFontSize,fontFamily:a.trFontFamily})},t.fn.createTable.isFunction=function(t){return t&&"[object Function]"==={}.toString.call(t)},t.fn.createTable.parseTableData=function(e,r,o){o.debug&&(o.parser=function(t,e,r,o){return t+":"+e},o.parseHeader=!0,o.parseRowNumber=!0,o.showTitle=!0,o.showFooter=!0);var a="";a='',title=o.titleText?o.titleText:e.length+" records",footer=o.footerText?o.footerText:e.length+" records",o.showTitle&&(a+='"),o.showFooter&&(a+='");var i=1;!0===r&&(a+=o.showTableRowNumber?'':"",t.each(e[0],function(e,l){t.fn.createTable.isFunction(o.parser)&&(o.parserCols=Array.isArray(o.parserCols)?o.parserCols:[],e=o.parseHeader?o.parser(0,i,e,r):e),i++,a+=""}),a+=""),a+="";for(var l=0;l":"",iCol=1,t.each(e[l],function(e,i){t.fn.createTable.isFunction(o.parser)&&(o.parserCols=Array.isArray(o.parserCols)?o.parserCols:[],i=o.parserCols.includes(e)||0==o.parserCols.length?o.parser(l+1,iCol,i,r):i),iCol++,a+=""}),!1===r&&(a+="");return a+="",a+="
'+title+"'+footer+"
"+t.fn.humanize(e)+"
'+value+"
"+i+"
"},t.fn.humanize=function(t){var e=t.split("_");for(i=0;i0){var i=this[0].className.split(" ");o="."+i.join(".")+" "}else void 0!==this[0].id&&(o="#"+this[0].id+" ");var l=t.fn.createTable.parseTableData(e,a.showTableHeader,a);return this.html(l),t(o+".json-to-table").css({borderCollapse:"collapse",width:a.width,border:a.borderWidth+" "+a.borderStyle+" "+a.borderColor,fontFamily:a.fontFamily}),t(o+".json-to-table caption#title").css({captionSide:"top",textAlign:a.titleAlign}),t(o+".json-to-table caption#footer").css({captionSide:"bottom",textAlign:a.footerAlign,fontSize:"12px"}),t(o+".jsl").css({minWidth:"18px",width:"18px",padding:"0"}),a.colsSameWidh&&t(o+".json-to-table thead th:not(:first-child), .json-to-table tbody td:not(:first-child)").css({width:100/Object.keys(e[0]).length+"%"}),t(o+".json-to-table thead th, .json-to-table tbody td").css({border:a.borderWidth+" "+a.borderStyle+" "+a.borderColor}),t(o+".json-to-table thead th").css({backgroundColor:a.thBg,color:a.thColor,height:a.thHeight,fontFamily:a.thFontFamily,fontSize:a.thFontSize,textTransform:a.thTextTransform}),void t(o+".json-to-table tbody td").css({backgroundColor:a.trBg,color:a.trColor,paddingLeft:a.tdPaddingLeft,paddingRight:a.tdPaddingRight,height:a.trHeight,fontSize:a.trFontSize,fontFamily:a.trFontFamily})},t.fn.createTable.isFunction=function(t){return t&&"[object Function]"==={}.toString.call(t)},t.fn.createTable.parseTableData=function(e,r,o){o.debug&&(o.parser=function(t,e,r,o){return t+":"+e},o.parseHeader=!0,o.parseRowNumber=!0,o.showTitle=!0,o.showFooter=!0);var a="";a='',title=o.titleText?o.titleText:e.length+" records",footer=o.footerText?o.footerText:e.length+" records",o.showTitle&&(a+='"),o.showFooter&&(a+='");var i=1;!0===r&&(a+=o.showTableRowNumber?'':"",t.each(e[0],function(e,r){t.fn.createTable.isFunction(o.parser)&&(o.parserCols=Array.isArray(o.parserCols)?o.parserCols:[],e=o.parseHeader?o.parser(0,i,e,!0):e),i++,a+=""}),a+=""),a+="";for(var l=0;l":"",iCol=1,t.each(e[l],function(e,r){t.fn.createTable.isFunction(o.parser)&&(o.parserCols=Array.isArray(o.parserCols)?o.parserCols:[],r=o.parserCols.includes(e)||0==o.parserCols.length?o.parser(l+1,iCol,r,!1):r),iCol++,a+=""}),a+="";return a+="",a+="
'+title+"'+footer+"
"+t.fn.humanize(e)+"
'+value+"
"+r+"
"},t.fn.humanize=function(t){var e=t.split("_");for(i=0;i Date: Tue, 30 Nov 2021 13:20:53 -0300 Subject: [PATCH 5/5] Fix readme example fix error when showTableRowNumber is true and no parser is present. missing value. --- JSON-to-Table-1.0.1.js => JSON-to-Table-1.0.2.js | 2 ++ JSON-to-Table.min.1.0.1.js => JSON-to-Table.min.1.0.2.js | 2 +- README.md | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) rename JSON-to-Table-1.0.1.js => JSON-to-Table-1.0.2.js (97%) rename JSON-to-Table.min.1.0.1.js => JSON-to-Table.min.1.0.2.js (64%) diff --git a/JSON-to-Table-1.0.1.js b/JSON-to-Table-1.0.2.js similarity index 97% rename from JSON-to-Table-1.0.1.js rename to JSON-to-Table-1.0.2.js index 33a026b..818688a 100644 --- a/JSON-to-Table-1.0.1.js +++ b/JSON-to-Table-1.0.2.js @@ -112,6 +112,8 @@ if ($.fn.createTable.isFunction(settings.parser)) { settings.parserCols = Array.isArray(settings.parserCols) ? settings.parserCols : []; value = settings.parseRowNumber ? settings.parser(i+1, 0, settings.rowNumberInitialValue + i, false) : settings.rowNumberInitialValue + i; + } else { //fix error when showTableRowNumber is true and no parser is present. missing value. + value = settings.rowNumberInitialValue + i; } table += settings.showTableRowNumber ? (''+(value)+'') : ''; diff --git a/JSON-to-Table.min.1.0.1.js b/JSON-to-Table.min.1.0.2.js similarity index 64% rename from JSON-to-Table.min.1.0.1.js rename to JSON-to-Table.min.1.0.2.js index 2c24627..61967ff 100644 --- a/JSON-to-Table.min.1.0.1.js +++ b/JSON-to-Table.min.1.0.2.js @@ -1 +1 @@ -!function(t){t.fn.createTable=function(e,r){var o,a=t.extend({},t.fn.createTable.defaults,r);if(void 0!==this[0].className&&this[0].className.length>0){var i=this[0].className.split(" ");o="."+i.join(".")+" "}else void 0!==this[0].id&&(o="#"+this[0].id+" ");var l=t.fn.createTable.parseTableData(e,a.showTableHeader,a);return this.html(l),t(o+".json-to-table").css({borderCollapse:"collapse",width:a.width,border:a.borderWidth+" "+a.borderStyle+" "+a.borderColor,fontFamily:a.fontFamily}),t(o+".json-to-table caption#title").css({captionSide:"top",textAlign:a.titleAlign}),t(o+".json-to-table caption#footer").css({captionSide:"bottom",textAlign:a.footerAlign,fontSize:"12px"}),t(o+".jsl").css({minWidth:"18px",width:"18px",padding:"0"}),a.colsSameWidh&&t(o+".json-to-table thead th:not(:first-child), .json-to-table tbody td:not(:first-child)").css({width:100/Object.keys(e[0]).length+"%"}),t(o+".json-to-table thead th, .json-to-table tbody td").css({border:a.borderWidth+" "+a.borderStyle+" "+a.borderColor}),t(o+".json-to-table thead th").css({backgroundColor:a.thBg,color:a.thColor,height:a.thHeight,fontFamily:a.thFontFamily,fontSize:a.thFontSize,textTransform:a.thTextTransform}),void t(o+".json-to-table tbody td").css({backgroundColor:a.trBg,color:a.trColor,paddingLeft:a.tdPaddingLeft,paddingRight:a.tdPaddingRight,height:a.trHeight,fontSize:a.trFontSize,fontFamily:a.trFontFamily})},t.fn.createTable.isFunction=function(t){return t&&"[object Function]"==={}.toString.call(t)},t.fn.createTable.parseTableData=function(e,r,o){o.debug&&(o.parser=function(t,e,r,o){return t+":"+e},o.parseHeader=!0,o.parseRowNumber=!0,o.showTitle=!0,o.showFooter=!0);var a="";a='',title=o.titleText?o.titleText:e.length+" records",footer=o.footerText?o.footerText:e.length+" records",o.showTitle&&(a+='"),o.showFooter&&(a+='");var i=1;!0===r&&(a+=o.showTableRowNumber?'':"",t.each(e[0],function(e,r){t.fn.createTable.isFunction(o.parser)&&(o.parserCols=Array.isArray(o.parserCols)?o.parserCols:[],e=o.parseHeader?o.parser(0,i,e,!0):e),i++,a+=""}),a+=""),a+="";for(var l=0;l":"",iCol=1,t.each(e[l],function(e,r){t.fn.createTable.isFunction(o.parser)&&(o.parserCols=Array.isArray(o.parserCols)?o.parserCols:[],r=o.parserCols.includes(e)||0==o.parserCols.length?o.parser(l+1,iCol,r,!1):r),iCol++,a+=""}),a+="";return a+="",a+="
'+title+"'+footer+"
"+t.fn.humanize(e)+"
'+value+"
"+r+"
"},t.fn.humanize=function(t){var e=t.split("_");for(i=0;i0){var i=this[0].className.split(" ");o="."+i.join(".")+" "}else void 0!==this[0].id&&(o="#"+this[0].id+" ");var l=t.fn.createTable.parseTableData(e,a.showTableHeader,a);return this.html(l),t(o+".json-to-table").css({borderCollapse:"collapse",width:a.width,border:a.borderWidth+" "+a.borderStyle+" "+a.borderColor,fontFamily:a.fontFamily}),t(o+".json-to-table caption#title").css({captionSide:"top",textAlign:a.titleAlign}),t(o+".json-to-table caption#footer").css({captionSide:"bottom",textAlign:a.footerAlign,fontSize:"12px"}),t(o+".jsl").css({minWidth:"18px",width:"18px",padding:"0"}),a.colsSameWidh&&t(o+".json-to-table thead th:not(:first-child), .json-to-table tbody td:not(:first-child)").css({width:100/Object.keys(e[0]).length+"%"}),t(o+".json-to-table thead th, .json-to-table tbody td").css({border:a.borderWidth+" "+a.borderStyle+" "+a.borderColor}),t(o+".json-to-table thead th").css({backgroundColor:a.thBg,color:a.thColor,height:a.thHeight,fontFamily:a.thFontFamily,fontSize:a.thFontSize,textTransform:a.thTextTransform}),void t(o+".json-to-table tbody td").css({backgroundColor:a.trBg,color:a.trColor,paddingLeft:a.tdPaddingLeft,paddingRight:a.tdPaddingRight,height:a.trHeight,fontSize:a.trFontSize,fontFamily:a.trFontFamily})},t.fn.createTable.isFunction=function(t){return t&&"[object Function]"==={}.toString.call(t)},t.fn.createTable.parseTableData=function(e,r,o){o.debug&&(o.parser=function(t,e,r,o){return t+":"+e},o.parseHeader=!0,o.parseRowNumber=!0,o.showTitle=!0,o.showFooter=!0);var a="";a='',title=o.titleText?o.titleText:e.length+" records",footer=o.footerText?o.footerText:e.length+" records",o.showTitle&&(a+='"),o.showFooter&&(a+='");var i=1;!0===r&&(a+=o.showTableRowNumber?'':"",t.each(e[0],function(e,r){t.fn.createTable.isFunction(o.parser)&&(o.parserCols=Array.isArray(o.parserCols)?o.parserCols:[],e=o.parseHeader?o.parser(0,i,e,!0):e),i++,a+=""}),a+=""),a+="";for(var l=0;l":"",iCol=1,t.each(e[l],function(e,r){t.fn.createTable.isFunction(o.parser)&&(o.parserCols=Array.isArray(o.parserCols)?o.parserCols:[],r=o.parserCols.includes(e)||0==o.parserCols.length?o.parser(l+1,iCol,r,!1):r),iCol++,a+=""}),a+="";return a+="",a+="
'+title+"'+footer+"
"+t.fn.humanize(e)+"
'+value+"
"+r+"
"},t.fn.humanize=function(t){var e=t.split("_");for(i=0;i