mirror of
https://github.com/Mottie/tablesorter.git
synced 2024-11-15 23:54:22 +00:00
Group: add optimizations from pull #830
This commit is contained in:
parent
4fc923ec78
commit
66aede3654
47
dist/js/widgets/widget-grouping.min.js
vendored
47
dist/js/widgets/widget-grouping.min.js
vendored
@ -5,32 +5,55 @@
|
||||
*/
|
||||
/*jshint browser:true, jquery:true, unused:false */
|
||||
/*global jQuery: false */
|
||||
!function(a){"use strict";var b=a.tablesorter;b.grouping={types:{number:function(a,c,d,e,f){var g,h;return e>1&&""!==d?c.hasClass(b.css.sortAsc)?(g=Math.floor(parseFloat(d)/e)*e,g>parseFloat(f||0)?g:parseFloat(f||0)):(g=Math.ceil(parseFloat(d)/e)*e,g<parseFloat(f||e)-g?parseFloat(f||e)-g:g):(h=(d+"").match(/\d+/g),h&&h.length>=e?h[e-1]:d||"")},separator:function(b,c,d,e){var f=(d+"").split(b.widgetOptions.group_separator);return a.trim(f&&e>0&&f.length>=e?f[(e||1)-1]:"")},word:function(a,b,c,d){var e=(c+" ").match(/\w+/g);return e&&e.length>=d?e[d-1]:c||""},letter:function(a,b,c,d){return c?(c+" ").substring(0,d):""},date:function(a,c,d,e,f){var g,h,i=a.widgetOptions,j=new Date(d||"");
|
||||
!function(a){"use strict";var b=a.tablesorter,c=b.grouping={types:{number:function(a,c,d,e){var f,g=c.hasClass(b.css.sortAsc);
|
||||
// show range
|
||||
return e>1&&""!==d?(f=g?Math.floor(parseFloat(d)/e)*e:Math.ceil(parseFloat(d)/e)*e,f+=" - "+(f+(e-1)*(g?1:-1))):f=parseFloat(d)||d,f},separator:function(b,c,d,e){var f=(d+"").split(b.widgetOptions.group_separator);
|
||||
// return $.trim(word && num > 0 && word.length >= num ? word[(num || 1) - 1] : '');
|
||||
return a.trim(f[e-1]||"")},text:function(a,b,c){return c},word:function(a,b,c,d){var e=(c+" ").match(/\w+/g)||[];
|
||||
// return word && word.length >= num ? word[num - 1] : txt || '';
|
||||
return e[d-1]||""},letter:function(a,b,c,d){return c?(c+" ").substring(0,d):""},date:function(a,b,d,e,f){var g,h,i=a.widgetOptions,j=new Date(d||"");
|
||||
// check for valid date
|
||||
// check for valid date
|
||||
return j instanceof Date&&isFinite(j)?(g=j.getFullYear(),h=b.grouping.findMonth(i,j.getMonth()),"year"===e?g:"month"===e?h:"monthyear"===e?h+" "+g:"day"===e?h+" "+j.getDate():"week"===e?b.grouping.findWeek(i,j.getDay()):"time"===e?b.grouping.findTime(i,j):i.group_dateString(j,a,c)):i.group_dateInvalid}},
|
||||
return j instanceof Date&&isFinite(j)?(g=j.getFullYear(),h=c.findMonth(i,j.getMonth()),"year"===e?g:"month"===e?h:"monthyear"===e?h+" "+g:"day"===e?h+" "+j.getDate():"week"===e?c.findWeek(i,j.getDay()):"time"===e?c.findTime(i,j):i.group_dateString(j,a,b)):i.group_dateInvalid}},
|
||||
// group date type functions to allow using this widget with Globalize
|
||||
findMonth:function(a,b){
|
||||
// CLDR returns an object { 1: "Jan", 2: "Feb", 3: "Mar", ..., 12: "Dec" }
|
||||
return a.group_months[b+(""===(a.group_months[0]||"")?1:0)]},findWeek:function(b,c){if(a.isArray(b.group_week))return b.group_week[c];if(!a.isEmptyObject(b.group_week)){
|
||||
// CLDR returns { sun: "Sun", mon: "Mon", tue: "Tue", wed: "Wed", thu: "Thu", ... }
|
||||
var d=["sun","mon","tue","wed","thu","fri","sat"];return b.group_week[d[c]]}},findTime:function(a,b){var c,d=b.getHours(),e=d>=12?1:0,
|
||||
var d=["sun","mon","tue","wed","thu","fri","sat"];return b.group_week[d[c]]}},findTime:function(a,b){var c,
|
||||
// CLDR returns { am: "AM", pm: "PM", ... }
|
||||
f=a.group_time.am&&a.group_time.pm,g=("00"+(a.group_time24Hour&&d>12?d-12:a.group_time24Hour&&0===d?d+12:d)).slice(-2),h=("00"+b.getMinutes()).slice(-2);return c=a.group_time[f?["am","pm"][e]:e],g+":"+h+(a.group_time24Hour?"":" "+(c||""))},update:function(c,d,e){if(!a.isEmptyObject(d.cache)){var f,g,h,i,j,k,l,m,n,o,p=b.hasWidget(c,"pager"),q="undefined"!=typeof d.sortList[0],r="",s=0,t=!1,u=a.isArray(e.group_forceColumn)&&"undefined"!=typeof e.group_forceColumn[0]?e.group_enforceSort&&!q?-1:e.group_forceColumn[0]:q?d.sortList[0][0]:-1;if(d.$table.find("tr.group-hidden").removeClass("group-hidden").end().find("tr.group-header").remove(),e.group_collapsible&&
|
||||
d=a.group_time.am&&a.group_time.pm,e=b.getHours(),f=e>=12?1:0,g=a.group_time24Hour&&e>12?e-12:a.group_time24Hour&&0===e?e+12:e,h=("00"+g).slice(-2),i=("00"+b.getMinutes()).slice(-2);return c=a.group_time[d?["am","pm"][f]:f],h+":"+i+(a.group_time24Hour?"":" "+(c||""))},update:function(b,d,e){if(!a.isEmptyObject(d.cache)){var f="undefined"!=typeof d.sortList[0],g={},h=a.isArray(e.group_forceColumn)&&"undefined"!=typeof e.group_forceColumn[0]?e.group_enforceSort&&!f?-1:e.group_forceColumn[0]:f?d.sortList[0][0]:-1;d.$table.find("tr.group-hidden").removeClass("group-hidden").end().find("tr.group-header").remove(),e.group_collapsible&&
|
||||
// clear pager saved spacer height (in case the rows are collapsed)
|
||||
d.$table.data("pagerSavedHeight",0),u>=0&&u<d.columns&&!d.$headerIndexed[u].hasClass("group-false")){for(e.group_currentGroup="",// save current groups
|
||||
e.group_currentGroups={},j=(d.$headerIndexed[u].attr("class")||"").match(/(group-\w+(-\w+)?)/g),k=j?j[0].split("-"):["group","letter",1],e.group_collapsible&&e.group_saveGroups&&b.storage&&(e.group_currentGroups=b.storage(c,"tablesorter-groups")||{},n="dir"+d.sortList[0][1],m=e.group_currentGroup=""+d.sortList[0][0]+n+k.join(""),e.group_currentGroups[m]?t=!0:e.group_currentGroups[m]=[]),g=0;g<d.$tbodies.length;g++)for(l=d.cache[g].normalized,r="",// clear grouping across tbodies
|
||||
f=p?d.pager.startRow-1:0,o=p?d.pager.endRow:l.length;o>f;f++)i=l[f][d.columns].$row,i.is(":visible")&&b.grouping.types[k[1]]&&(h=l[f]?b.grouping.types[k[1]](d,d.$headerIndexed[u],l[f][u],/date/.test(j)?k[2]:parseInt(k[2]||1,10)||1,r):h,r!==h&&(r=h,"number"===k[1]&&k[2]>1&&""!==h&&(h+=" - "+(parseInt(h,10)+(parseInt(k[2],10)-1)*(d.$headerIndexed[u].hasClass(b.css.sortAsc)?1:-1))),a.isFunction(e.group_formatter)&&(h=e.group_formatter((h||"").toString(),u,c,d,e)||h),i.before('<tr class="group-header '+d.selectorRemove.slice(1)+'" unselectable="on" '+(d.tabIndex?'tabindex="0" ':"")+'data-group-index="'+s++ +'"><td colspan="'+d.columns+'">'+(e.group_collapsible?"<i/>":"")+'<span class="group-name">'+h+'</span><span class="group-count"></span></td></tr>'),e.group_saveGroups&&!t&&e.group_collapsed&&e.group_collapsible&&e.group_currentGroups[e.group_currentGroup].push(h)));d.$table.find("tr.group-header").bind("selectstart",!1).each(function(){var b,d,f,g=a(this),h=g.nextUntil("tr.group-header").filter(":visible");(e.group_count||a.isFunction(e.group_callback))&&(d=g.find(".group-count"),d.length&&(e.group_count&&d.html(e.group_count.replace(/\{num\}/g,h.length)),a.isFunction(e.group_callback)&&e.group_callback(g.find("td"),h,u,c))),e.group_saveGroups&&!a.isEmptyObject(e.group_currentGroups)&&e.group_currentGroups[e.group_currentGroup].length?(f=g.find(".group-name").text().toLowerCase()+g.attr("data-group-index"),b=a.inArray(f,e.group_currentGroups[e.group_currentGroup])>-1,g.toggleClass("collapsed",b),h.toggleClass("group-hidden",b)):e.group_collapsed&&e.group_collapsible&&(g.addClass("collapsed"),h.addClass("group-hidden"))}),d.$table.trigger(e.group_complete)}}},bindEvents:function(c,d,e){e.group_collapsible&&(e.group_currentGroups=[],
|
||||
d.$table.data("pagerSavedHeight",0),h>=0&&h<d.columns&&!d.$headerIndexed[h].hasClass("group-false")&&(e.group_collapsedGroup="",// save current groups
|
||||
e.group_collapsedGroups={},g.column=h,
|
||||
// group class finds 'group-{word/separator/letter/number/date/false}-{optional:#/year/month/day/week/time}'
|
||||
g.groupClass=(d.$headerIndexed[h].attr("class")||"").match(/(group-\w+(-\w+)?)/g),
|
||||
// grouping = [ 'group', '{word/separator/letter/number/date/false}', '{#/year/month/day/week/time}' ]
|
||||
g.grouping=g.groupClass?g.groupClass[0].split("-"):["group","letter",1],// default to letter 1
|
||||
// save current grouping
|
||||
g.savedGroup=c.saveCurrentGrouping(d,e,g),
|
||||
// find column groups
|
||||
c.findColumnGroups(d,e,g),c.processHeaders(d,e,g),d.$table.trigger(e.group_complete))}},processHeaders:function(b,c,d){var e,f,g,h,i,j,k=b.$table.find("tr.group-header"),l=k.length;for(k.bind("selectstart",!1),e=0;l>e;e++)j=k.eq(e),i=j.nextUntil("tr.group-header").filter(":visible"),(c.group_count||a.isFunction(c.group_callback))&&(g=j.find(".group-count"),g.length&&(c.group_count&&g.html(c.group_count.replace(/\{num\}/g,i.length)),a.isFunction(c.group_callback)&&c.group_callback(j.find("td"),i,d.column,b.table))),c.group_saveGroups&&!a.isEmptyObject(c.group_collapsedGroups)&&c.group_collapsedGroups[c.group_collapsedGroup].length?(h=j.find(".group-name").text().toLowerCase()+j.attr("data-group-index"),f=a.inArray(h,c.group_collapsedGroups[c.group_collapsedGroup])>-1,j.toggleClass("collapsed",f),i.toggleClass("group-hidden",f)):c.group_collapsed&&c.group_collapsible&&(j.addClass("collapsed"),i.addClass("group-hidden"))},groupHeaderHTML:function(a,b,c){return'<tr class="group-header '+a.selectorRemove.slice(1)+'" unselectable="on" '+(a.tabIndex?'tabindex="0" ':"")+'data-group-index="'+c.groupIndex++ +'"><td colspan="'+a.columns+'">'+(b.group_collapsible?"<i/>":"")+'<span class="group-name">'+c.currentGroup+'</span><span class="group-count"></span></td></tr>'},saveCurrentGrouping:function(a,c,d){
|
||||
// save current grouping
|
||||
var e,f,g=!1;
|
||||
// include direction when saving groups (reversed numbers shows different range values)
|
||||
// combine column, sort direction & grouping as save key
|
||||
return c.group_collapsible&&c.group_saveGroups&&b.storage&&(c.group_collapsedGroups=b.storage(a.table,"tablesorter-groups")||{},f="dir"+a.sortList[0][1],e=c.group_collapsedGroup=""+a.sortList[0][0]+f+d.grouping.join(""),c.group_collapsedGroups[e]?g=!0:c.group_collapsedGroups[e]=[]),g},findColumnGroups:function(a,d,e){var f,g,h,i,j=b.hasWidget(a.table,"pager");for(e.groupIndex=0,f=0;f<a.$tbodies.length;f++)for(g=a.cache[f].normalized,e.group="",// clear grouping across tbodies
|
||||
h=j?a.pager.startRow-1:0,i=j?a.pager.endRow:g.length;i>h;h++)e.rowData=g[h],e.$row=e.rowData[a.columns].$row,
|
||||
// fixes #438
|
||||
e.$row.is(":visible")&&c.types[e.grouping[1]]&&c.insertGroupHeader(a,d,e)},insertGroupHeader:function(b,d,e){var f=b.$headerIndexed[e.column],g=e.rowData[e.column],h=/date/.test(e.groupClass)?e.grouping[2]:parseInt(e.grouping[2]||1,10)||1;e.currentGroup=e.rowData?c.types[e.grouping[1]](b,f,g,h,e.group):e.currentGroup,e.group!==e.currentGroup&&(e.group=e.currentGroup,a.isFunction(d.group_formatter)&&(e.currentGroup=d.group_formatter((e.group||"").toString(),e.column,b.table,b,d)||e.group),e.$row.before(c.groupHeaderHTML(b,d,e)),d.group_saveGroups&&!e.savedGroup&&d.group_collapsed&&d.group_collapsible&&
|
||||
// all groups start collapsed
|
||||
d.group_collapsedGroups[d.group_collapsedGroup].push(e.currentGroup))},bindEvents:function(d,e,f){f.group_collapsible&&(f.group_collapsedGroups=[],
|
||||
// .on() requires jQuery 1.7+
|
||||
d.$table.on("click toggleGroup keyup","tr.group-header",function(f){
|
||||
e.$table.on("click toggleGroup keyup","tr.group-header",function(c){
|
||||
// pressing enter will toggle the group
|
||||
if(f.stopPropagation(),"keyup"!==f.type||13===f.which){var g,h,i,j=a(this),k=j.find(".group-name").text().toLowerCase()+j.attr("data-group-index");
|
||||
if(c.stopPropagation(),"keyup"!==c.type||13===c.which){var g,h,i,j=a(this),k=j.find(".group-name").text().toLowerCase()+j.attr("data-group-index");
|
||||
// use shift-click to toggle ALL groups
|
||||
!f.shiftKey||"click"!==f.type&&"keyup"!==f.type||j.siblings(".group-header").trigger("toggleGroup"),j.toggleClass("collapsed"),
|
||||
!c.shiftKey||"click"!==c.type&&"keyup"!==c.type||j.siblings(".group-header").trigger("toggleGroup"),j.toggleClass("collapsed"),
|
||||
// nextUntil requires jQuery 1.4+
|
||||
j.nextUntil("tr.group-header").toggleClass("group-hidden",j.hasClass("collapsed")),
|
||||
// save collapsed groups
|
||||
e.group_saveGroups&&b.storage&&(h=d.$table.find(".group-header"),g=j.hasClass("collapsed"),e.group_currentGroups[e.group_currentGroup]||(e.group_currentGroups[e.group_currentGroup]=[]),g&&e.group_currentGroup?e.group_currentGroups[e.group_currentGroup].push(k):e.group_currentGroup&&(i=a.inArray(k,e.group_currentGroups[e.group_currentGroup]),i>-1&&e.group_currentGroups[e.group_currentGroup].splice(i,1)),b.storage(c,"tablesorter-groups",e.group_currentGroups))}})),a(e.group_saveReset).on("click",function(){b.grouping.clearSavedGroups(c)}),d.$table.on("pagerChange.tsgrouping",function(){b.grouping.update(c,d,e)})},clearSavedGroups:function(a){a&&b.storage&&(b.storage(a,"tablesorter-groups",""),b.grouping.update(a,a.config,a.config.widgetOptions))}},b.addWidget({id:"group",priority:100,options:{group_collapsible:!0,// make the group header clickable and collapse the rows below it.
|
||||
f.group_saveGroups&&b.storage&&(h=e.$table.find(".group-header"),g=j.hasClass("collapsed"),f.group_collapsedGroups[f.group_collapsedGroup]||(f.group_collapsedGroups[f.group_collapsedGroup]=[]),g&&f.group_collapsedGroup?f.group_collapsedGroups[f.group_collapsedGroup].push(k):f.group_collapsedGroup&&(i=a.inArray(k,f.group_collapsedGroups[f.group_collapsedGroup]),i>-1&&f.group_collapsedGroups[f.group_collapsedGroup].splice(i,1)),b.storage(d,"tablesorter-groups",f.group_collapsedGroups))}})),a(f.group_saveReset).on("click",function(){c.clearSavedGroups(d)}),e.$table.on("pagerChange.tsgrouping",function(){c.update(d,e,f)})},clearSavedGroups:function(a){a&&b.storage&&(b.storage(a,"tablesorter-groups",""),c.update(a,a.config,a.config.widgetOptions))}};b.addWidget({id:"group",priority:100,options:{group_collapsible:!0,// make the group header clickable and collapse the rows below it.
|
||||
group_collapsed:!1,// start with all groups collapsed
|
||||
group_saveGroups:!0,// remember collapsed groups
|
||||
group_saveReset:null,// element to clear saved collapsed groups
|
||||
@ -53,4 +76,4 @@ group_dateInvalid:"Invalid Date",
|
||||
// this function is used when 'group-date' is set to create the date string
|
||||
// you can just return date, date.toLocaleString(), date.toLocaleDateString() or d.toLocaleTimeString()
|
||||
// reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date#Conversion_getter
|
||||
group_dateString:function(a){return a.toLocaleString()}},init:function(a,c,d,e){b.grouping.bindEvents(a,d,e)},format:function(a,c,d){b.grouping.update(a,c,d)},remove:function(a,b,c){b.$table.off("click","tr.group-header").off("pagerChange.tsgrouping").find(".group-hidden").removeClass("group-hidden").end().find("tr.group-header").remove()}})}(jQuery);
|
||||
group_dateString:function(a){return a.toLocaleString()}},init:function(a,b,d,e){c.bindEvents(a,d,e)},format:function(a,b,d){c.update(a,b,d)},remove:function(a,b,c){b.$table.off("click","tr.group-header").off("pagerChange.tsgrouping").find(".group-hidden").removeClass("group-hidden").end().find("tr.group-header").remove()}})}(jQuery);
|
@ -99,7 +99,7 @@ span.alert { padding: 1px 3px; }
|
||||
table th.nobold { font-weight: normal; }
|
||||
table th a { text-decoration: underline; color: #000; }
|
||||
#group .ui-slider,#align .ui-slider { width: 100px; height: 3px; font-size: 0.8em; display: inline-block; margin-left: 10px; }
|
||||
#group .demo-label,#align .demo-label { display: inline-block; min-width: 120px; }
|
||||
#group .demo-label,#align .demo-label { display: inline-block; min-width: 125px; }
|
||||
#align .demo-label { display: inline-block; min-width: 150px; }
|
||||
@media all and (max-width: 700px) {
|
||||
table.compatibility, div.box { float: none; width: 100%; margin: 0; }
|
||||
|
@ -67,6 +67,7 @@ tr.group-header.collapsed td i {
|
||||
|
||||
<!-- grouping widget -->
|
||||
<script src="../js/parsers/parser-input-select.js"></script>
|
||||
<script src="../js/parsers/parser-date-weekday.js"></script>
|
||||
<script src="../js/widgets/widget-grouping.js"></script>
|
||||
|
||||
<script id="js">$(function(){
|
||||
@ -77,6 +78,7 @@ tr.group-header.collapsed td i {
|
||||
0: { sorter: "checkbox" },
|
||||
3: { sorter: "select" },
|
||||
6: { sorter: "inputs" }
|
||||
// 7: defaults to "shortDate", but set to "weekday-index" ("group-date-weekday") or "time" ("group-date-time")
|
||||
},
|
||||
widgets: [ "group", "columns", "filter", "zebra" ],
|
||||
widgetOptions: {
|
||||
@ -93,7 +95,7 @@ tr.group-header.collapsed td i {
|
||||
// checkbox parser text used for checked/unchecked values
|
||||
group_checkbox : [ 'checked', 'unchecked' ],
|
||||
|
||||
// change these default date names based on your language preferences
|
||||
// change these default date names based on your language preferences (see Globalize section for details)
|
||||
group_months : [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ],
|
||||
group_week : [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ],
|
||||
group_time : [ "AM", "PM" ],
|
||||
@ -115,6 +117,7 @@ tr.group-header.collapsed td i {
|
||||
// table = current table (DOM); c = table.config; wo = table.config.widgetOptions
|
||||
if (col === 7 && txt.indexOf("GMT") > 0) {
|
||||
// remove "GMT-0000 (Xxxx Standard Time)" from the end of the full date
|
||||
// this code is needed if group_dateString returns date.toString(); (not localeString)
|
||||
txt = txt.substring(0, txt.indexOf("GMT"));
|
||||
}
|
||||
// If there are empty cells, name the group "Empty"
|
||||
@ -160,6 +163,14 @@ tr.group-header.collapsed td i {
|
||||
<ul>
|
||||
<li>This widget will <strong>only work</strong> in tablesorter version 2.8+ and jQuery version 1.7+.</li>
|
||||
<li>Please do not use this widget in very large tables (it might be really slow) <del>or when your table includes multiple tbodies</del>.<br><br></li>
|
||||
|
||||
<li>In <span class="version">v2.24.1</span>
|
||||
<ul>
|
||||
<li>Added <code>"group-text"</code> group type to the Header Class Names. This class name will use the all of the text from the cell (this would essentially be the same as using "group-word-999").</li>
|
||||
<li>Updated this demo to use the new "weekday-index" parser when the date column is set to "group-date-weekday", and to use the "time" parser when the date column is set to "group-date-time". It is not the most efficient because changing parsers requires an "update".</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>In <span class="version">v2.24.0</span>
|
||||
<ul>
|
||||
<li>This widget now works properly when used with a pager that has the `removeRows` option set to `true`.</li>
|
||||
@ -172,32 +183,43 @@ tr.group-header.collapsed td i {
|
||||
<li>For information on how to load & use Globalize, see the Globalization section below.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>In <span class="version">v2.23.3</span>
|
||||
<ul>
|
||||
<li>Added <code>group_forceColumn</code> & <code>group_enforceSort</code> options for force column grouping.</li>
|
||||
<li>Updated method used to save collapsed groups, so any previously collapsed groups will be ignored after this update.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>In <span class="version">v2.22.0</span>, group headers are now keyboard accessible using <kbd>Tab</kbd>; and pressing <kbd>Enter</kbd> while the header has focus will toggle the group header, or use <kbd>Shift</kbd> + <kbd>Enter</kbd> to toggle all groups.</li>
|
||||
<li>In <span class="version">v2.21.0</span>
|
||||
<ul>
|
||||
<li>Added <code>group_checkbox</code> option to allow setting the parsed text from the "parser-input-select.js" checkbox parser.</li>
|
||||
<li>Fixed an issue with the filter widget overriding the "group-hidden" class name.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>In <span class="version">v2.15.6</span>, added <code>group_saveGroups</code> & <code>group_saveReset</code> options. More details are included in the "Options" section.</li>
|
||||
<li>In <span class="version">v2.14</span>, added <code>group_dateString</code> option. More details are included in the "Options" section.</li>
|
||||
<li>In <span class="version">v2.13</span>, added <code>group_separator</code> option & <code>group-separator-#</code> header class name. To see this in action, check out the <a href="example-parsers-file-type.html">file type parser demo</a>.</li>
|
||||
<li>In <span class="version">v2.12</span>, added <code>group_callback</code> & <code>group_complete</code> options. See options section below for details.</li>
|
||||
<li>In <span class="version">v2.11</span>:
|
||||
<ul>
|
||||
<li>The grouping widget now works across multiple tbodies.</li>
|
||||
<li>Added <code>group-false</code> header option which disables the grouping widget for a specific column.</li>
|
||||
<li>Added the <code>group_collapsed</code> option - get more details in the options block below.</li>
|
||||
<li>You can now toggle <strong>all</strong> group rows by holding down the <kbd>Shift</kbd> key while clicking on a group header.</li>
|
||||
<li>This widget now works properly with the pager addon (pager addon updated).</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="accordion start-closed">
|
||||
<h3 id="old-notes"><a href="#">Older Notes</a></h3>
|
||||
<div>
|
||||
<ul>
|
||||
<li>In <span class="version">v2.23.3</span>
|
||||
<ul>
|
||||
<li>Added <code>group_forceColumn</code> & <code>group_enforceSort</code> options for force column grouping.</li>
|
||||
<li>Updated method used to save collapsed groups, so any previously collapsed groups will be ignored after this update.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>In <span class="version">v2.22.0</span>, group headers are now keyboard accessible using <kbd>Tab</kbd>; and pressing <kbd>Enter</kbd> while the header has focus will toggle the group header, or use <kbd>Shift</kbd> + <kbd>Enter</kbd> to toggle all groups.</li>
|
||||
<li>In <span class="version">v2.21.0</span>
|
||||
<ul>
|
||||
<li>Added <code>group_checkbox</code> option to allow setting the parsed text from the "parser-input-select.js" checkbox parser.</li>
|
||||
<li>Fixed an issue with the filter widget overriding the "group-hidden" class name.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>In <span class="version">v2.15.6</span>, added <code>group_saveGroups</code> & <code>group_saveReset</code> options. More details are included in the "Options" section.</li>
|
||||
<li>In <span class="version">v2.14</span>, added <code>group_dateString</code> option. More details are included in the "Options" section.</li>
|
||||
<li>In <span class="version">v2.13</span>, added <code>group_separator</code> option & <code>group-separator-#</code> header class name. To see this in action, check out the <a href="example-parsers-file-type.html">file type parser demo</a>.</li>
|
||||
<li>In <span class="version">v2.12</span>, added <code>group_callback</code> & <code>group_complete</code> options. See options section below for details.</li>
|
||||
<li>In <span class="version">v2.11</span>:
|
||||
<ul>
|
||||
<li>The grouping widget now works across multiple tbodies.</li>
|
||||
<li>Added <code>group-false</code> header option which disables the grouping widget for a specific column.</li>
|
||||
<li>Added the <code>group_collapsed</code> option - get more details in the options block below.</li>
|
||||
<li>You can now toggle <strong>all</strong> group rows by holding down the <kbd>Shift</kbd> key while clicking on a group header.</li>
|
||||
<li>This widget now works properly with the pager addon (pager addon updated).</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul>
|
||||
<li>Clicking on any of the sortable header cells will cause the column below it to sort and add a group header.</li>
|
||||
</ul>
|
||||
</div>
|
||||
@ -488,7 +510,11 @@ group_dateString : function(date, config, $header ) {
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td rowspan="4">Text</td>
|
||||
<td rowspan="5">Text</td>
|
||||
<td><code>"group-text"</code></td>
|
||||
<td>Group the rows using all of the text from the column's parsed data.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>"group-word"</code></td>
|
||||
<td>Group the rows using the first word it finds in the column's parsed data (same as <code>"group-word-1"</code>).</td>
|
||||
</tr>
|
||||
@ -526,7 +552,7 @@ group_dateString : function(date, config, $header ) {
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td rowspan="6">Date</td>
|
||||
<td rowspan="7">Date</td>
|
||||
<td><code>"group-date"</code></td>
|
||||
<td>Group the rows by full date (this shows the current UTC time corrected for your time zone).</td>
|
||||
</tr>
|
||||
@ -557,7 +583,8 @@ group_dateString : function(date, config, $header ) {
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
<span class="remark">*</span> When sorting some columns, different group headers with the same group name may exist (try "group-date-week" and "group-date-time"). To make these columns sort specifically by the group you want, you'll need to modify the parser.
|
||||
<span class="remark">*</span> When sorting some columns, different group headers with the same group name may exist. To make these columns sort specifically by the group you want, you'll need to modify the parser.
|
||||
<p>Before v2.24.1, this demo only used the "shortDate" parser on the date column, so when "group-date-week" or "group-date-time" were set, group headers would repeat.</p>
|
||||
</div>
|
||||
|
||||
<h3><a href="#">Globalization</a></h3>
|
||||
@ -739,7 +766,7 @@ $(function() {
|
||||
|
||||
<span class="demo-label">Numeric column:</span> <div id="slider0"></div> <span class="numberclass"></span> (includes subtotals)<br>
|
||||
<span class="demo-label">Animals column:</span> <div id="slider1"></div> <span class="animalclass"></span><br>
|
||||
<span class="demo-label">Date column:</span> <div id="slider2"></div> <span class="dateclass"></span>
|
||||
<span class="demo-label">Date column:</span> <div id="slider2"></div> <span class="dateclass"></span><sup class="results">†</sup>
|
||||
<br><br>
|
||||
<button class="group_reset">Reset Saved Collapsed Groups</button>
|
||||
<div id="demo"><table id="groups">
|
||||
@ -784,6 +811,8 @@ $(function() {
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<small><span class="results">†</span> When "group-date-week" is set, the parser is changed to "weekday-index". And when "group-date-time" is set, the "time" parser is being used. All other date column settings use the "shortDate" parser.</small>
|
||||
<p></p>
|
||||
|
||||
<h1>Page Header</h1>
|
||||
<div>
|
||||
@ -815,7 +844,8 @@ $(function() {
|
||||
<script>
|
||||
/* DEMO ONLY CODE */
|
||||
$(function(){
|
||||
var startBlock = 10,
|
||||
var $groups = $('#groups'),
|
||||
startBlock = 10,
|
||||
startVal = 1,
|
||||
curGroup = 0,
|
||||
numcol = 2,
|
||||
@ -830,16 +860,16 @@ $(function() {
|
||||
step: 10,
|
||||
create: function(){
|
||||
$('.numberclass').html(' "group-number-' + startBlock + '"');
|
||||
$('#groups .tablesorter-header-inner:eq(' + numcol + ')').find('span').html(startBlock);
|
||||
$groups.find('.tablesorter-header-inner:eq(' + numcol + ')').find('span').html(startBlock);
|
||||
},
|
||||
slide: function( event, ui ) {
|
||||
$('#groups')[0].config.$headers.eq(numcol)
|
||||
$groups[0].config.$headers.eq(numcol)
|
||||
.attr('class', function(i,v){
|
||||
return v.replace(/group-number-\d+/, 'group-number-' + ui.value);
|
||||
})
|
||||
.trigger('sorton', [ [[numcol,0]] ]);
|
||||
$('.numberclass').html(' "group-number-' + ui.value + '"');
|
||||
$('#groups .tablesorter-header-inner:eq(' + numcol + ')').find('span').html(ui.value);
|
||||
$groups.find('.tablesorter-header-inner:eq(' + numcol + ')').find('span').html(ui.value);
|
||||
}
|
||||
});
|
||||
// animal (letter) column slider
|
||||
@ -850,16 +880,16 @@ $(function() {
|
||||
step: 1,
|
||||
create: function(){
|
||||
$('.animalclass').html(' "group-letter-' + startVal + '"');
|
||||
$('#groups .tablesorter-header-inner:eq(' + letcol + ')').find('span').html(startVal === 1 ? 'letter' : startVal + ' letters');
|
||||
$groups.find('.tablesorter-header-inner:eq(' + letcol + ')').find('span').html(startVal === 1 ? 'letter' : startVal + ' letters');
|
||||
},
|
||||
slide: function( event, ui ) {
|
||||
$('#groups')[0].config.$headers.eq(letcol)
|
||||
$groups[0].config.$headers.eq(letcol)
|
||||
.attr('class', function(i,v){
|
||||
return v.replace(/group-letter-\d+/, 'group-letter-' + ui.value);
|
||||
})
|
||||
.trigger('sorton', [ [[letcol,0]] ]);
|
||||
$('.animalclass').html(' "group-letter-' + ui.value + '"');
|
||||
$('#groups .tablesorter-header-inner:eq(' + letcol + ')').find('span').html(ui.value === 1 ? 'letter' : ui.value + ' letters');
|
||||
$groups.find('.tablesorter-header-inner:eq(' + letcol + ')').find('span').html(ui.value === 1 ? 'letter' : ui.value + ' letters');
|
||||
}
|
||||
});
|
||||
// date column slider
|
||||
@ -870,16 +900,25 @@ $(function() {
|
||||
step: 1,
|
||||
create: function(){
|
||||
$('.dateclass').html(' "group-date' + (curGroup > 0 ? '-' + dateGroups[curGroup] : '') + '"');
|
||||
$('#groups .tablesorter-header-inner:eq(' + datecol + ')').find('span').html(curGroup === 0 ? 'full' : dateGroups[curGroup]);
|
||||
$groups.find('.tablesorter-header-inner:eq(' + datecol + ')').find('span').html(curGroup === 0 ? 'full' : dateGroups[curGroup]);
|
||||
},
|
||||
slide: function( event, ui ) {
|
||||
$('#groups')[0].config.$headers.eq(datecol)
|
||||
var $h = $groups[0].config.$headers.eq(datecol)
|
||||
.attr('class', function(i,v){
|
||||
return v.replace(/group-date(-\w+)?/, 'group-date' + (ui.value > 0 ? '-' + dateGroups[ui.value] : ''));
|
||||
})
|
||||
.trigger('sorton', [ [[datecol,0]] ]);
|
||||
});
|
||||
$h.removeClass('sorter-weekday-index sorter-time');
|
||||
if ( dateGroups[ui.value] === 'week' ) {
|
||||
$h.addClass('sorter-weekday-index');
|
||||
$groups.trigger('update', [ [[datecol,0]] ]);
|
||||
} else if ( dateGroups[ui.value] === 'time' ) {
|
||||
$h.addClass('sorter-time');
|
||||
$groups.trigger('update', [ [[datecol,0]] ]);
|
||||
} else {
|
||||
$groups.trigger('update', [ [[datecol,0]] ]);
|
||||
}
|
||||
$('.dateclass').html(' "group-date' + (ui.value > 0 ? '-' + dateGroups[ui.value] : '') + '"');
|
||||
$('#groups .tablesorter-header-inner:eq(' + datecol + ')').find('span').html(ui.value === 0 ? 'full' : dateGroups[ui.value]);
|
||||
$groups.find('.tablesorter-header-inner:eq(' + datecol + ')').find('span').html(ui.value === 0 ? 'full' : dateGroups[ui.value]);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -6,52 +6,57 @@
|
||||
/*global jQuery: false */
|
||||
;(function($){
|
||||
'use strict';
|
||||
var ts = $.tablesorter;
|
||||
var ts = $.tablesorter,
|
||||
|
||||
ts.grouping = {
|
||||
tsg = ts.grouping = {
|
||||
|
||||
types : {
|
||||
number : function(c, $column, txt, num, group){
|
||||
var value, word;
|
||||
if (num > 1 && txt !== '') {
|
||||
if ($column.hasClass(ts.css.sortAsc)) {
|
||||
value = Math.floor(parseFloat(txt) / num) * num;
|
||||
return value > parseFloat(group || 0) ? value : parseFloat(group || 0);
|
||||
number : function(c, $column, txt, num) {
|
||||
var word, result,
|
||||
ascSort = $column.hasClass( ts.css.sortAsc );
|
||||
if ( num > 1 && txt !== '' ) {
|
||||
if ( ascSort ) {
|
||||
result = Math.floor( parseFloat( txt ) / num ) * num;
|
||||
} else {
|
||||
value = Math.ceil(parseFloat(txt) / num) * num;
|
||||
return value < parseFloat(group || num) - value ? parseFloat(group || num) - value : value;
|
||||
result = Math.ceil( parseFloat( txt ) / num ) * num;
|
||||
}
|
||||
// show range
|
||||
result += ' - ' + ( result + ( num - 1 ) * ( ascSort ? 1 : -1 ) );
|
||||
} else {
|
||||
word = (txt + '').match(/\d+/g);
|
||||
return word && word.length >= num ? word[num - 1] : txt || '';
|
||||
result = parseFloat( txt ) || txt;
|
||||
}
|
||||
return result;
|
||||
},
|
||||
separator : function(c, $column, txt, num){
|
||||
separator : function(c, $column, txt, num) {
|
||||
var word = (txt + '').split(c.widgetOptions.group_separator);
|
||||
return $.trim(word && num > 0 && word.length >= num ? word[(num || 1) - 1] : '');
|
||||
// return $.trim(word && num > 0 && word.length >= num ? word[(num || 1) - 1] : '');
|
||||
return $.trim( word[ num - 1 ] || '' );
|
||||
},
|
||||
word : function(c, $column, txt, num){
|
||||
var word = (txt + ' ').match(/\w+/g);
|
||||
return word && word.length >= num ? word[num - 1] : txt || '';
|
||||
text : function( c, $column, txt ) {
|
||||
return txt;
|
||||
},
|
||||
letter : function(c, $column, txt, num){
|
||||
word : function(c, $column, txt, num) {
|
||||
var word = (txt + ' ').match(/\w+/g) || [];
|
||||
// return word && word.length >= num ? word[num - 1] : txt || '';
|
||||
return word[ num - 1 ] || '';
|
||||
},
|
||||
letter : function(c, $column, txt, num) {
|
||||
return txt ? (txt + ' ').substring(0, num) : '';
|
||||
},
|
||||
date : function(c, $column, txt, part, group){
|
||||
date : function(c, $column, txt, part, group) {
|
||||
var year, month,
|
||||
wo = c.widgetOptions,
|
||||
time = new Date(txt || '');
|
||||
|
||||
// check for valid date
|
||||
if ( time instanceof Date && isFinite( time ) ) {
|
||||
year = time.getFullYear();
|
||||
month = ts.grouping.findMonth( wo, time.getMonth() );
|
||||
month = tsg.findMonth( wo, time.getMonth() );
|
||||
return part === 'year' ? year :
|
||||
part === 'month' ? month :
|
||||
part === 'monthyear' ? month + ' ' + year :
|
||||
part === 'day' ? month + ' ' + time.getDate() :
|
||||
part === 'week' ? ts.grouping.findWeek( wo, time.getDay() ) :
|
||||
part === 'time' ? ts.grouping.findTime( wo, time ) :
|
||||
part === 'week' ? tsg.findWeek( wo, time.getDay() ) :
|
||||
part === 'time' ? tsg.findTime( wo, time ) :
|
||||
wo.group_dateString( time, c, $column );
|
||||
} else {
|
||||
return wo.group_dateInvalid;
|
||||
@ -75,24 +80,22 @@
|
||||
},
|
||||
findTime : function( wo, time ) {
|
||||
var suffix,
|
||||
h = time.getHours(),
|
||||
period = h >= 12 ? 1 : 0,
|
||||
// CLDR returns { am: "AM", pm: "PM", ... }
|
||||
isObj = wo.group_time.am && wo.group_time.pm,
|
||||
hours = ( '00' + ( wo.group_time24Hour && h > 12 ? h - 12 : wo.group_time24Hour && h === 0 ? h + 12 : h ) ).slice(-2),
|
||||
h = time.getHours(),
|
||||
period = h >= 12 ? 1 : 0,
|
||||
p24 = wo.group_time24Hour && h > 12 ? h - 12 :
|
||||
wo.group_time24Hour && h === 0 ? h + 12 : h,
|
||||
hours = ( '00' + p24 ).slice(-2),
|
||||
min = ( '00' + time.getMinutes() ).slice(-2);
|
||||
suffix = wo.group_time[ isObj ? [ 'am', 'pm' ][ period ] : period ];
|
||||
return hours + ':' + min + ( wo.group_time24Hour ? '' : ' ' + ( suffix || '' ) );
|
||||
},
|
||||
|
||||
update : function(table, c, wo){
|
||||
update : function(table, c, wo) {
|
||||
if ($.isEmptyObject(c.cache)) { return; }
|
||||
var rowIndex, tbodyIndex, currentGroup, $row, groupClass, grouping, norm_rows, saveName, direction, end,
|
||||
hasPager = ts.hasWidget( table, 'pager' ),
|
||||
hasSort = typeof c.sortList[0] !== 'undefined',
|
||||
group = '',
|
||||
groupIndex = 0,
|
||||
savedGroup = false,
|
||||
var hasSort = typeof c.sortList[0] !== 'undefined',
|
||||
data = {},
|
||||
column = $.isArray( wo.group_forceColumn ) && typeof wo.group_forceColumn[0] !== 'undefined' ?
|
||||
( wo.group_enforceSort && !hasSort ? -1 : wo.group_forceColumn[0] ) :
|
||||
( hasSort ? c.sortList[0][0] : -1 );
|
||||
@ -104,99 +107,135 @@
|
||||
c.$table.data('pagerSavedHeight', 0);
|
||||
}
|
||||
if (column >= 0 && column < c.columns && !c.$headerIndexed[column].hasClass('group-false')) {
|
||||
wo.group_currentGroup = ''; // save current groups
|
||||
wo.group_currentGroups = {};
|
||||
wo.group_collapsedGroup = ''; // save current groups
|
||||
wo.group_collapsedGroups = {};
|
||||
|
||||
data.column = column;
|
||||
// group class finds 'group-{word/separator/letter/number/date/false}-{optional:#/year/month/day/week/time}'
|
||||
groupClass = (c.$headerIndexed[column].attr('class') || '').match(/(group-\w+(-\w+)?)/g);
|
||||
data.groupClass = (c.$headerIndexed[column].attr('class') || '').match(/(group-\w+(-\w+)?)/g);
|
||||
// grouping = [ 'group', '{word/separator/letter/number/date/false}', '{#/year/month/day/week/time}' ]
|
||||
grouping = groupClass ? groupClass[0].split('-') : [ 'group', 'letter', 1 ]; // default to letter 1
|
||||
data.grouping = data.groupClass ? data.groupClass[0].split('-') : [ 'group', 'letter', 1 ]; // default to letter 1
|
||||
|
||||
// save current grouping
|
||||
if (wo.group_collapsible && wo.group_saveGroups && ts.storage) {
|
||||
wo.group_currentGroups = ts.storage( table, 'tablesorter-groups' ) || {};
|
||||
// include direction when saving groups (reversed numbers shows different range values)
|
||||
direction = 'dir' + c.sortList[0][1];
|
||||
// combine column, sort direction & grouping as save key
|
||||
saveName = wo.group_currentGroup = '' + c.sortList[0][0] + direction + grouping.join('');
|
||||
if (!wo.group_currentGroups[saveName]) {
|
||||
wo.group_currentGroups[saveName] = [];
|
||||
} else {
|
||||
savedGroup = true;
|
||||
}
|
||||
}
|
||||
for (tbodyIndex = 0; tbodyIndex < c.$tbodies.length; tbodyIndex++) {
|
||||
norm_rows = c.cache[tbodyIndex].normalized;
|
||||
group = ''; // clear grouping across tbodies
|
||||
rowIndex = hasPager ? c.pager.startRow - 1 : 0;
|
||||
end = hasPager ? c.pager.endRow : norm_rows.length;
|
||||
for ( ; rowIndex < end; rowIndex++ ) {
|
||||
$row = norm_rows[ rowIndex ][ c.columns ].$row;
|
||||
if ( $row.is(':visible') ) {
|
||||
// fixes #438
|
||||
if (ts.grouping.types[grouping[1]]) {
|
||||
currentGroup = norm_rows[rowIndex] ?
|
||||
ts.grouping.types[grouping[1]]( c, c.$headerIndexed[column], norm_rows[rowIndex][column], /date/.test(groupClass) ?
|
||||
grouping[2] : parseInt(grouping[2] || 1, 10) || 1, group ) : currentGroup;
|
||||
if (group !== currentGroup) {
|
||||
group = currentGroup;
|
||||
// show range if number > 1
|
||||
if (grouping[1] === 'number' && grouping[2] > 1 && currentGroup !== '') {
|
||||
currentGroup += ' - ' + (parseInt(currentGroup, 10) +
|
||||
((parseInt(grouping[2], 10) - 1) * (c.$headerIndexed[column].hasClass(ts.css.sortAsc) ? 1 : -1)));
|
||||
}
|
||||
if ($.isFunction(wo.group_formatter)) {
|
||||
currentGroup = wo.group_formatter((currentGroup || '').toString(), column, table, c, wo) || currentGroup;
|
||||
}
|
||||
$row.before('<tr class="group-header ' + c.selectorRemove.slice(1) +
|
||||
'" unselectable="on" ' + ( c.tabIndex ? 'tabindex="0" ' : '' ) + 'data-group-index="' +
|
||||
( groupIndex++ ) + '"><td colspan="' + c.columns + '">' +
|
||||
( wo.group_collapsible ? '<i/>' : '' ) +
|
||||
'<span class="group-name">' + currentGroup + '</span>' +
|
||||
'<span class="group-count"></span></td></tr>');
|
||||
if (wo.group_saveGroups && !savedGroup && wo.group_collapsed && wo.group_collapsible) {
|
||||
// all groups start collapsed
|
||||
wo.group_currentGroups[wo.group_currentGroup].push(currentGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
c.$table.find('tr.group-header')
|
||||
.bind('selectstart', false)
|
||||
.each(function(){
|
||||
var isHidden, $label, name,
|
||||
$row = $(this),
|
||||
$rows = $row.nextUntil('tr.group-header').filter(':visible');
|
||||
if (wo.group_count || $.isFunction(wo.group_callback)) {
|
||||
$label = $row.find('.group-count');
|
||||
if ($label.length) {
|
||||
if (wo.group_count) {
|
||||
$label.html( wo.group_count.replace(/\{num\}/g, $rows.length) );
|
||||
}
|
||||
if ($.isFunction(wo.group_callback)) {
|
||||
wo.group_callback($row.find('td'), $rows, column, table);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (wo.group_saveGroups && !$.isEmptyObject(wo.group_currentGroups) && wo.group_currentGroups[wo.group_currentGroup].length) {
|
||||
name = $row.find('.group-name').text().toLowerCase() + $row.attr('data-group-index');
|
||||
isHidden = $.inArray( name, wo.group_currentGroups[wo.group_currentGroup] ) > -1;
|
||||
$row.toggleClass('collapsed', isHidden);
|
||||
$rows.toggleClass('group-hidden', isHidden);
|
||||
} else if (wo.group_collapsed && wo.group_collapsible) {
|
||||
$row.addClass('collapsed');
|
||||
$rows.addClass('group-hidden');
|
||||
}
|
||||
});
|
||||
data.savedGroup = tsg.saveCurrentGrouping( c, wo, data );
|
||||
|
||||
// find column groups
|
||||
tsg.findColumnGroups( c, wo, data );
|
||||
tsg.processHeaders( c, wo, data );
|
||||
|
||||
c.$table.trigger(wo.group_complete);
|
||||
}
|
||||
},
|
||||
|
||||
processHeaders : function( c, wo, data ) {
|
||||
var index, isHidden, $label, name, $rows, $row,
|
||||
$headers = c.$table.find( 'tr.group-header' ),
|
||||
len = $headers.length;
|
||||
|
||||
$headers.bind( 'selectstart', false );
|
||||
for ( index = 0; index < len; index++ ) {
|
||||
$row = $headers.eq( index );
|
||||
$rows = $row.nextUntil( 'tr.group-header' ).filter( ':visible' );
|
||||
|
||||
// add group count (only visible rows!)
|
||||
if ( wo.group_count || $.isFunction( wo.group_callback ) ) {
|
||||
$label = $row.find( '.group-count' );
|
||||
if ( $label.length ) {
|
||||
if ( wo.group_count ) {
|
||||
$label.html( wo.group_count.replace( /\{num\}/g, $rows.length ) );
|
||||
}
|
||||
if ( $.isFunction( wo.group_callback ) ) {
|
||||
wo.group_callback( $row.find( 'td' ), $rows, data.column, c.table );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// save collapsed groups
|
||||
if ( wo.group_saveGroups &&
|
||||
!$.isEmptyObject( wo.group_collapsedGroups ) &&
|
||||
wo.group_collapsedGroups[ wo.group_collapsedGroup ].length ) {
|
||||
|
||||
name = $row.find( '.group-name' ).text().toLowerCase() + $row.attr( 'data-group-index' );
|
||||
isHidden = $.inArray( name, wo.group_collapsedGroups[ wo.group_collapsedGroup ] ) > -1;
|
||||
$row.toggleClass( 'collapsed', isHidden );
|
||||
$rows.toggleClass( 'group-hidden', isHidden );
|
||||
} else if ( wo.group_collapsed && wo.group_collapsible ) {
|
||||
$row.addClass( 'collapsed' );
|
||||
$rows.addClass( 'group-hidden' );
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
groupHeaderHTML : function( c, wo, data ) {
|
||||
return '<tr class="group-header ' + c.selectorRemove.slice(1) +
|
||||
'" unselectable="on" ' + ( c.tabIndex ? 'tabindex="0" ' : '' ) + 'data-group-index="' +
|
||||
( data.groupIndex++ ) + '">' +
|
||||
'<td colspan="' + c.columns + '">' +
|
||||
( wo.group_collapsible ? '<i/>' : '' ) +
|
||||
'<span class="group-name">' + data.currentGroup + '</span>' +
|
||||
'<span class="group-count"></span>' +
|
||||
'</td></tr>';
|
||||
},
|
||||
saveCurrentGrouping : function( c, wo, data ) {
|
||||
// save current grouping
|
||||
var saveName, direction,
|
||||
savedGroup = false;
|
||||
if (wo.group_collapsible && wo.group_saveGroups && ts.storage) {
|
||||
wo.group_collapsedGroups = ts.storage( c.table, 'tablesorter-groups' ) || {};
|
||||
// include direction when saving groups (reversed numbers shows different range values)
|
||||
direction = 'dir' + c.sortList[0][1];
|
||||
// combine column, sort direction & grouping as save key
|
||||
saveName = wo.group_collapsedGroup = '' + c.sortList[0][0] + direction + data.grouping.join('');
|
||||
if (!wo.group_collapsedGroups[saveName]) {
|
||||
wo.group_collapsedGroups[saveName] = [];
|
||||
} else {
|
||||
savedGroup = true;
|
||||
}
|
||||
}
|
||||
return savedGroup;
|
||||
},
|
||||
findColumnGroups : function( c, wo, data ) {
|
||||
var tbodyIndex, norm_rows, $row, rowIndex, end,
|
||||
hasPager = ts.hasWidget( c.table, 'pager' );
|
||||
data.groupIndex = 0;
|
||||
for ( tbodyIndex = 0; tbodyIndex < c.$tbodies.length; tbodyIndex++ ) {
|
||||
norm_rows = c.cache[ tbodyIndex ].normalized;
|
||||
data.group = ''; // clear grouping across tbodies
|
||||
rowIndex = hasPager ? c.pager.startRow - 1 : 0;
|
||||
end = hasPager ? c.pager.endRow : norm_rows.length;
|
||||
for ( ; rowIndex < end; rowIndex++ ) {
|
||||
data.rowData = norm_rows[ rowIndex ];
|
||||
data.$row = data.rowData[ c.columns ].$row;
|
||||
// fixes #438
|
||||
if ( data.$row.is( ':visible' ) && tsg.types[ data.grouping[ 1 ] ] ) {
|
||||
tsg.insertGroupHeader( c, wo, data );
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
insertGroupHeader: function( c, wo, data ) {
|
||||
var $header = c.$headerIndexed[ data.column ],
|
||||
txt = data.rowData[ data.column ],
|
||||
num = /date/.test( data.groupClass ) ? data.grouping[ 2 ] : parseInt( data.grouping[ 2 ] || 1, 10 ) || 1;
|
||||
data.currentGroup = data.rowData ?
|
||||
tsg.types[ data.grouping[ 1 ] ]( c, $header, txt, num, data.group ) :
|
||||
data.currentGroup;
|
||||
if ( data.group !== data.currentGroup ) {
|
||||
data.group = data.currentGroup;
|
||||
if ( $.isFunction( wo.group_formatter ) ) {
|
||||
data.currentGroup = wo.group_formatter( ( data.group || '' ).toString(), data.column, c.table, c, wo ) || data.group;
|
||||
}
|
||||
data.$row.before( tsg.groupHeaderHTML( c, wo, data ) );
|
||||
if ( wo.group_saveGroups && !data.savedGroup && wo.group_collapsed && wo.group_collapsible ) {
|
||||
// all groups start collapsed
|
||||
wo.group_collapsedGroups[ wo.group_collapsedGroup ].push( data.currentGroup );
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
bindEvents : function(table, c, wo){
|
||||
if (wo.group_collapsible) {
|
||||
wo.group_currentGroups = [];
|
||||
wo.group_collapsedGroups = [];
|
||||
// .on() requires jQuery 1.7+
|
||||
c.$table.on('click toggleGroup keyup', 'tr.group-header', function(event){
|
||||
event.stopPropagation();
|
||||
@ -216,33 +255,33 @@
|
||||
if (wo.group_saveGroups && ts.storage) {
|
||||
$groups = c.$table.find('.group-header');
|
||||
isCollapsed = $this.hasClass('collapsed');
|
||||
if (!wo.group_currentGroups[wo.group_currentGroup]) {
|
||||
wo.group_currentGroups[wo.group_currentGroup] = [];
|
||||
if (!wo.group_collapsedGroups[wo.group_collapsedGroup]) {
|
||||
wo.group_collapsedGroups[wo.group_collapsedGroup] = [];
|
||||
}
|
||||
if (isCollapsed && wo.group_currentGroup) {
|
||||
wo.group_currentGroups[wo.group_currentGroup].push( name );
|
||||
} else if (wo.group_currentGroup) {
|
||||
indx = $.inArray( name, wo.group_currentGroups[wo.group_currentGroup] );
|
||||
if (isCollapsed && wo.group_collapsedGroup) {
|
||||
wo.group_collapsedGroups[wo.group_collapsedGroup].push( name );
|
||||
} else if (wo.group_collapsedGroup) {
|
||||
indx = $.inArray( name, wo.group_collapsedGroups[wo.group_collapsedGroup] );
|
||||
if (indx > -1) {
|
||||
wo.group_currentGroups[wo.group_currentGroup].splice( indx, 1 );
|
||||
wo.group_collapsedGroups[wo.group_collapsedGroup].splice( indx, 1 );
|
||||
}
|
||||
}
|
||||
ts.storage( table, 'tablesorter-groups', wo.group_currentGroups );
|
||||
ts.storage( table, 'tablesorter-groups', wo.group_collapsedGroups );
|
||||
}
|
||||
});
|
||||
}
|
||||
$(wo.group_saveReset).on('click', function(){
|
||||
ts.grouping.clearSavedGroups(table);
|
||||
tsg.clearSavedGroups(table);
|
||||
});
|
||||
c.$table.on('pagerChange.tsgrouping', function(){
|
||||
ts.grouping.update(table, c, wo);
|
||||
tsg.update(table, c, wo);
|
||||
});
|
||||
},
|
||||
|
||||
clearSavedGroups: function(table){
|
||||
if (table && ts.storage) {
|
||||
ts.storage(table, 'tablesorter-groups', '');
|
||||
ts.grouping.update(table, table.config, table.config.widgetOptions);
|
||||
tsg.update(table, table.config, table.config.widgetOptions);
|
||||
}
|
||||
}
|
||||
|
||||
@ -284,10 +323,10 @@
|
||||
group_dateString : function(date) { return date.toLocaleString(); }
|
||||
},
|
||||
init: function(table, thisWidget, c, wo){
|
||||
ts.grouping.bindEvents(table, c, wo);
|
||||
tsg.bindEvents(table, c, wo);
|
||||
},
|
||||
format: function(table, c, wo) {
|
||||
ts.grouping.update(table, c, wo);
|
||||
tsg.update(table, c, wo);
|
||||
},
|
||||
remove : function(table, c, wo){
|
||||
c.$table
|
||||
|
Loading…
Reference in New Issue
Block a user