1/** 2 * stacktable.js 3 * Author & copyright (c) 2012: John Polacek 4 * CardTable by: Justin McNally (2015) 5 * Dual MIT & GPL license 6 * 7 * Page: http://johnpolacek.github.com/stacktable.js 8 * Repo: https://github.com/johnpolacek/stacktable.js/ 9 * 10 * jQuery plugin for stacking tables on small screens 11 * 12 */ 13;(function($) { 14 $.fn.cardtable = function(options) { 15 var $tables = this, 16 defaults = {id:'stacktable small-only',hideOriginal:true,headIndex:0}, 17 settings = $.extend({}, defaults, options); 18 19 // checking the "headIndex" option presence... or defaults it to 0 20 if(options && options.headIndex) 21 headIndex = options.headIndex; 22 else 23 headIndex = 0; 24 25 return $tables.each(function() { 26 $table = $(this); 27 if ($table.hasClass('stacktable')) { 28 return; 29 } 30 var table_css = $(this).prop('class'); 31 var $stacktable = $('<div></div>'); 32 if (typeof settings.myClass !== 'undefined') $stacktable.addClass(settings.myClass); 33 var markup = ''; 34 35 36 $table.addClass('stacktable large-only'); 37 $caption = $table.find("caption").clone(); 38 $topRow = $table.find('tr').eq(0); 39 40 // using rowIndex and cellIndex in order to reduce ambiguity 41 $table.find('tbody tr').each(function(rowIndex,value) { 42 43 // declaring headMarkup and bodyMarkup, to be used for separately head and body of single records 44 headMarkup = ''; 45 bodyMarkup = ''; 46 tr_class = $(this).prop('class'); 47 // for the first row, "headIndex" cell is the head of the table 48 // for the other rows, put the "headIndex" cell as the head for that row 49 // then iterate through the key/values 50 $(this).find('td,th').each(function(cellIndex,value) { 51 if ($(this).html() !== ''){ 52 bodyMarkup += '<tr class="' + tr_class +'">'; 53 if ($topRow.find('td,th').eq(cellIndex).html()){ 54 bodyMarkup += '<td class="st-key">'+$table.find('thead th').eq(cellIndex).html()+'</td>'; 55 } else { 56 bodyMarkup += '<td class="st-key"></td>'; 57 } 58 bodyMarkup += '<td class="st-val '+$(this).prop('class') +'">'+$(this).html()+'</td>'; 59 bodyMarkup += '</tr>'; 60 } 61 }); 62 63 markup += '<table class=" '+ table_css +' '+settings.id+'"><tbody>' + headMarkup + bodyMarkup + '</tbody></table>'; 64 }); 65 66 $table.find('tfoot tr td').each(function(rowIndex,value) { 67 if ($.trim($(value).text()) !== '') { 68 markup += '<table class="'+ table_css + ' ' +settings.id+'"><tbody><tr><td>' + $(value).html() + '</td></tr></tbody></table>'; 69 } 70 }); 71 72 $stacktable.prepend($caption); 73 $stacktable.append($(markup)); 74 $table.before($stacktable); 75 if (!settings.hideOriginal) $table.show(); 76 }); 77 }; 78 79 $.fn.stacktable = function(options) { 80 var $tables = this, 81 defaults = {id:'stacktable small-only',hideOriginal:true,headIndex:0}, 82 settings = $.extend({}, defaults, options); 83 84 // checking the "headIndex" option presence... or defaults it to 0 85 if(options && options.headIndex) 86 headIndex = options.headIndex; 87 else 88 headIndex = 0; 89 90 return $tables.each(function() { 91 var table_css = $(this).prop('class'); 92 var $stacktable = $('<table class="'+ table_css +' '+settings.id+'"><tbody></tbody></table>'); 93 if (typeof settings.myClass !== 'undefined') $stacktable.addClass(settings.myClass); 94 var markup = ''; 95 96 $table = $(this); 97 $table.addClass('stacktable large-only'); 98 $caption = $table.find("caption").clone(); 99 $topRow = $table.find('tr').eq(0); 100 101 // using rowIndex and cellIndex in order to reduce ambiguity 102 $table.find('tr').each(function(rowIndex,value) { 103 104 // declaring headMarkup and bodyMarkup, to be used for separately head and body of single records 105 headMarkup = ''; 106 bodyMarkup = ''; 107 tr_class = $(this).prop('class'); 108 // for the first row, "headIndex" cell is the head of the table 109 if (rowIndex === 0) { 110 // the main heading goes into the markup variable 111 markup += '<tr class=" '+tr_class +' "><th class="st-head-row st-head-row-main" colspan="2">
111'+$(this).find('th,td').eq(headIndex).html()+'</th></tr>'; 112 } 113 else { 114 // for the other rows, put the "headIndex" cell as the head for that row 115 // then iterate through the key/values 116 $(this).find('td,th').each(function(cellIndex,value) { 117 if (cellIndex === headIndex) { 118 headMarkup = '<tr class="'+ tr_class+'"><th class="st-head-row" colspan="2">'+$(this).html()+'</th></tr>'; 119 } else { 120 if ($(this).html() !== ''){ 121 bodyMarkup += '<tr class="' + tr_class +'">'; 122 if ($topRow.find('td,th').eq(cellIndex).html()){ 123 bodyMarkup += '<td class="st-key">'+$topRow.find('td,th').eq(cellIndex).html()+'</td>'; 124 } else { 125 bodyMarkup += '<td class="st-key"></td>'; 126 } 127 bodyMarkup += '<td class="st-val '+$(this).prop('class') +'">'+$(this).html()+'</td>'; 128 bodyMarkup += '</tr>'; 129 } 130 } 131 }); 132 133 markup += headMarkup + bodyMarkup; 134 } 135 }); 136 137 $stacktable.prepend($caption); 138 $stacktable.append($(markup)); 139 $table.before($stacktable); 140 if (!settings.hideOriginal) $table.show(); 141 }); 142 }; 143 144 $.fn.stackcolumns = function(options) { 145 var $tables = this, 146 defaults = {id:'stacktable small-only',hideOriginal:true}, 147 settings = $.extend({}, defaults, options); 148 149 return $tables.each(function() { 150 $table = $(this); 151 var num_cols = $table.find('tr').eq(0).find('td,th').length; //first table <tr> must not contain colspans, or add sum(colspan-1) here. 152 if(num_cols<3) //stackcolumns has no effect on tables with less than 3 columns 153 return; 154 155 var $stackcolumns = $('<table class="'+settings.id+'"></table>'); 156 if (typeof settings.myClass !== 'undefined') $stackcolumns.addClass(settings.myClass); 157 $table.addClass('stacktable large-only'); 158 var tb = $('<tbody></tbody>'); 159 var col_i = 1; //col index starts at 0 -> start copy at second column. 160 161 while (col_i < num_cols) { 162 $table.find('tr').each(function(index,value) { 163 var tem = $('<tr></tr>'); // todo opt. copy styles of $this; todo check if parent is thead or tfoot to handle accordingly 164 if(index === 0) tem.addClass("st-head-row st-head-row-main"); 165 first = $(this).find('td,th').eq(0).clone().addClass("st-key"); 166 var target = col_i; 167 // if colspan apply, recompute target for second cell. 168 if ($(this).find("*[colspan]").length) { 169 var i =0; 170 $(this).find('td,th').each(function(index,value) { 171 var cs = $(this).attr("colspan"); 172 if (cs) { 173 cs = parseInt(cs, 10); 174 target -= cs-1; 175 if ((i+cs) > (col_i)) //out of current bounds 176 target += i + cs - col_i -1; 177 i += cs; 178 } 179 else 180 i++; 181 182 if (i > col_i) 183 return false; //target is set; break. 184 }); 185 } 186 second = $(this).find('td,th').eq(target).clone().addClass("st-val").removeAttr("colspan"); 187 tem.append(first, second); 188 tb.append(tem); 189 }); 190 ++col_i; 191 } 192 193 $stackcolumns.append($(tb)); 194 $table.before($stackcolumns); 195 if (!(settings.hideOriginal)) { 196 $table.show(); 197 } 198 }); 199 }; 200 201}(jQuery));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.