├── jquery_tablesorter ├── models.py ├── __init__.py └── static │ ├── css │ └── tablesorter │ │ ├── psd │ │ ├── green-asc.psd │ │ ├── green-desc.psd │ │ └── green-unsorted.psd │ │ ├── images │ │ ├── black-asc.gif │ │ ├── green-asc.gif │ │ ├── ice-asc.gif │ │ ├── ice-desc.gif │ │ ├── white-asc.gif │ │ ├── black-desc.gif │ │ ├── dropbox-asc.png │ │ ├── green-desc.gif │ │ ├── white-desc.gif │ │ ├── black-unsorted.gif │ │ ├── dropbox-desc.png │ │ ├── green-header.gif │ │ ├── green-unsorted.gif │ │ ├── ice-unsorted.gif │ │ ├── white-unsorted.gif │ │ ├── dropbox-asc-hovered.png │ │ └── dropbox-desc-hovered.png │ │ ├── addons │ │ └── pager │ │ │ ├── icons │ │ │ ├── last.png │ │ │ ├── next.png │ │ │ ├── prev.png │ │ │ ├── first.png │ │ │ └── loading.gif │ │ │ └── jquery.tablesorter.pager.css │ │ ├── theme.jui.css │ │ ├── theme.bootstrap.css │ │ ├── theme.dark.css │ │ ├── theme.black-ice.css │ │ ├── theme.default.css │ │ ├── filter.formatter.css │ │ ├── theme.ice.css │ │ ├── theme.blue.css │ │ ├── theme.dropbox.css │ │ ├── theme.grey.css │ │ ├── theme.green.css │ │ └── theme.less │ └── js │ └── tablesorter │ ├── parsers │ ├── parser-date.js │ ├── parser-date-weekday.js │ ├── parser-date-month.js │ ├── parser-date-iso8601.js │ ├── parser-ignore-articles.js │ ├── parser-date-two-digit-year.js │ ├── parser-feet-inch-fraction.js │ ├── parser-input-select.js │ ├── parser-metric.js │ └── parser-ipv6.js │ ├── widgets │ ├── widget-repeatheaders.js │ ├── widget-editable.js │ ├── widget-grouping.js │ ├── widget-scroller.js │ └── widget-build-table.js │ ├── jquery.metadata.js │ ├── addons │ └── pager │ │ └── jquery.tablesorter.pager.min.js │ └── jquery.tablesorter.widgets-filter-formatter.min.js ├── MANIFEST.in ├── .gitattributes ├── setup.py ├── .gitignore └── README.md /jquery_tablesorter/models.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | graft jquery_tablesorter/static 2 | -------------------------------------------------------------------------------- /jquery_tablesorter/__init__.py: -------------------------------------------------------------------------------- 1 | '''Django static files for the jQuery tablesorter plugin.''' 2 | -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/psd/green-asc.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/django-jquery-tablesorter/django/jquery_tablesorter/static/css/tablesorter/psd/green-asc.psd -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/images/black-asc.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/django-jquery-tablesorter/django/jquery_tablesorter/static/css/tablesorter/images/black-asc.gif -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/images/green-asc.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/django-jquery-tablesorter/django/jquery_tablesorter/static/css/tablesorter/images/green-asc.gif -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/images/ice-asc.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/django-jquery-tablesorter/django/jquery_tablesorter/static/css/tablesorter/images/ice-asc.gif -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/images/ice-desc.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/django-jquery-tablesorter/django/jquery_tablesorter/static/css/tablesorter/images/ice-desc.gif -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/images/white-asc.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/django-jquery-tablesorter/django/jquery_tablesorter/static/css/tablesorter/images/white-asc.gif -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/psd/green-desc.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/django-jquery-tablesorter/django/jquery_tablesorter/static/css/tablesorter/psd/green-desc.psd -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/images/black-desc.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/django-jquery-tablesorter/django/jquery_tablesorter/static/css/tablesorter/images/black-desc.gif -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/images/dropbox-asc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/django-jquery-tablesorter/django/jquery_tablesorter/static/css/tablesorter/images/dropbox-asc.png -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/images/green-desc.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/django-jquery-tablesorter/django/jquery_tablesorter/static/css/tablesorter/images/green-desc.gif -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/images/white-desc.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/django-jquery-tablesorter/django/jquery_tablesorter/static/css/tablesorter/images/white-desc.gif -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/psd/green-unsorted.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/django-jquery-tablesorter/django/jquery_tablesorter/static/css/tablesorter/psd/green-unsorted.psd -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/images/black-unsorted.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/django-jquery-tablesorter/django/jquery_tablesorter/static/css/tablesorter/images/black-unsorted.gif -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/images/dropbox-desc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/django-jquery-tablesorter/django/jquery_tablesorter/static/css/tablesorter/images/dropbox-desc.png -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/images/green-header.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/django-jquery-tablesorter/django/jquery_tablesorter/static/css/tablesorter/images/green-header.gif -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/images/green-unsorted.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/django-jquery-tablesorter/django/jquery_tablesorter/static/css/tablesorter/images/green-unsorted.gif -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/images/ice-unsorted.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/django-jquery-tablesorter/django/jquery_tablesorter/static/css/tablesorter/images/ice-unsorted.gif -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/images/white-unsorted.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/django-jquery-tablesorter/django/jquery_tablesorter/static/css/tablesorter/images/white-unsorted.gif -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/addons/pager/icons/last.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/django-jquery-tablesorter/django/jquery_tablesorter/static/css/tablesorter/addons/pager/icons/last.png -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/addons/pager/icons/next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/django-jquery-tablesorter/django/jquery_tablesorter/static/css/tablesorter/addons/pager/icons/next.png -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/addons/pager/icons/prev.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/django-jquery-tablesorter/django/jquery_tablesorter/static/css/tablesorter/addons/pager/icons/prev.png -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/addons/pager/icons/first.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/django-jquery-tablesorter/django/jquery_tablesorter/static/css/tablesorter/addons/pager/icons/first.png -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/addons/pager/icons/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/django-jquery-tablesorter/django/jquery_tablesorter/static/css/tablesorter/addons/pager/icons/loading.gif -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/images/dropbox-asc-hovered.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/django-jquery-tablesorter/django/jquery_tablesorter/static/css/tablesorter/images/dropbox-asc-hovered.png -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/images/dropbox-desc-hovered.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikebryant/django-jquery-tablesorter/django/jquery_tablesorter/static/css/tablesorter/images/dropbox-desc-hovered.png -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | *.md diss=astextplain -------------------------------------------------------------------------------- /jquery_tablesorter/static/js/tablesorter/parsers/parser-date.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Extract dates using popular natural language date parsers 3 | */ 4 | /*jshint jquery:true */ 5 | ;(function($){ 6 | "use strict"; 7 | 8 | /*! Sugar (http://sugarjs.com/dates#comparing_dates) 9 | * demo: http://jsfiddle.net/Mottie/abkNM/551/ 10 | */ 11 | $.tablesorter.addParser({ 12 | id: "sugar", 13 | is: function() { 14 | return false; 15 | }, 16 | format: function(s) { 17 | return Date.create ? Date.create(s).getTime() || s : new Date(s).getTime() || s; 18 | }, 19 | type: "numeric" 20 | }); 21 | 22 | /*! Datejs (http://www.datejs.com/) 23 | * demo: http://jsfiddle.net/Mottie/abkNM/550/ 24 | */ 25 | $.tablesorter.addParser({ 26 | id: "datejs", 27 | is: function() { 28 | return false; 29 | }, 30 | format: function(s) { 31 | return Date.parse && Date.parse(s) || s; 32 | }, 33 | type: "numeric" 34 | }); 35 | 36 | })(jQuery); 37 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | setup( 4 | name='django-jquery-tablesorter', 5 | version='2.12.0', 6 | url='https://github.com/mikebryant/django-jquery-tablesorter', 7 | description='Django package for the tablesorter plugin.', 8 | author='Christian Bach', 9 | maintainer='Mike Bryant', 10 | maintainer_email='mike@mikebryant.me.uk', 11 | license='GPL', 12 | keywords=['django', 'jquery', 'staticfiles'], 13 | platforms='any', 14 | classifiers=[ 15 | 'Development Status :: 5 - Production/Stable', 16 | 'Environment :: Web Environment', 17 | 'Framework :: Django', 18 | 'Intended Audience :: Developers', 19 | 'Natural Language :: English', 20 | 'Operating System :: OS Independent', 21 | 'Programming Language :: Python', 22 | 'Topic :: Utilities', 23 | ], 24 | packages=['jquery_tablesorter'], 25 | install_requires=['django-jquery >= 1.2.6',], 26 | include_package_data=True, 27 | ) 28 | -------------------------------------------------------------------------------- /jquery_tablesorter/static/js/tablesorter/parsers/parser-date-weekday.js: -------------------------------------------------------------------------------- 1 | /*! Weekday parser 2 | * Demo: http://jsfiddle.net/Mottie/abkNM/477/ 3 | */ 4 | /*jshint jquery:true */ 5 | ;(function($){ 6 | "use strict"; 7 | 8 | var ts = $.tablesorter; 9 | ts.dates = $.extend({}, ts.dates, { 10 | // *** modify this array to change match the language *** 11 | weekdayCased : [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ] 12 | }); 13 | ts.dates.weekdayLower = ts.dates.weekdayCased.join(',').toLocaleLowerCase().split(','); 14 | 15 | ts.addParser({ 16 | id: "weekday", 17 | is: function(){ 18 | return false; 19 | }, 20 | format: function(s, table) { 21 | var j = -1, c = table.config; 22 | s = c.ignoreCase ? s.toLocaleLowerCase() : s; 23 | $.each(ts.dates[ 'weekday' + (c.ignoreCase ? 'Lower' : 'Cased') ], function(i,v){ 24 | if (j < 0 && s.match(v)) { j = i; } 25 | }); 26 | // return s (original string) if there isn't a match 27 | // (non-weekdays will sort separately and empty cells will sort as expected) 28 | return j < 0 ? s : j; 29 | }, 30 | type: "numeric" 31 | }); 32 | 33 | })(jQuery); 34 | -------------------------------------------------------------------------------- /jquery_tablesorter/static/js/tablesorter/parsers/parser-date-month.js: -------------------------------------------------------------------------------- 1 | /*! Month parser 2 | * Demo: http://jsfiddle.net/Mottie/abkNM/477/ 3 | */ 4 | /*jshint jquery:true */ 5 | ;(function($){ 6 | "use strict"; 7 | 8 | var ts = $.tablesorter; 9 | ts.dates = $.extend({}, ts.dates, { 10 | // *** modify this array to change match the language *** 11 | monthCased : [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ] 12 | }); 13 | ts.dates.monthLower = ts.dates.monthCased.join(',').toLocaleLowerCase().split(','); 14 | 15 | ts.addParser({ 16 | id: "month", 17 | is: function(){ 18 | return false; 19 | }, 20 | format: function(s, table) { 21 | var j = -1, c = table.config; 22 | s = c.ignoreCase ? s.toLocaleLowerCase() : s; 23 | $.each(ts.dates[ 'month' + (c.ignoreCase ? 'Lower' : 'Cased') ], function(i,v){ 24 | if (j < 0 && s.match(v)) { j = i; } 25 | }); 26 | // return s (original string) if there isn't a match 27 | // (non-weekdays will sort separately and empty cells will sort as expected) 28 | return j < 0 ? s : j; 29 | }, 30 | type: "numeric" 31 | }); 32 | 33 | })(jQuery); 34 | -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/addons/pager/jquery.tablesorter.pager.css: -------------------------------------------------------------------------------- 1 | /* pager wrapper, div */ 2 | .tablesorter-pager { 3 | padding: 5px; 4 | } 5 | /* pager wrapper, in thead/tfoot */ 6 | td.tablesorter-pager { 7 | background-color: #e6eeee; 8 | margin: 0; /* needed for bootstrap .pager gets a 18px bottom margin */ 9 | } 10 | /* pager navigation arrows */ 11 | .tablesorter-pager img { 12 | vertical-align: middle; 13 | margin-right: 2px; 14 | cursor: pointer; 15 | } 16 | 17 | /* pager output text */ 18 | .tablesorter-pager .pagedisplay { 19 | padding: 0 5px 0 5px; 20 | width: auto; 21 | white-space: nowrap; 22 | text-align: center; 23 | } 24 | 25 | /* pager element reset (needed for bootstrap) */ 26 | .tablesorter-pager select { 27 | margin: 0; 28 | padding: 0; 29 | } 30 | 31 | /*** css used when "updateArrows" option is true ***/ 32 | /* the pager itself gets a disabled class when the number of rows is less than the size */ 33 | .tablesorter-pager.disabled { 34 | display: none; 35 | } 36 | /* hide or fade out pager arrows when the first or last row is visible */ 37 | .tablesorter-pager .disabled { 38 | /* visibility: hidden */ 39 | opacity: 0.5; 40 | filter: alpha(opacity=50); 41 | cursor: default; 42 | } -------------------------------------------------------------------------------- /jquery_tablesorter/static/js/tablesorter/parsers/parser-date-iso8601.js: -------------------------------------------------------------------------------- 1 | /*! ISO-8601 date parser 2 | * This parser will work with dates in ISO8601 format 3 | * 2013-02-18T18:18:44+00:00 4 | * Written by Sean Ellingham :https://github.com/seanellingham 5 | * See https://github.com/Mottie/tablesorter/issues/247 6 | */ 7 | /*global jQuery: false */ 8 | ;(function($){ 9 | "use strict"; 10 | 11 | var iso8601date = /^([0-9]{4})(-([0-9]{2})(-([0-9]{2})(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?$/; 12 | $.tablesorter.addParser({ 13 | id : 'iso8601date', 14 | is : function(s) { 15 | return s.match(iso8601date); 16 | }, 17 | format : function(s) { 18 | var result = s.match(iso8601date); 19 | if (result) { 20 | var date = new Date(result[1], 0, 1); 21 | if (result[3]) { date.setMonth(result[3] - 1); } 22 | if (result[5]) { date.setDate(result[5]); } 23 | if (result[7]) { date.setHours(result[7]); } 24 | if (result[8]) { date.setMinutes(result[8]); } 25 | if (result[10]) { date.setSeconds(result[10]); } 26 | if (result[12]) { date.setMilliseconds(Number('0.' + result[12]) * 1000); } 27 | return date; 28 | } 29 | return 0; 30 | }, 31 | type : 'numeric' 32 | }); 33 | 34 | })(jQuery); 35 | -------------------------------------------------------------------------------- /jquery_tablesorter/static/js/tablesorter/widgets/widget-repeatheaders.js: -------------------------------------------------------------------------------- 1 | /*! tablesorter repeatHeaders widget - updated 4/12/2013 2 | * Requires tablesorter v2.8+ and jQuery 1.7+ 3 | * Original by Christian Bach from the example-widgets.html demo 4 | */ 5 | /*global jQuery: false */ 6 | ;(function($){ 7 | "use strict"; 8 | 9 | $.tablesorter.addWidget({ 10 | id: "repeatHeaders", 11 | priority: 10, 12 | options: { 13 | rowsToSkip : 4 14 | }, 15 | // format is called on init and when a sorting has finished 16 | format: function(table, c, wo) { 17 | var h = '', i, $tr, l, skip; 18 | // cache and collect all TH headers 19 | if (!wo.repeatHeaders) { 20 | h = ''; 21 | $.each(c.headerContent, function(i,t) { 22 | h += '' + t + ''; 23 | }); 24 | // "remove-me" class was added in case the table needs to be updated, the "remove-me" rows will be 25 | // removed prior to the update to prevent including the rows in the update - see "selectorRemove" option 26 | wo.repeatHeaders = h + ''; 27 | } 28 | 29 | // number of rows to skip 30 | skip = wo && wo.rowsToSkip || 4; 31 | 32 | // remove appended headers by classname 33 | c.$table.find("tr.repeated-header").remove(); 34 | $tr = c.$tbodies.find('tr'); 35 | l = $tr.length; 36 | // loop all tr elements and insert a copy of the "headers" 37 | for (i = skip; i < l; i += skip) { 38 | // insert a copy of the table head every X rows 39 | $tr.eq(i).before(wo.repeatHeaders); 40 | } 41 | }, 42 | // this remove function is called when using the refreshWidgets method or when destroying the tablesorter plugin 43 | // this function only applies to tablesorter v2.4+ 44 | remove: function(table, c){ 45 | c.$table.find("tr.repeated-header").remove(); 46 | } 47 | 48 | }); 49 | 50 | })(jQuery); 51 | -------------------------------------------------------------------------------- /jquery_tablesorter/static/js/tablesorter/parsers/parser-ignore-articles.js: -------------------------------------------------------------------------------- 1 | /*! Title parser 2 | * This parser will remove "The", "A" and "An" from the beginning of a book 3 | * or movie title, so it sorts by the second word or number 4 | * Demo: http://jsfiddle.net/Mottie/abkNM/5/ 5 | */ 6 | /*global jQuery: false */ 7 | ;(function($){ 8 | "use strict"; 9 | 10 | // basic list from http://en.wikipedia.org/wiki/Article_%28grammar%29 11 | $.tablesorter.ignoreArticles = { 12 | "en" : "the, a, an", 13 | "de" : "der, die, das, des, dem, den, ein, eine, einer, eines, einem, einen", 14 | "nl" : "de, het, de, een", 15 | "es" : "el, la, lo, los, las, un, una, unos, unas", 16 | "pt" : "o, a, os, as, um, uma, uns, umas", 17 | "fr" : "le, la, l'_, les, un, une, des", 18 | "it" : "il, lo, la, l'_, i, gli, le, un', uno, una, un", 19 | "hu" : "a, az, egy" 20 | }; 21 | 22 | // To add a custom parser, define: 23 | // $.tablesorter.ignoreArticles['xx'] = "A, B, C"; 24 | // and then set the language id 'xx' in the headers option 25 | // ignoreArticles : 'xx' 26 | 27 | $.tablesorter.addParser({ 28 | id: 'ignoreArticles', 29 | is: function() { 30 | return false; 31 | }, 32 | format: function(s, table, cell, cellIndex) { 33 | var c = table.config, art, lang; 34 | if ( !(c.headers && c.headers[cellIndex] && c.headers[cellIndex].ignoreArticlesRegex) ) { 35 | // initialize - save regex in c.headers[cellIndex].ignoreArticles 36 | if (!c.headers) { c.headers = {}; } 37 | if (!c.headers[cellIndex]) { c.headers[cellIndex] = {}; } 38 | lang = $.tablesorter.getData(c.$headers.eq(cellIndex), c.headers[cellIndex], 'ignoreArticles'); 39 | art = ($.tablesorter.ignoreArticles[lang] || "the, a, an" ) + ""; 40 | c.headers[cellIndex].ignoreArticlesRegex = new RegExp('^(' + $.trim( art.split(/\s*\,\s*/).join('\\s|') + "\\s" ).replace("_\\s","") + ')', 'i'); 41 | } 42 | return (s || '').replace(c.headers[cellIndex].ignoreArticlesRegex, ''); 43 | }, 44 | type: 'text' 45 | }); 46 | 47 | })(jQuery); 48 | -------------------------------------------------------------------------------- /jquery_tablesorter/static/js/tablesorter/parsers/parser-date-two-digit-year.js: -------------------------------------------------------------------------------- 1 | /*! Two digit year parser 2 | * Demo: http://jsfiddle.net/Mottie/abkNM/427/ 3 | */ 4 | /*jshint jquery:true */ 5 | ;(function($){ 6 | "use strict"; 7 | 8 | var ts = $.tablesorter, 9 | 10 | // Make the date be within +/- range of the 2 digit year 11 | // so if the current year is 2020, and the 2 digit year is 80 (2080 - 2020 > 50), it becomes 1980 12 | // if the 2 digit year is 50 (2050 - 2020 < 50), then it becomes 2050. 13 | range = 50; 14 | 15 | ts.dates = $.extend({}, ts.dates, { 16 | regxxxxyy: /(\d{1,2})[\/\s](\d{1,2})[\/\s](\d{2})/, 17 | regyyxxxx: /(\d{2})[\/\s](\d{1,2})[\/\s](\d{1,2})/ 18 | }); 19 | 20 | ts.formatDate = function(s, regex, format){ 21 | s = s 22 | // replace separators 23 | .replace(/\s+/g," ").replace(/[-.,]/g, "/") 24 | // reformat xx/xx/xx to mm/dd/19yy; 25 | .replace(regex, format); 26 | var d = new Date(s), 27 | y = d.getFullYear(), 28 | now = new Date().getFullYear(); 29 | // if date > 50 years old (set range), add 100 years 30 | // this will work when people start using "50" and mean "2050" 31 | while (now - y > range) { 32 | y += 100; 33 | } 34 | return d.setFullYear(y); 35 | }; 36 | 37 | $.tablesorter.addParser({ 38 | id: "ddmmyy", 39 | is: function() { 40 | return false; 41 | }, 42 | format: function(s) { 43 | // reformat dd/mm/yy to mm/dd/19yy; 44 | return ts.formatDate(s, ts.dates.regxxxxyy, "$2/$1/19$3"); 45 | }, 46 | type: "numeric" 47 | }); 48 | 49 | $.tablesorter.addParser({ 50 | id: "mmddyy", 51 | is: function() { 52 | return false; 53 | }, 54 | format: function(s) { 55 | // reformat mm/dd/yy to mm/dd/19yy 56 | return ts.formatDate(s, ts.dates.regxxxxyy, "$1/$2/19$3"); 57 | }, 58 | type: "numeric" 59 | }); 60 | 61 | $.tablesorter.addParser({ 62 | id: "yymmdd", 63 | is: function() { 64 | return false; 65 | }, 66 | format: function(s) { 67 | // reformat yy/mm/dd to mm/dd/19yy 68 | return ts.formatDate(s, ts.dates.regyyxxxx, "$2/$3/19$1"); 69 | }, 70 | type: "numeric" 71 | }); 72 | 73 | })(jQuery); 74 | -------------------------------------------------------------------------------- /jquery_tablesorter/static/js/tablesorter/parsers/parser-feet-inch-fraction.js: -------------------------------------------------------------------------------- 1 | /*! Distance parser 2 | * This parser will parser numbers like 5'10" (5 foot 10 inches) 3 | * and 31½ into sortable values. 4 | * Demo: http://jsfiddle.net/Mottie/abkNM/154/ 5 | */ 6 | /*global jQuery: false */ 7 | ;(function($){ 8 | "use strict"; 9 | 10 | var ts = $.tablesorter; 11 | ts.symbolRegex = /[\u215b\u215c\u215d\u215e\u00bc\u00bd\u00be]/g; 12 | ts.processFractions = function(n, table) { 13 | if (n) { 14 | var t, p = 0; 15 | n = $.trim(n.replace(/\"/,'')); 16 | // look for a space in the first part of the number: "10 3/4" and save the "10" 17 | if (/\s/.test(n)) { 18 | p = ts.formatFloat(n.split(' ')[0], table); 19 | // remove stuff to the left of the space 20 | n = $.trim(n.substring(n.indexOf(' '), n.length)); 21 | } 22 | // look for a "/" to calculate fractions 23 | if (/\//g.test(n)) { 24 | t = n.split('/'); 25 | // turn 3/4 into .75; make sure we don't divide by zero 26 | n = p + parseInt(t[0], 10) / parseInt(t[1] || 1, 10); 27 | // look for fraction symbols 28 | } else if (ts.symbolRegex.test(n)) { 29 | n = p + n.replace(ts.symbolRegex, function(m){ 30 | return { 31 | '\u215b' : '.125', // 1/8 32 | '\u215c' : '.375', // 3/8 33 | '\u215d' : '.625', // 5/8 34 | '\u215e' : '.875', // 7/8 35 | '\u00bc' : '.25', // 1/4 36 | '\u00bd' : '.5', // 1/2 37 | '\u00be' : '.75' // 3/4 38 | }[m]; 39 | }); 40 | } 41 | } 42 | return n || 0; 43 | }; 44 | 45 | $.tablesorter.addParser({ 46 | id: 'distance', 47 | is: function() { 48 | // return false so this parser is not auto detected 49 | return false; 50 | }, 51 | format: function(s, table) { 52 | if (s === '') { return ''; } 53 | // look for feet symbol = ' 54 | // very generic test to catch 1.1', 1 1/2' and 1½' 55 | var d = (/^\s*\S*(\s+\S+)?\s*\'/.test(s)) ? s.split("'") : [0,s], 56 | f = ts.processFractions(d[0], table), // feet 57 | i = ts.processFractions(d[1], table); // inches 58 | return (/[\'\"]/).test(s) ? parseFloat(f) + (parseFloat(i)/12 || 0) : parseFloat(f) + parseFloat(i); 59 | }, 60 | type: 'numeric' 61 | }); 62 | 63 | })(jQuery); 64 | -------------------------------------------------------------------------------- /jquery_tablesorter/static/js/tablesorter/widgets/widget-editable.js: -------------------------------------------------------------------------------- 1 | /*! tablesorter Editable Content widget - updated 4/12/2013 2 | * Requires tablesorter v2.8+ and jQuery 1.7+ 3 | * by Rob Garrison 4 | */ 5 | /*jshint browser:true, jquery:true, unused:false */ 6 | /*global jQuery: false */ 7 | ;(function($){ 8 | "use strict"; 9 | 10 | $.tablesorter.addWidget({ 11 | id: 'editable', 12 | options : { 13 | editable_columns : [], 14 | editable_enterToAccept : true, 15 | editable_autoResort : false, 16 | editable_noEdit : 'no-edit', 17 | editable_editComplete : 'editComplete' 18 | }, 19 | init: function(table, thisWidget, c, wo){ 20 | if (!wo.editable_columns.length) { return; } 21 | var cols = []; 22 | $.each(wo.editable_columns, function(i, col){ 23 | cols.push('td:nth-child(' + (col + 1) + ')'); 24 | }); 25 | c.$tbodies.find( cols.join(',') ).not('.' + wo.editable_noEdit).prop('contenteditable', true); 26 | c.$tbodies 27 | .on('mouseleave.tseditable', function(){ 28 | if (c.$table.data('contentFocused')) { 29 | $(':focus').trigger('blur'); 30 | } 31 | }) 32 | .on('focus.tseditable', '[contenteditable]', function(){ 33 | c.$table.data('contentFocused', true); 34 | var $this = $(this), v = $this.html(); 35 | if (wo.editable_enterToAccept) { 36 | // prevent enter from adding into the content 37 | $this.on('keydown.tseditable', function(e){ 38 | if (e.which === 13) { 39 | e.preventDefault(); 40 | } 41 | }); 42 | } 43 | $this.data({ before : v, original: v }); 44 | }) 45 | .on('blur focusout keyup '.split(' ').join('.tseditable '), '[contenteditable]', function(e){ 46 | if (!c.$table.data('contentFocused')) { return; } 47 | var $this = $(e.target), t; 48 | if (e.which === 27) { 49 | // user cancelled 50 | $this.html( $this.data('original') ).trigger('blur.tseditable'); 51 | c.$table.data('contentFocused', false); 52 | return false; 53 | } 54 | t = e.type !== 'keyup' || (wo.editable_enterToAccept && e.which === 13); 55 | // change if new or user hits enter (if option set) 56 | if ($this.data('before') !== $this.html() || t) { 57 | $this.data('before', $this.html()).trigger('change'); 58 | if (t) { 59 | c.$table 60 | .data('contentFocused', false) 61 | .trigger('updateCell', [ $this, wo.editable_autoResort, function(table){ 62 | $this.trigger( wo.editable_editComplete ); 63 | } ]); 64 | $this.trigger('blur.tseditable'); 65 | } 66 | } 67 | }); 68 | } 69 | }); 70 | 71 | })(jQuery); 72 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *_test*.* 11 | *.tmp 12 | *.bak 13 | *.swp 14 | *~.nib 15 | local.properties 16 | .classpath 17 | .settings/ 18 | .loadpath 19 | 20 | # External tool builders 21 | .externalToolBuilders/ 22 | 23 | # Locally stored "Eclipse launch configurations" 24 | *.launch 25 | 26 | # CDT-specific 27 | .cproject 28 | 29 | # PDT-specific 30 | .buildpath 31 | 32 | 33 | ################# 34 | ## Visual Studio 35 | ################# 36 | 37 | ## Ignore Visual Studio temporary files, build results, and 38 | ## files generated by popular Visual Studio add-ons. 39 | 40 | # User-specific files 41 | *.suo 42 | *.user 43 | *.sln.docstates 44 | 45 | # Build results 46 | [Dd]ebug/ 47 | [Rr]elease/ 48 | *_i.c 49 | *_p.c 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.vspscc 64 | .builds 65 | *.dotCover 66 | 67 | ## TODO: If you have NuGet Package Restore enabled, uncomment this 68 | #packages/ 69 | 70 | # Visual C++ cache files 71 | ipch/ 72 | *.aps 73 | *.ncb 74 | *.opensdf 75 | *.sdf 76 | 77 | # Visual Studio profiler 78 | *.psess 79 | *.vsp 80 | 81 | # ReSharper is a .NET coding add-in 82 | _ReSharper* 83 | 84 | # Installshield output folder 85 | [Ee]xpress 86 | 87 | # DocProject is a documentation generator add-in 88 | DocProject/buildhelp/ 89 | DocProject/Help/*.HxT 90 | DocProject/Help/*.HxC 91 | DocProject/Help/*.hhc 92 | DocProject/Help/*.hhk 93 | DocProject/Help/*.hhp 94 | DocProject/Help/Html2 95 | DocProject/Help/html 96 | 97 | # Click-Once directory 98 | publish 99 | 100 | # Others 101 | [Bb]in 102 | [Oo]bj 103 | sql 104 | TestResults 105 | *.Cache 106 | ClientBin 107 | stylecop.* 108 | ~$* 109 | *.dbmdl 110 | Generated_Code #added for RIA/Silverlight projects 111 | 112 | # Backup & report files from converting an old project file to a newer 113 | # Visual Studio version. Backup files are not needed, because we have git ;-) 114 | _UpgradeReport_Files/ 115 | Backup*/ 116 | UpgradeLog*.XML 117 | 118 | 119 | 120 | ############ 121 | ## Windows 122 | ############ 123 | 124 | # Windows image file caches 125 | Thumbs.db 126 | 127 | # Folder config file 128 | Desktop.ini 129 | 130 | 131 | ############# 132 | ## Python 133 | ############# 134 | 135 | *.py[co] 136 | 137 | # Packages 138 | *.egg 139 | *.egg-info 140 | dist 141 | build 142 | eggs 143 | parts 144 | bin 145 | var 146 | sdist 147 | develop-eggs 148 | .installed.cfg 149 | 150 | # Installer logs 151 | pip-log.txt 152 | 153 | # Unit test / coverage reports 154 | .coverage 155 | .tox 156 | 157 | #Translations 158 | *.mo 159 | 160 | #Mr Developer 161 | .mr.developer.cfg 162 | 163 | # Mac crap 164 | .DS_Store 165 | -------------------------------------------------------------------------------- /jquery_tablesorter/static/js/tablesorter/parsers/parser-input-select.js: -------------------------------------------------------------------------------- 1 | /*! input & select parsers for jQuery 1.7+ & tablesorter 2.7.11+ 2 | * Demo: http://mottie.github.com/tablesorter/docs/example-widget-grouping.html 3 | */ 4 | /*jshint browser: true, jquery:true, unused:false */ 5 | ;(function($){ 6 | "use strict"; 7 | 8 | var resort = true, // resort table after update 9 | updateServer = function(event, $table, $input){ 10 | // do something here to update your server, if needed 11 | // event = change event object 12 | // $table = jQuery object of the table that was just updated 13 | // $input = jQuery object of the input or select that was modified 14 | }; 15 | 16 | // Custom parser for parsing input values 17 | // updated dynamically using the "change" function below 18 | $.tablesorter.addParser({ 19 | id: "inputs", 20 | is: function(){ 21 | return false; 22 | }, 23 | format: function(s, table, cell) { 24 | return $(cell).find('input').val() || s; 25 | }, 26 | type: "text" 27 | }); 28 | 29 | // Custom parser for including checkbox status if using the grouping widget 30 | // updated dynamically using the "change" function below 31 | $.tablesorter.addParser({ 32 | id: "checkbox", 33 | is: function(){ 34 | return false; 35 | }, 36 | format: function(s, table, cell) { 37 | // using plain language here because this is what is shown in the group headers 38 | // change it as desired 39 | var $c = $(cell).find('input'); 40 | return $c.length ? $c.is(':checked') ? 'checked' : 'unchecked' : s; 41 | }, 42 | type: "text" 43 | }); 44 | 45 | // Custom parser which returns the currently selected options 46 | // updated dynamically using the "change" function below 47 | $.tablesorter.addParser({ 48 | id: "select", 49 | is: function(){ 50 | return false; 51 | }, 52 | format: function(s, table, cell) { 53 | return $(cell).find('select').val() || s; 54 | }, 55 | type: "text" 56 | }); 57 | 58 | // update select and all input types in the tablesorter cache when the change event fires. 59 | // This method only works with jQuery 1.7+ 60 | // you can change it to use delegate (v1.4.3+) or live (v1.3+) as desired 61 | // if this code interferes somehow, target the specific table $('#mytable'), instead of $('table') 62 | $(window).load(function(){ 63 | // this flag prevents the updateCell event from being spammed 64 | // it happens when you modify input text and hit enter 65 | var alreadyUpdating = false; 66 | $('table').find('tbody').on('change', 'select, input', function(e){ 67 | if (!alreadyUpdating) { 68 | var $tar = $(e.target), 69 | $table = $tar.closest('table'); 70 | alreadyUpdating = true; 71 | $table.trigger('updateCell', [ $tar.closest('td'), resort ]); 72 | updateServer(e, $table, $tar); 73 | setTimeout(function(){ alreadyUpdating = false; }, 10); 74 | } 75 | }); 76 | }); 77 | 78 | })(jQuery); 79 | -------------------------------------------------------------------------------- /jquery_tablesorter/static/js/tablesorter/parsers/parser-metric.js: -------------------------------------------------------------------------------- 1 | /*! Metric parser 2 | * Demo: http://jsfiddle.net/Mottie/abkNM/382/ 3 | * Set the metric name in the header (defaults to "m|meter"), e.g. 4 | * HDD Size 5 | * Distance 6 | */ 7 | /*jshint jquery:true */ 8 | ;(function($){ 9 | "use strict"; 10 | 11 | var prefixes = { 12 | // "prefix" : [ base 10, base 2 ] 13 | // skipping IEEE 1541 defined prefixes: kibibyte, mebibyte, etc, for now. 14 | "Y|Yotta|yotta" : [ 1e24, Math.pow(1024, 8) ], // 1024^8 15 | "Z|Zetta|zetta" : [ 1e21, Math.pow(1024, 7) ], // 1024^7 16 | "E|Exa|exa" : [ 1e18, Math.pow(1024, 6) ], // 1024^6 17 | "P|Peta|peta" : [ 1e15, Math.pow(1024, 5) ], // 1024^5 18 | "T|Tera|tera" : [ 1e12, Math.pow(1024, 4) ], // 1024^4 19 | "G|Giga|giga" : [ 1e9, Math.pow(1024, 3) ], // 1024^3 20 | "M|Mega|mega" : [ 1e6, Math.pow(1024, 2) ], // 1024^2 21 | "k|Kilo|kilo" : [ 1e3, 1024 ], // 1024 22 | // prefixes below here are rarely, if ever, used in binary 23 | "h|hecto" : [ 1e2, 1e2 ], 24 | "da|deka" : [ 1e1, 1e1 ], 25 | "d|deci" : [ 1e-1, 1e-1 ], 26 | "c|centi" : [ 1e-2, 1e-2], 27 | "m|milli" : [ 1e-3, 1e-3 ], 28 | "µ|micro" : [ 1e-6, 1e-6 ], 29 | "n|nano" : [ 1e-9, 1e-9 ], 30 | "p|pico" : [ 1e-12, 1e-12 ], 31 | "f|femto" : [ 1e-15, 1e-15 ], 32 | "a|atto" : [ 1e-18, 1e-18 ], 33 | "z|zepto" : [ 1e-21, 1e-21 ], 34 | "y|yocto" : [ 1e-24, 1e-24 ] 35 | }, 36 | // the \\d+ will not catch digits with spaces, commas or decimals; so use the value from n instead 37 | RegLong = "(\\d+)(\\s+)?([Zz]etta|[Ee]xa|[Pp]eta|[Tt]era|[Gg]iga|[Mm]ega|kilo|hecto|deka|deci|centi|milli|micro|nano|pico|femto|atto|zepto|yocto)(", 38 | RegAbbr = "(\\d+)(\\s+)?(Z|E|P|T|G|M|k|h|da|d|c|m|µ|n|p|f|a|z|y)("; 39 | 40 | $.tablesorter.addParser({ 41 | id: 'metric', 42 | is: function() { 43 | return false; 44 | }, 45 | format: function(s, table, cell, cellIndex) { 46 | var v = 'm|meter', 47 | b, t, 48 | // process number here to get a numerical format (us or eu) 49 | n = $.tablesorter.formatFloat(s.replace(/[^\w,. \-()]/g, ""), table), 50 | $t = table.config.$headers.filter('[data-column="' + cellIndex + '"]'), 51 | m = $t.data('metric'); 52 | if (!m) { 53 | // stored values 54 | t = ($t.attr('data-metric-name') || v).split('|'); 55 | m = [ t[1] || t[0].substring(1), t[0] ]; 56 | m[2] = new RegExp(RegLong + m[0] + "|" + m[1] + ")"); 57 | m[3] = new RegExp(RegAbbr + m[1] + ")"); 58 | $t.data('metric', m); 59 | } 60 | // find match to full name or abbreviation 61 | t = s.match(m[2]) || s.match(m[3]); 62 | if (t) { 63 | for (v in prefixes) { 64 | if (t[3].match(v)) { 65 | // exception when using binary prefix 66 | // change base for binary use 67 | b = /^[b|bit|byte|o|octet]/.test(t[4]) ? 1 : 0; 68 | return n * prefixes[v][b]; 69 | } 70 | } 71 | } 72 | return n; 73 | }, 74 | type: 'numeric' 75 | }); 76 | 77 | })(jQuery); 78 | -------------------------------------------------------------------------------- /jquery_tablesorter/static/js/tablesorter/parsers/parser-ipv6.js: -------------------------------------------------------------------------------- 1 | /*! IPv6 Address parser (WIP) 2 | * IPv6 Address (ffff:0000:0000:0000:0000:0000:0000:0000) 3 | * needs to support short versions like "::8" or "1:2::7:8" 4 | * and "::00:192.168.10.184" (embedded IPv4 address) 5 | * see http://www.intermapper.com/support/tools/IPV6-Validator.aspx 6 | */ 7 | /*global jQuery: false */ 8 | ;(function($){ 9 | "use strict"; 10 | 11 | var ts = $.tablesorter; 12 | 13 | $.extend( ts.regex, {}, { 14 | ipv4Validate : /((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})/, 15 | ipv4Extract : /([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})/, 16 | 17 | // simplified regex from http://www.intermapper.com/support/tools/IPV6-Validator.aspx 18 | // (specifically from http://download.dartware.com/thirdparty/ipv6validator.js) 19 | ipv6Validate : /^\s*((([0-9a-f]{1,4}:){7}([0-9a-f]{1,4}|:))|(([0-9a-f]{1,4}:){6}(:[0-9a-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){5}(((:[0-9a-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){4}(((:[0-9a-f]{1,4}){1,3})|((:[0-9a-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){3}(((:[0-9a-f]{1,4}){1,4})|((:[0-9a-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){2}(((:[0-9a-f]{1,4}){1,5})|((:[0-9a-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){1}(((:[0-9a-f]{1,4}){1,6})|((:[0-9a-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9a-f]{1,4}){1,7})|((:[0-9a-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/i 20 | }); 21 | 22 | ts.addParser({ 23 | id: "ipv6Address", 24 | is: function(s) { 25 | return ts.regex.ipv6Validate.test(s); 26 | }, 27 | format: function(address, table) { 28 | // code modified from http://forrst.com/posts/JS_Expand_Abbreviated_IPv6_Addresses-1OR 29 | var i, t, sides, groups, groupsPresent, 30 | hex = table ? (typeof table === "boolean" ? table : table && table.config.ipv6HexFormat || false) : false, 31 | fullAddress = '', 32 | expandedAddress = '', 33 | validGroupCount = 8, 34 | validGroupSize = 4; 35 | // remove any extra spaces 36 | address = address.replace(/\s*/g, ''); 37 | // look for embedded ipv4 38 | if (ts.regex.ipv4Validate.test(address)) { 39 | groups = address.match(ts.regex.ipv4Extract); 40 | t = ''; 41 | for (i = 1; i < groups.length; i++){ 42 | t += ('00' + (parseInt(groups[i], 10).toString(16)) ).slice(-2) + ( i === 2 ? ':' : '' ); 43 | } 44 | address = address.replace( ts.regex.ipv4Extract, t ); 45 | } 46 | 47 | if (address.indexOf("::") == -1) { 48 | // All eight groups are present 49 | fullAddress = address; 50 | } else { 51 | // Consecutive groups of zeroes have been collapsed with "::". 52 | sides = address.split("::"); 53 | groupsPresent = 0; 54 | for (i = 0; i < sides.length; i++) { 55 | groupsPresent += sides[i].split(":").length; 56 | } 57 | fullAddress += sides[0] + ":"; 58 | for (i = 0; i < validGroupCount - groupsPresent; i++) { 59 | fullAddress += "0000:"; 60 | } 61 | fullAddress += sides[1]; 62 | } 63 | groups = fullAddress.split(":"); 64 | for (i = 0; i < validGroupCount; i++) { 65 | // it's fastest & easiest for tablesorter to sort decimal values (vs hex) 66 | groups[i] = hex ? ('0000' + groups[i]).slice(-4) : 67 | ('00000' + (parseInt(groups[i], 16) || 0)).slice(-5); 68 | expandedAddress += ( i != validGroupCount-1) ? groups[i] + ':' : groups[i]; 69 | } 70 | return hex ? expandedAddress : expandedAddress.replace(/:/g, ''); 71 | }, 72 | // uses natural sort hex compare 73 | type: "numeric" 74 | }); 75 | 76 | })(jQuery); 77 | -------------------------------------------------------------------------------- /jquery_tablesorter/static/js/tablesorter/jquery.metadata.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Metadata - jQuery plugin for parsing metadata from elements 3 | * 4 | * Copyright (c) 2006 John Resig, Yehuda Katz, Jörn Zaefferer, Paul McLanahan 5 | * 6 | * Dual licensed under the MIT and GPL licenses: 7 | * http://www.opensource.org/licenses/mit-license.php 8 | * http://www.gnu.org/licenses/gpl.html 9 | * 10 | */ 11 | 12 | /** 13 | * Sets the type of metadata to use. Metadata is encoded in JSON, and each property 14 | * in the JSON will become a property of the element itself. 15 | * 16 | * There are three supported types of metadata storage: 17 | * 18 | * attr: Inside an attribute. The name parameter indicates *which* attribute. 19 | * 20 | * class: Inside the class attribute, wrapped in curly braces: { } 21 | * 22 | * elem: Inside a child element (e.g. a script tag). The 23 | * name parameter indicates *which* element. 24 | * 25 | * The metadata for an element is loaded the first time the element is accessed via jQuery. 26 | * 27 | * As a result, you can define the metadata type, use $(expr) to load the metadata into the elements 28 | * matched by expr, then redefine the metadata type and run another $(expr) for other elements. 29 | * 30 | * @name $.metadata.setType 31 | * 32 | * @example

This is a p

33 | * @before $.metadata.setType("class") 34 | * @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label" 35 | * @desc Reads metadata from the class attribute 36 | * 37 | * @example

This is a p

38 | * @before $.metadata.setType("attr", "data") 39 | * @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label" 40 | * @desc Reads metadata from a "data" attribute 41 | * 42 | * @example

This is a p

43 | * @before $.metadata.setType("elem", "script") 44 | * @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label" 45 | * @desc Reads metadata from a nested script element 46 | * 47 | * @param String type The encoding type 48 | * @param String name The name of the attribute to be used to get metadata (optional) 49 | * @cat Plugins/Metadata 50 | * @descr Sets the type of encoding to be used when loading metadata for the first time 51 | * @type undefined 52 | * @see metadata() 53 | */ 54 | 55 | (function($) { 56 | 57 | $.extend({ 58 | metadata : { 59 | defaults : { 60 | type: 'class', 61 | name: 'metadata', 62 | cre: /(\{.*\})/, 63 | single: 'metadata' 64 | }, 65 | setType: function( type, name ){ 66 | this.defaults.type = type; 67 | this.defaults.name = name; 68 | }, 69 | get: function( elem, opts ){ 70 | var data, m, e, attr, 71 | settings = $.extend({},this.defaults,opts); 72 | // check for empty string in single property 73 | if ( !settings.single.length ) { settings.single = 'metadata'; } 74 | 75 | data = $.data(elem, settings.single); 76 | // returned cached data if it already exists 77 | if ( data ) { return data; } 78 | 79 | data = "{}"; 80 | 81 | if ( settings.type === "class" ) { 82 | m = settings.cre.exec( elem.className ); 83 | if ( m ) { data = m[1]; } 84 | } else if ( settings.type === "elem" ) { 85 | if( !elem.getElementsByTagName ) { return undefined; } 86 | e = elem.getElementsByTagName(settings.name); 87 | if ( e.length ) { data = $.trim(e[0].innerHTML); } 88 | } else if ( elem.getAttribute !== undefined ) { 89 | attr = elem.getAttribute( settings.name ); 90 | if ( attr ) { data = attr; } 91 | } 92 | 93 | if ( data.indexOf( '{' ) <0 ) { data = "{" + data + "}"; } 94 | 95 | data = eval("(" + data + ")"); 96 | 97 | $.data( elem, settings.single, data ); 98 | return data; 99 | } 100 | } 101 | }); 102 | 103 | /** 104 | * Returns the metadata object for the first member of the jQuery object. 105 | * 106 | * @name metadata 107 | * @descr Returns element's metadata object 108 | * @param Object opts An object contianing settings to override the defaults 109 | * @type jQuery 110 | * @cat Plugins/Metadata 111 | */ 112 | $.fn.metadata = function( opts ){ 113 | return $.metadata.get( this[0], opts ); 114 | }; 115 | 116 | })(jQuery); -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/theme.jui.css: -------------------------------------------------------------------------------- 1 | /************* 2 | jQuery UI Theme 3 | *************/ 4 | /* overall */ 5 | .tablesorter-jui { 6 | width: 100%; 7 | border-collapse: separate; 8 | border-spacing: 2px; /* adjust spacing between table cells */ 9 | margin: 10px 0 15px; 10 | padding: 5px; 11 | font-size: 0.8em; 12 | } 13 | 14 | /* header */ 15 | .tablesorter-jui th, 16 | .tablesorter-jui thead td { 17 | position: relative; 18 | background-repeat: no-repeat; 19 | background-position: right center; 20 | /* UI hover and active states make the font normal and the table resizes, this fixes it */ 21 | font-weight: bold !important; 22 | border-width: 1px !important; 23 | text-align: left; 24 | } 25 | .tablesorter-jui .header, 26 | .tablesorter-jui .tablesorter-header { 27 | cursor: pointer; 28 | white-space: normal; 29 | padding: 8px; /* wider than the icon */ 30 | } 31 | .tablesorter-jui .tablesorter-header-inner { 32 | padding-right: 20px; 33 | } 34 | .tablesorter-jui thead tr th .ui-icon { 35 | position: absolute; 36 | right: 3px; 37 | top: 50%; 38 | margin-top: -8px; /* half the icon height; older IE doesn't like this */ 39 | } 40 | 41 | /* tfoot */ 42 | .tablesorter-jui tfoot th, 43 | .tablesorter-jui tfoot td { 44 | font-weight: normal !important; 45 | font-size: .9em; 46 | padding: 2px; 47 | } 48 | 49 | /* tbody */ 50 | .tablesorter-jui td { 51 | padding: 4px; 52 | vertical-align: top; 53 | } 54 | 55 | /* hovered row colors */ 56 | .tablesorter-jui tbody > tr:hover td { 57 | opacity: 0.7; 58 | filter: alpha(opacity=70); 59 | } 60 | 61 | /* table processing indicator */ 62 | .tablesorter-jui .tablesorter-processing .tablesorter-header-inner { 63 | background-position: center center !important; 64 | background-repeat: no-repeat !important; 65 | /* background-image: url(../addons/pager/icons/loading.gif) !important; */ 66 | background-image: url('data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=') !important; 67 | } 68 | 69 | /* Zebra widget - This allows you to use ui-state-default as the zebra stripe color */ 70 | .tablesorter-jui tr.ui-state-default { 71 | background-image: none; 72 | font-weight: normal; 73 | } 74 | 75 | /* processing background color */ 76 | .tablesorter-jui .tablesorter-processing { 77 | background-color: #ddd; /* older browsers that don't support rgba */ 78 | background-color: rgba(255,255,255,0.8); 79 | } 80 | 81 | /* caption */ 82 | caption { 83 | background: #fff; 84 | } 85 | 86 | /* filter widget */ 87 | .tablesorter-jui .tablesorter-filter-row td { 88 | background: transparent; 89 | line-height: normal; 90 | text-align: center; /* center the input */ 91 | -webkit-transition: line-height 0.1s ease; 92 | -moz-transition: line-height 0.1s ease; 93 | -o-transition: line-height 0.1s ease; 94 | transition: line-height 0.1s ease; 95 | } 96 | /* optional disabled input styling */ 97 | .tablesorter-jui .tablesorter-filter-row .disabled { 98 | opacity: 0.5; 99 | filter: alpha(opacity=50); 100 | cursor: not-allowed; 101 | } 102 | /* hidden filter row */ 103 | .tablesorter-jui .tablesorter-filter-row.hideme td { 104 | /*** *********************************************** ***/ 105 | /*** change this padding to modify the thickness ***/ 106 | /*** of the closed filter row (height = padding x 2) ***/ 107 | padding: 2px; 108 | /*** *********************************************** ***/ 109 | margin: 0; 110 | line-height: 0; 111 | cursor: pointer; 112 | } 113 | .tablesorter-jui .tablesorter-filter-row.hideme .tablesorter-filter { 114 | height: 1px; 115 | min-height: 0; 116 | border: 0; 117 | padding: 0; 118 | margin: 0; 119 | /* don't use visibility: hidden because it disables tabbing */ 120 | opacity: 0; 121 | filter: alpha(opacity=0); 122 | } 123 | /* filters */ 124 | .tablesorter-jui .tablesorter-filter { 125 | width: 98%; 126 | height: auto; 127 | margin: 0; 128 | padding: 4px; 129 | background-color: #fff; 130 | border: 1px solid #bbb; 131 | color: #333; 132 | -webkit-box-sizing: border-box; 133 | -moz-box-sizing: border-box; 134 | box-sizing: border-box; 135 | -webkit-transition: height 0.1s ease; 136 | -moz-transition: height 0.1s ease; 137 | -o-transition: height 0.1s ease; 138 | transition: height 0.1s ease; 139 | } 140 | 141 | /* ajax error row */ 142 | .tablesorter .tablesorter-errorRow td { 143 | cursor: pointer; 144 | background-color: #e6bf99; 145 | } 146 | -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/theme.bootstrap.css: -------------------------------------------------------------------------------- 1 | /************* 2 | Bootstrap theme 3 | *************/ 4 | /* jQuery Bootstrap Theme */ 5 | .tablesorter-bootstrap { 6 | width: 100%; 7 | } 8 | .tablesorter-bootstrap .tablesorter-header, 9 | .tablesorter-bootstrap tfoot th, 10 | .tablesorter-bootstrap tfoot td { 11 | font: bold 14px/20px Arial, Sans-serif; 12 | padding: 4px; 13 | margin: 0 0 18px; 14 | background-color: #eee; 15 | } 16 | 17 | .tablesorter-bootstrap .tablesorter-header { 18 | cursor: pointer; 19 | } 20 | 21 | .tablesorter-bootstrap .tablesorter-header-inner { 22 | position: relative; 23 | padding: 4px 18px 4px 4px; 24 | } 25 | 26 | /* bootstrap uses for icons */ 27 | .tablesorter-bootstrap .tablesorter-header i { 28 | font-size: 11px; 29 | position: absolute; 30 | right: 2px; 31 | top: 50%; 32 | margin-top: -7px; /* half the icon height; older IE doesn't like this */ 33 | width: 14px; 34 | height: 14px; 35 | background-repeat: no-repeat; 36 | line-height: 14px; 37 | display: inline-block; 38 | } 39 | .tablesorter-bootstrap .bootstrap-icon-unsorted { 40 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAOCAYAAAD5YeaVAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAWVJREFUeNqUUL9Lw2AUTGP8mqGlpBQkNeCSRcckEBcHq1jImMElToKuDvpHFMGhU0BQcHBwLji6CE1B4uB/INQsDi4d2jQ/fPeZxo764OV6915f7lLJ81xot9tCURXqdVEUr7IsO6ffH9Q5BlEUCaLwWxWqTcbYnaIoh0Dw4gAvcWlxq1qt9hqNxg6hUGAP+uIPUrGs0qXLer2+v/pTX6QpxLtkc2U2m53ACb8sSdIDXerSEms2m6+DweAICA4d89KGbduf9MpEVdXQ9/2LVqv1CASHjjn3iq/x1xKFfxQPqGnada1W86bT6SiO42OS3qk3KPStLMvbk8nkfjwen/LLuq6blFymMB0KdUPSGhAcOualjX6/f0bCiC7NaWGPQr0BwaFjzn0gYJqmLAiCA8/zni3LmhuGkQPBoWPOPwQeaPIqD4fDruu6L6Zp5kBw6IudchmdJAkLw3DXcZwnIPjy/FuAAQCiqqWWCAFKcwAAAABJRU5ErkJggg==); 41 | } 42 | 43 | /* since bootstrap (table-striped) uses nth-child(), we just use this to add a zebra stripe color */ 44 | .tablesorter-bootstrap tr.odd td { 45 | background-color: #f9f9f9; 46 | } 47 | .tablesorter-bootstrap tbody > .odd:hover > td, 48 | .tablesorter-bootstrap tbody > .even:hover > td { 49 | background-color: #f5f5f5; 50 | } 51 | .tablesorter-bootstrap tr.even td { 52 | background-color: #fff; 53 | } 54 | 55 | /* processing icon */ 56 | .tablesorter-bootstrap .tablesorter-processing { 57 | background-image: url('data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs='); 58 | position: absolute; 59 | z-index: 1000; 60 | } 61 | 62 | /* caption */ 63 | caption { 64 | background: #fff; 65 | } 66 | 67 | /* filter widget */ 68 | .tablesorter-bootstrap .tablesorter-filter-row .tablesorter-filter { 69 | width: 98%; 70 | height: auto; 71 | margin: 0 auto; 72 | padding: 4px 6px; 73 | background-color: #fff; 74 | color: #333; 75 | -webkit-box-sizing: border-box; 76 | -moz-box-sizing: border-box; 77 | box-sizing: border-box; 78 | -webkit-transition: height 0.1s ease; 79 | -moz-transition: height 0.1s ease; 80 | -o-transition: height 0.1s ease; 81 | transition: height 0.1s ease; 82 | } 83 | .tablesorter-bootstrap .tablesorter-filter-row .tablesorter-filter.disabled { 84 | background: #eee; 85 | cursor: not-allowed; 86 | } 87 | .tablesorter-bootstrap .tablesorter-filter-row td { 88 | background: #efefef; 89 | line-height: normal; 90 | text-align: center; 91 | padding: 4px 6px; 92 | vertical-align: middle; 93 | -webkit-transition: line-height 0.1s ease; 94 | -moz-transition: line-height 0.1s ease; 95 | -o-transition: line-height 0.1s ease; 96 | transition: line-height 0.1s ease; 97 | } 98 | /* hidden filter row */ 99 | .tablesorter-bootstrap .tablesorter-filter-row.hideme td { 100 | padding: 2px; /* change this to modify the thickness of the closed border row */ 101 | margin: 0; 102 | line-height: 0; 103 | } 104 | .tablesorter-bootstrap .tablesorter-filter-row.hideme .tablesorter-filter { 105 | height: 1px; 106 | min-height: 0; 107 | border: 0; 108 | padding: 0; 109 | margin: 0; 110 | /* don't use visibility: hidden because it disables tabbing */ 111 | opacity: 0; 112 | filter: alpha(opacity=0); 113 | } 114 | 115 | /* pager plugin */ 116 | .tablesorter-bootstrap .tablesorter-pager select { 117 | padding: 4px 6px; 118 | } 119 | .tablesorter-bootstrap .tablesorter-pager .pagedisplay { 120 | border: 0; 121 | } 122 | /* tfoot i for pager controls */ 123 | .tablesorter-bootstrap tfoot i { 124 | font-size: 11px; 125 | } 126 | 127 | /* ajax error row */ 128 | .tablesorter .tablesorter-errorRow td { 129 | cursor: pointer; 130 | background-color: #e6bf99; 131 | } 132 | -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/theme.dark.css: -------------------------------------------------------------------------------- 1 | /************* 2 | Dark Theme (by thezoggy) 3 | *************/ 4 | /* overall */ 5 | .tablesorter-dark { 6 | width: 100%; 7 | font: 11px/18px Arial, Sans-serif; 8 | color: #ccc; 9 | text-align: left; 10 | background-color: #000; 11 | border-spacing: 0; 12 | } 13 | 14 | /* header */ 15 | .tablesorter-dark th, 16 | .tablesorter-dark thead td { 17 | padding: 4px; 18 | font: bold 12px/20px Arial, Sans-serif; 19 | color: #fff; 20 | background-color: #000; 21 | border-collapse: collapse; 22 | } 23 | .tablesorter-dark thead th { 24 | border-bottom: #333 2px solid; 25 | } 26 | .tablesorter-dark .header, 27 | .tablesorter-dark .tablesorter-header { 28 | padding: 4px 20px 4px 4px; 29 | cursor: pointer; 30 | background-image: url(data:image/gif;base64,R0lGODlhFQAJAIAAAP///////yH5BAEAAAEALAAAAAAVAAkAAAIXjI+AywnaYnhUMoqt3gZXPmVg94yJVQAAOw==); 31 | background-position: center right; 32 | background-repeat: no-repeat; 33 | } 34 | .tablesorter-dark thead .headerSortUp, 35 | .tablesorter-dark thead .tablesorter-headerSortUp, 36 | .tablesorter-dark thead .tablesorter-headerAsc { 37 | background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7); 38 | border-bottom: #888 1px solid; 39 | } 40 | .tablesorter-dark thead .headerSortDown, 41 | .tablesorter-dark thead .tablesorter-headerSortDown, 42 | .tablesorter-dark thead .tablesorter-headerDesc { 43 | background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7); 44 | border-bottom: #888 1px solid; 45 | } 46 | .tablesorter-dark thead .sorter-false { 47 | background-image: none; 48 | padding: 4px; 49 | } 50 | 51 | /* tfoot */ 52 | .tablesorter-dark tfoot .tablesorter-headerSortUp, 53 | .tablesorter-dark tfoot .tablesorter-headerSortDown, 54 | .tablesorter-dark tfoot .tablesorter-headerAsc, 55 | .tablesorter-dark tfoot .tablesorter-headerDesc { 56 | border-top: #888 1px solid; 57 | /* remove sort arrows from footer */ 58 | background-image: none; 59 | } 60 | 61 | /* tbody */ 62 | .tablesorter-dark td { 63 | padding: 4px; 64 | background-color: #000; 65 | border-bottom: #333 1px solid; 66 | color: #ccc; 67 | } 68 | 69 | /* hovered row colors */ 70 | .tablesorter-dark tbody > tr:hover > td, 71 | .tablesorter-dark tbody > tr.even:hover > td, 72 | .tablesorter-dark tbody > tr.odd:hover > td { 73 | background: #000; 74 | } 75 | 76 | /* table processing indicator */ 77 | .tablesorter-dark .tablesorter-processing { 78 | background-position: center center !important; 79 | background-repeat: no-repeat !important; 80 | /* background-image: url(../addons/pager/icons/loading.gif) !important; */ 81 | background-image: url('data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=') !important; 82 | } 83 | 84 | /* Zebra Widget - row alternating colors */ 85 | .tablesorter-dark tr.odd td { 86 | background-color: #202020; 87 | } 88 | .tablesorter-dark tr.even td { 89 | background-color: #101010; 90 | } 91 | 92 | /* Column Widget - column sort colors */ 93 | .tablesorter-dark td.primary, 94 | .tablesorter-dark tr.odd td.primary { 95 | background-color: #0a0a0a; 96 | } 97 | .tablesorter-dark tr.even td.primary { 98 | background-color: #050505; 99 | } 100 | .tablesorter-dark td.secondary, 101 | .tablesorter-dark tr.odd td.secondary { 102 | background-color: #0f0f0f; 103 | } 104 | .tablesorter-dark tr.even td.secondary { 105 | background-color: #0a0a0a; 106 | } 107 | .tablesorter-dark td.tertiary, 108 | .tablesorter-dark tr.odd td.tertiary { 109 | background-color: #191919; 110 | } 111 | .tablesorter-dark tr.even td.tertiary { 112 | background-color: #0f0f0f; 113 | } 114 | 115 | /* caption */ 116 | caption { 117 | background: #fff; 118 | } 119 | 120 | /* filter widget */ 121 | .tablesorter-dark .tablesorter-filter-row td { 122 | background: #202020; 123 | line-height: normal; 124 | text-align: center; /* center the input */ 125 | -webkit-transition: line-height 0.1s ease; 126 | -moz-transition: line-height 0.1s ease; 127 | -o-transition: line-height 0.1s ease; 128 | transition: line-height 0.1s ease; 129 | } 130 | /* optional disabled input styling */ 131 | .tablesorter-dark .tablesorter-filter-row .disabled { 132 | opacity: 0.5; 133 | filter: alpha(opacity=50); 134 | cursor: not-allowed; 135 | } 136 | 137 | /* hidden filter row */ 138 | .tablesorter-dark .tablesorter-filter-row.hideme td { 139 | /*** *********************************************** ***/ 140 | /*** change this padding to modify the thickness ***/ 141 | /*** of the closed filter row (height = padding x 2) ***/ 142 | padding: 2px; 143 | /*** *********************************************** ***/ 144 | margin: 0; 145 | line-height: 0; 146 | cursor: pointer; 147 | } 148 | .tablesorter-dark .tablesorter-filter-row.hideme .tablesorter-filter { 149 | height: 1px; 150 | min-height: 0; 151 | border: 0; 152 | padding: 0; 153 | margin: 0; 154 | /* don't use visibility: hidden because it disables tabbing */ 155 | opacity: 0; 156 | filter: alpha(opacity=0); 157 | } 158 | 159 | /* filters */ 160 | .tablesorter-dark .tablesorter-filter { 161 | width: 98%; 162 | height: auto; 163 | margin: 4px; 164 | padding: 4px; 165 | background-color: #111; 166 | border: 1px solid #222; 167 | color: #ddd; 168 | -webkit-box-sizing: border-box; 169 | -moz-box-sizing: border-box; 170 | box-sizing: border-box; 171 | -webkit-transition: height 0.1s ease; 172 | -moz-transition: height 0.1s ease; 173 | -o-transition: height 0.1s ease; 174 | transition: height 0.1s ease; 175 | } 176 | 177 | /* ajax error row */ 178 | .tablesorter .tablesorter-errorRow td { 179 | cursor: pointer; 180 | background-color: #e6bf99; 181 | } 182 | -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/theme.black-ice.css: -------------------------------------------------------------------------------- 1 | /************* 2 | Black Ice Theme (by thezoggy) 3 | *************/ 4 | /* overall */ 5 | .tablesorter-blackice { 6 | width: 100%; 7 | margin-right: auto; 8 | margin-left: auto; 9 | font: 11px/18px Arial, Sans-serif; 10 | text-align: left; 11 | background-color: #000; 12 | border-collapse: collapse; 13 | border-spacing: 0; 14 | } 15 | 16 | /* header */ 17 | .tablesorter-blackice th, 18 | .tablesorter-blackice thead td { 19 | padding: 4px; 20 | font: bold 13px/20px Arial, Sans-serif; 21 | color: #e5e5e5; 22 | text-align: left; 23 | text-shadow: 0 1px 0 rgba(0, 0, 0, 0.7); 24 | background-color: #111; 25 | border: 1px solid #232323; 26 | } 27 | .tablesorter-blackice .header, 28 | .tablesorter-blackice .tablesorter-header { 29 | padding: 4px 20px 4px 4px; 30 | cursor: pointer; 31 | background-image: url(data:image/gif;base64,R0lGODlhFQAJAIAAAP///////yH5BAEAAAEALAAAAAAVAAkAAAIXjI+AywnaYnhUMoqt3gZXPmVg94yJVQAAOw==); 32 | background-position: center right; 33 | background-repeat: no-repeat; 34 | } 35 | .tablesorter-blackice .headerSortUp, 36 | .tablesorter-blackice .tablesorter-headerSortUp, 37 | .tablesorter-blackice .tablesorter-headerAsc { 38 | background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7); 39 | color: #fff; 40 | } 41 | .tablesorter-blackice .headerSortDown, 42 | .tablesorter-blackice .tablesorter-headerSortDown, 43 | .tablesorter-blackice .tablesorter-headerDesc { 44 | color: #fff; 45 | background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7); 46 | } 47 | .tablesorter-blackice thead .sorter-false { 48 | background-image: none; 49 | padding: 4px; 50 | } 51 | 52 | /* tfoot */ 53 | .tablesorter-blackice tfoot .tablesorter-headerSortUp, 54 | .tablesorter-blackice tfoot .tablesorter-headerSortDown, 55 | .tablesorter-blackice tfoot .tablesorter-headerAsc, 56 | .tablesorter-blackice tfoot .tablesorter-headerDesc { 57 | /* remove sort arrows from footer */ 58 | background-image: none; 59 | } 60 | 61 | /* tbody */ 62 | .tablesorter-blackice td { 63 | padding: 4px; 64 | color: #ccc; 65 | vertical-align: top; 66 | background-color: #333; 67 | border: 1px solid #232323; 68 | } 69 | 70 | /* hovered row colors */ 71 | .tablesorter-blackice tbody > tr:hover > td, 72 | .tablesorter-blackice tbody > tr.even:hover > td, 73 | .tablesorter-blackice tbody > tr.odd:hover > td { 74 | background: #000; 75 | } 76 | 77 | /* table processing indicator */ 78 | .tablesorter-blackice .tablesorter-processing { 79 | background-position: center center !important; 80 | background-repeat: no-repeat !important; 81 | /* background-image: url(../addons/pager/icons/loading.gif) !important; */ 82 | background-image: url('data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=') !important; 83 | } 84 | 85 | /* Zebra Widget - row alternating colors */ 86 | .tablesorter-blackice tr.odd td { 87 | background-color: #333; 88 | } 89 | .tablesorter-blackice tr.even td { 90 | background-color: #393939; 91 | } 92 | 93 | /* Column Widget - column sort colors */ 94 | .tablesorter-blackice td.primary, 95 | .tablesorter-blackice tr.odd td.primary { 96 | background-color: #2f3a40; 97 | } 98 | .tablesorter-blackice tr.even td.primary { 99 | background-color: #3f4a50; 100 | } 101 | .tablesorter-blackice td.secondary, 102 | .tablesorter-blackice tr.odd td.secondary { 103 | background-color: #3f4a50; 104 | } 105 | .tablesorter-blackice tr.even td.secondary { 106 | background-color: #4f5a60; 107 | } 108 | .tablesorter-blackice td.tertiary, 109 | .tablesorter-blackice tr.odd td.tertiary { 110 | background-color: #4f5a60; 111 | } 112 | .tablesorter-blackice tr.even td.tertiary { 113 | background-color: #5a646b; 114 | } 115 | 116 | /* caption */ 117 | caption { 118 | background: #fff; 119 | } 120 | 121 | /* filter widget */ 122 | .tablesorter-blackice .tablesorter-filter-row td { 123 | background: #222; 124 | line-height: normal; 125 | text-align: center; /* center the input */ 126 | -webkit-transition: line-height 0.1s ease; 127 | -moz-transition: line-height 0.1s ease; 128 | -o-transition: line-height 0.1s ease; 129 | transition: line-height 0.1s ease; 130 | } 131 | /* optional disabled input styling */ 132 | .tablesorter-blackice .tablesorter-filter-row .disabled { 133 | opacity: 0.5; 134 | filter: alpha(opacity=50); 135 | cursor: not-allowed; 136 | } 137 | /* hidden filter row */ 138 | .tablesorter-blackice .tablesorter-filter-row.hideme td { 139 | /*** *********************************************** ***/ 140 | /*** change this padding to modify the thickness ***/ 141 | /*** of the closed filter row (height = padding x 2) ***/ 142 | padding: 2px; 143 | /*** *********************************************** ***/ 144 | margin: 0; 145 | line-height: 0; 146 | cursor: pointer; 147 | } 148 | .tablesorter-blackice .tablesorter-filter-row.hideme .tablesorter-filter { 149 | height: 1px; 150 | min-height: 0; 151 | border: 0; 152 | padding: 0; 153 | margin: 0; 154 | /* don't use visibility: hidden because it disables tabbing */ 155 | opacity: 0; 156 | filter: alpha(opacity=0); 157 | } 158 | /* filters */ 159 | .tablesorter-blackice .tablesorter-filter { 160 | width: 98%; 161 | height: auto; 162 | margin: 0; 163 | padding: 4px; 164 | background-color: #fff; 165 | border: 1px solid #bbb; 166 | color: #333; 167 | -webkit-box-sizing: border-box; 168 | -moz-box-sizing: border-box; 169 | box-sizing: border-box; 170 | -webkit-transition: height 0.1s ease; 171 | -moz-transition: height 0.1s ease; 172 | -o-transition: height 0.1s ease; 173 | transition: height 0.1s ease; 174 | } 175 | 176 | /* ajax error row */ 177 | .tablesorter .tablesorter-errorRow td { 178 | cursor: pointer; 179 | background-color: #e6bf99; 180 | } 181 | -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/theme.default.css: -------------------------------------------------------------------------------- 1 | /************* 2 | Default Theme 3 | *************/ 4 | /* overall */ 5 | .tablesorter-default { 6 | width: 100%; 7 | font: 12px/18px Arial, Sans-serif; 8 | color: #333; 9 | background-color: #fff; 10 | border-spacing: 0; 11 | margin: 10px 0 15px; 12 | text-align: left; 13 | } 14 | 15 | /* header */ 16 | .tablesorter-default th, 17 | .tablesorter-default thead td { 18 | font: bold 12px/18px Arial, Sans-serif; 19 | color: #000; 20 | background-color: #fff; 21 | border-collapse: collapse; 22 | border-bottom: #ccc 2px solid; 23 | padding: 0; 24 | } 25 | .tablesorter-default tfoot th, 26 | .tablesorter-default tfoot td { 27 | border: 0; 28 | } 29 | .tablesorter-default .header, 30 | .tablesorter-default .tablesorter-header { 31 | background-image: url(data:image/gif;base64,R0lGODlhFQAJAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAkAAAIXjI+AywnaYnhUMoqt3gZXPmVg94yJVQAAOw==); 32 | background-position: center right; 33 | background-repeat: no-repeat; 34 | cursor: pointer; 35 | white-space: normal; 36 | padding: 4px 20px 4px 4px; 37 | } 38 | .tablesorter-default thead .headerSortUp, 39 | .tablesorter-default thead .tablesorter-headerSortUp, 40 | .tablesorter-default thead .tablesorter-headerAsc { 41 | background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7); 42 | border-bottom: #000 2px solid; 43 | } 44 | .tablesorter-default thead .headerSortDown, 45 | .tablesorter-default thead .tablesorter-headerSortDown, 46 | .tablesorter-default thead .tablesorter-headerDesc { 47 | background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7); 48 | border-bottom: #000 2px solid; 49 | } 50 | .tablesorter-default thead .sorter-false { 51 | background-image: none; 52 | padding: 4px; 53 | } 54 | 55 | /* tfoot */ 56 | .tablesorter-default tfoot .tablesorter-headerSortUp, 57 | .tablesorter-default tfoot .tablesorter-headerSortDown, 58 | .tablesorter-default tfoot .tablesorter-headerAsc, 59 | .tablesorter-default tfoot .tablesorter-headerDesc { 60 | border-top: #000 2px solid; 61 | } 62 | 63 | /* tbody */ 64 | .tablesorter-default td { 65 | background-color: #fff; 66 | border-bottom: #ccc 1px solid; 67 | padding: 4px; 68 | vertical-align: top; 69 | } 70 | 71 | /* hovered row colors */ 72 | .tablesorter-default tbody > tr:hover > td, 73 | .tablesorter-default tbody > tr.even:hover > td, 74 | .tablesorter-default tbody > tr.odd:hover > td { 75 | background: #fff; 76 | color: #000; 77 | } 78 | 79 | /* table processing indicator */ 80 | .tablesorter-default .tablesorter-processing { 81 | background-position: center center !important; 82 | background-repeat: no-repeat !important; 83 | /* background-image: url(../addons/pager/icons/loading.gif) !important; */ 84 | background-image: url('data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=') !important; 85 | } 86 | 87 | /* Zebra Widget - row alternating colors */ 88 | .tablesorter-default tr.odd td { 89 | background-color: #dfdfdf; 90 | } 91 | .tablesorter-default tr.even td { 92 | background-color: #efefef; 93 | } 94 | 95 | /* Column Widget - column sort colors */ 96 | .tablesorter-default tr.odd td.primary { 97 | background-color: #bfbfbf; 98 | } 99 | .tablesorter-default td.primary, 100 | .tablesorter-default tr.even td.primary { 101 | background-color: #d9d9d9; 102 | } 103 | .tablesorter-default tr.odd td.secondary { 104 | background-color: #d9d9d9; 105 | } 106 | .tablesorter-default td.secondary, 107 | .tablesorter-default tr.even td.secondary { 108 | background-color: #e6e6e6; 109 | } 110 | .tablesorter-default tr.odd td.tertiary { 111 | background-color: #e6e6e6; 112 | } 113 | .tablesorter-default td.tertiary, 114 | .tablesorter-default tr.even td.tertiary { 115 | background-color: #f2f2f2; 116 | } 117 | 118 | /* caption */ 119 | caption { 120 | background: #fff; 121 | } 122 | 123 | /* filter widget */ 124 | .tablesorter-default .tablesorter-filter-row td { 125 | background: #eee; 126 | border-bottom: #ccc 1px solid; 127 | line-height: normal; 128 | text-align: center; /* center the input */ 129 | -webkit-transition: line-height 0.1s ease; 130 | -moz-transition: line-height 0.1s ease; 131 | -o-transition: line-height 0.1s ease; 132 | transition: line-height 0.1s ease; 133 | } 134 | /* optional disabled input styling */ 135 | .tablesorter-default .tablesorter-filter-row .disabled { 136 | opacity: 0.5; 137 | filter: alpha(opacity=50); 138 | cursor: not-allowed; 139 | } 140 | /* hidden filter row */ 141 | .tablesorter-default .tablesorter-filter-row.hideme td { 142 | /*** *********************************************** ***/ 143 | /*** change this padding to modify the thickness ***/ 144 | /*** of the closed filter row (height = padding x 2) ***/ 145 | padding: 2px; 146 | /*** *********************************************** ***/ 147 | margin: 0; 148 | line-height: 0; 149 | cursor: pointer; 150 | } 151 | .tablesorter-default .tablesorter-filter-row.hideme .tablesorter-filter { 152 | height: 1px; 153 | min-height: 0; 154 | border: 0; 155 | padding: 0; 156 | margin: 0; 157 | /* don't use visibility: hidden because it disables tabbing */ 158 | opacity: 0; 159 | filter: alpha(opacity=0); 160 | } 161 | /* filters */ 162 | .tablesorter-default .tablesorter-filter { 163 | width: 95%; 164 | height: auto; 165 | margin: 4px; 166 | padding: 4px; 167 | background-color: #fff; 168 | border: 1px solid #bbb; 169 | color: #333; 170 | -webkit-box-sizing: border-box; 171 | -moz-box-sizing: border-box; 172 | box-sizing: border-box; 173 | -webkit-transition: height 0.1s ease; 174 | -moz-transition: height 0.1s ease; 175 | -o-transition: height 0.1s ease; 176 | transition: height 0.1s ease; 177 | } 178 | 179 | /* ajax error row */ 180 | .tablesorter .tablesorter-errorRow td { 181 | cursor: pointer; 182 | background-color: #e6bf99; 183 | } 184 | -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/filter.formatter.css: -------------------------------------------------------------------------------- 1 | /**** Filter Formatter Elements ****/ 2 | .tablesorter .tablesorter-filter-row td { 3 | text-align: center; 4 | font-size: 0.9em; 5 | font-weight: normal; 6 | } 7 | 8 | /**** Sliders ****/ 9 | /* shrink the sliders to look nicer inside of a table cell */ 10 | .tablesorter .ui-slider, .tablesorter input.range { 11 | width: 90%; 12 | margin: 2px auto 2px auto; /* add enough top margin so the tooltips will fit */ 13 | font-size: 0.8em; 14 | } 15 | .tablesorter .ui-slider { 16 | top: 12px; 17 | } 18 | .tablesorter .ui-slider .ui-slider-handle { 19 | width: 0.9em; 20 | height: 0.9em; 21 | } 22 | .tablesorter .ui-datepicker { 23 | font-size: 0.8em; 24 | } 25 | .tablesorter .ui-slider-horizontal { 26 | height: 0.5em; 27 | } 28 | /* Add tooltips to slider handles */ 29 | .tablesorter .value-popup:after { 30 | content : attr(data-value); 31 | position: absolute; 32 | bottom: 14px; 33 | left: -7px; 34 | min-width: 18px; 35 | height: 12px; 36 | background-color: #444; 37 | background-image: -webkit-gradient(linear, left top, left bottom, from(#444444), to(#999999)); 38 | background-image: -webkit-linear-gradient(top, #444, #999); 39 | background-image: -moz-linear-gradient(top, #444, #999); 40 | background-image: -o-linear-gradient(top, #444, #999); 41 | background-image: linear-gradient(to bottom, #444, #999); 42 | -webkit-border-radius: 3px; 43 | border-radius: 3px; 44 | -webkit-background-clip: padding-box; background-clip: padding-box; 45 | -webkit-box-shadow: 0px 0px 4px 0px #777; 46 | box-shadow: 0px 0px 4px 0px #777; 47 | border: #444 1px solid; 48 | color: #fff; 49 | font: 1em/1.1em Arial, Sans-Serif; 50 | padding: 1px; 51 | text-align: center; 52 | } 53 | .tablesorter .value-popup:before { 54 | content: ""; 55 | position: absolute; 56 | width: 0; 57 | height: 0; 58 | border-top: 8px solid #777; 59 | border-left: 8px solid transparent; 60 | border-right: 8px solid transparent; 61 | top: -8px; 62 | left: 50%; 63 | margin-left: -8px; 64 | margin-top: -1px; 65 | } 66 | 67 | /**** Date Picker ****/ 68 | .tablesorter .dateFrom, .tablesorter .dateTo { 69 | width: 80px; 70 | margin: 2px 5px; 71 | } 72 | 73 | /**** Color Picker/HTML5Number Toggle button ****/ 74 | .tablesorter .button { 75 | width: 14px; 76 | height: 14px; 77 | background: #fcfff4; 78 | background: -webkit-linear-gradient(top, #fcfff4 0%, #dfe5d7 40%, #b3bead 100%); 79 | background: -moz-linear-gradient(top, #fcfff4 0%, #dfe5d7 40%, #b3bead 100%); 80 | background: -o-linear-gradient(top, #fcfff4 0%, #dfe5d7 40%, #b3bead 100%); 81 | background: -ms-linear-gradient(top, #fcfff4 0%, #dfe5d7 40%, #b3bead 100%); 82 | background: linear-gradient(top, #fcfff4 0%, #dfe5d7 40%, #b3bead 100%); 83 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fcfff4', endColorstr='#b3bead', GradientType=0 ); 84 | margin: 1px 5px 1px 1px; 85 | -webkit-border-radius: 25px; 86 | -moz-border-radius: 25px; 87 | border-radius: 25px; 88 | -webkit-box-shadow: inset 0px 1px 1px white, 0px 1px 3px rgba(0,0,0,0.5); 89 | -moz-box-shadow: inset 0px 1px 1px white, 0px 1px 3px rgba(0,0,0,0.5); 90 | box-shadow: inset 0px 1px 1px white, 0px 1px 3px rgba(0,0,0,0.5); 91 | position: relative; 92 | top: 3px; 93 | display: inline-block; 94 | } 95 | 96 | .tablesorter .button label { 97 | cursor: pointer; 98 | position: absolute; 99 | width: 10px; 100 | height: 10px; 101 | -webkit-border-radius: 25px; 102 | -moz-border-radius: 25px; 103 | border-radius: 25px; 104 | left: 2px; 105 | top: 2px; 106 | -webkit-box-shadow: inset 0px 1px 1px rgba(0,0,0,0.5), 0px 1px 0px rgba(255,255,255,1); 107 | -moz-box-shadow: inset 0px 1px 1px rgba(0,0,0,0.5), 0px 1px 0px rgba(255,255,255,1); 108 | box-shadow: inset 0px 1px 1px rgba(0,0,0,0.5), 0px 1px 0px rgba(255,255,255,1); 109 | background: #45484d; 110 | background: -webkit-linear-gradient(top, #222 0%, #45484d 100%); 111 | background: -moz-linear-gradient(top, #222 0%, #45484d 100%); 112 | background: -o-linear-gradient(top, #222 0%, #45484d 100%); 113 | background: -ms-linear-gradient(top, #222 0%, #45484d 100%); 114 | background: linear-gradient(top, #222 0%, #45484d 100%); 115 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#222', endColorstr='#45484d', GradientType=0 ); 116 | } 117 | 118 | .tablesorter .button label:after { 119 | -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; 120 | filter: alpha(opacity=0); 121 | opacity: 0; 122 | content: ''; 123 | position: absolute; 124 | width: 8px; 125 | height: 8px; 126 | background: #55f; 127 | background: -webkit-linear-gradient(top, #aaf 0%, #55f 100%); 128 | background: -moz-linear-gradient(top, #aaf 0%, #55f 100%); 129 | background: -o-linear-gradient(top, #aaf 0%, #55f 100%); 130 | background: -ms-linear-gradient(top, #aaf 0%, #55f 100%); 131 | background: linear-gradient(top, #aaf 0%, #55f 100%); 132 | -webkit-border-radius: 25px; 133 | -moz-border-radius: 25px; 134 | border-radius: 25px; 135 | top: 1px; 136 | left: 1px; 137 | -webkit-box-shadow: inset 0px 1px 1px #fff, 0px 1px 3px rgba(0,0,0,0.5); 138 | -moz-box-shadow: inset 0px 1px 1px #fff, 0px 1px 3px rgba(0,0,0,0.5); 139 | box-shadow: inset 0px 1px 1px #fff, 0px 1px 3px rgba(0,0,0,0.5); 140 | } 141 | 142 | .tablesorter .button label:hover::after { 143 | -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=30)"; 144 | filter: alpha(opacity=30); 145 | opacity: 0.3; 146 | } 147 | 148 | .tablesorter .button input[type=checkbox] { 149 | visibility: hidden; 150 | } 151 | 152 | .tablesorter .button input[type=checkbox]:checked + label:after { 153 | -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; 154 | filter: alpha(opacity=100); 155 | opacity: 1; 156 | } 157 | 158 | .tablesorter .colorpicker { 159 | width: 30px; 160 | height: 18px; 161 | } 162 | .tablesorter .ui-spinner-input { 163 | width: 100px; 164 | height: 18px; 165 | } 166 | .tablesorter .currentColor, .tablesorter .ui-spinner { 167 | position: relative; 168 | } 169 | .tablesorter input.number { 170 | position: relative; 171 | } 172 | 173 | /* hide filter row */ 174 | .tablesorter .tablesorter-filter-row.hideme td * { 175 | height: 1px; 176 | min-height: 0; 177 | border: 0; 178 | padding: 0; 179 | margin: 0; 180 | /* don't use visibility: hidden because it disables tabbing */ 181 | opacity: 0; 182 | filter: alpha(opacity=0); 183 | } 184 | -------------------------------------------------------------------------------- /jquery_tablesorter/static/js/tablesorter/widgets/widget-grouping.js: -------------------------------------------------------------------------------- 1 | /*! tablesorter Grouping widget - updated 10/18/2013 2 | * Requires tablesorter v2.8+ and jQuery 1.7+ 3 | * by Rob Garrison 4 | */ 5 | /*jshint browser:true, jquery:true, unused:false */ 6 | /*global jQuery: false */ 7 | ;(function($){ 8 | "use strict"; 9 | var ts = $.tablesorter; 10 | 11 | ts.grouping = { 12 | number : function(c, $col, txt, num, group){ 13 | var t, w; 14 | if (num > 1 && txt !== '') { 15 | if ($col.hasClass(ts.css.sortAsc)) { 16 | t = Math.floor(parseFloat(txt)/num) * num; 17 | return t > parseFloat(group || 0) ? t : parseFloat(group || 0); 18 | } else { 19 | t = Math.ceil(parseFloat(txt)/num) * num; 20 | return t < parseFloat(group || num) - t ? parseFloat(group || num) - t : t; 21 | } 22 | } else { 23 | w = (txt + '').match(/\d+/g); 24 | return w && w.length >= num ? w[num - 1] : txt || ''; 25 | } 26 | }, 27 | word : function(c, $col, txt, num){ 28 | var w = (txt + ' ').match(/\w+/g); 29 | return w && w.length >= num ? w[num - 1] : txt || ''; 30 | }, 31 | letter : function(c, $col, txt, num){ 32 | return txt ? (txt + ' ').substring(0, num) : ''; 33 | }, 34 | date : function(c, $col, txt, part){ 35 | var wo = c.widgetOptions, 36 | t = new Date(txt || ''), 37 | t2 = t.getHours(); 38 | return part === 'year' ? t.getFullYear() : 39 | part === 'month' ? wo.group_months[t.getMonth()] : 40 | part === 'day' ? wo.group_months[t.getMonth()] + ' ' + t.getDate() : 41 | part === 'week' ? wo.group_week[t.getDay()] : 42 | part === 'time' ? ('00' + (t2 > 12 ? t2 - 12 : t2 === 0 ? t2 + 12 : t2)).slice(-2) + ':' + 43 | ('00' + t.getMinutes()).slice(-2) + ' ' + ('00' + wo.group_time[t2 >= 12 ? 1 : 0]).slice(-2) : 44 | t.toString(); 45 | } 46 | }; 47 | 48 | ts.addWidget({ 49 | id: 'group', 50 | // run AFTER the zebra widget, so the header rows do not get zebra striping 51 | priority: 100, 52 | options: { 53 | group_collapsible : true, // make the group header clickable and collapse the rows below it. 54 | group_collapsed : false, // start with all groups collapsed 55 | group_count : ' ({num})', // if not false, the "{num}" string is replaced with the number of rows in the group 56 | // change these default date names based on your language preferences 57 | group_months : [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ], 58 | group_week : [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ], 59 | group_time : [ 'AM', 'PM' ], 60 | group_formatter : null, // function(txt, col, table, c, wo) { return txt; } 61 | group_callback : null, // function($cell, $rows, column, table){}, callback allowing modification of the group header labels 62 | group_complete : 'groupingComplete' // event triggered on the table when the grouping widget has finished work 63 | }, 64 | init: function(table, thisWidget, c, wo){ 65 | if (wo.group_collapsible) { 66 | // .on() requires jQuery 1.7+ 67 | c.$table.on('click toggleGroup', 'tr.group-header', function(e){ 68 | // use shift-click to toggle ALL groups 69 | if (e.type === 'click' && e.shiftKey) { 70 | $(this).siblings('.group-header').trigger('toggleGroup'); 71 | } 72 | $(this).toggleClass('collapsed'); 73 | // nextUntil requires jQuery 1.4+ 74 | $(this).nextUntil('tr.group-header').toggleClass('group-hidden', $(this).hasClass('collapsed') ); 75 | e.stopPropagation(); 76 | }); 77 | } 78 | }, 79 | format: function(table, c, wo) { 80 | var j, k, curr, $tr, t, t2, time, n, 81 | group = '', 82 | col = c.sortList[0] ? c.sortList[0][0] : -1; 83 | c.$table 84 | .find('tr.group-hidden').removeClass('group-hidden').end() 85 | .find('tr.group-header').remove(); 86 | if (wo.group_collapsible) { 87 | // clear pager saved spacer height (in case the rows are collapsed) 88 | $.data(table, 'pagerSavedHeight', 0); 89 | } 90 | if (col >= 0 && !c.$headers.eq(col).hasClass('group-false')) { 91 | if (c.debug){ time = new Date(); } 92 | for (k = 0; k < c.$tbodies.length; k++) { 93 | n = c.cache[k].normalized; 94 | group = ''; // clear grouping across tbodies 95 | $tr = c.$tbodies.eq(k).children('tr'); 96 | if (wo.group_collapsed && wo.group_collapsible) { 97 | $tr.addClass('group-hidden'); 98 | } 99 | for (j = 0; j < $tr.length; j++) { 100 | if ( $tr.eq(j).is(':visible') ) { 101 | t = (c.$headers.eq(col).attr('class') || '').match(/(group-\w+(-\w+)?)/g); 102 | // group-{type}-{number/date} 103 | t2 = t ? t[0].split('-') : ['','letter',1]; // default to letter 1 104 | curr = n[j] ? ts.grouping[t2[1]]( c, c.$headers.eq(col), c.cache[k].normalized[j][col], /date/.test(t) ? t2[2] : parseInt(t2[2] || 1, 10) || 1, group ) : curr; 105 | if (group !== curr) { 106 | group = curr; 107 | // show range if number > 1 108 | if (t2[1] === 'number' && t2[2] > 1 && curr !== '') { 109 | curr += ' - ' + (parseInt(curr, 10) + ((parseInt(t2[2],10) - 1) * (c.$headers.eq(col).hasClass(ts.css.sortAsc) ? 1 : -1))); 110 | } 111 | if ($.isFunction(wo.group_formatter)) { 112 | curr = wo.group_formatter((curr || '').toString(), col, table, c, wo) || curr; 113 | } 114 | $tr.eq(j).before('' + (wo.group_collapsible ? '' : '') + '' + 116 | curr + ''); 117 | } 118 | } 119 | } 120 | } 121 | $tr = c.$table.find('tr.group-header').bind('selectstart', false); 122 | if (wo.group_count || $.isFunction(wo.group_callback)) { 123 | $tr.each(function(){ 124 | var $rows, 125 | $row = $(this), 126 | $label = $row.find('.group-count'); 127 | if ($label.length) { 128 | $rows = $(this).nextUntil('tr.group-header').filter(':visible'); 129 | if (wo.group_count) { 130 | $label.html( wo.group_count.replace(/\{num\}/g, $rows.length) ); 131 | } 132 | if ($.isFunction(wo.group_callback)) { 133 | wo.group_callback($row.find('td'), $rows, col, table); 134 | } 135 | } 136 | }); 137 | } 138 | c.$table.trigger(wo.group_complete); 139 | if (c.debug) { 140 | $.tablesorter.benchmark("Applying groups widget: ", time); 141 | } 142 | } 143 | }, 144 | remove : function(table, c, wo){ 145 | c.$table 146 | .off('click', 'tr.group-header') 147 | .find('.group-hidden').removeClass('group-hidden').end() 148 | .find('tr.group-header').remove(); 149 | } 150 | }); 151 | 152 | })(jQuery); 153 | -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/theme.ice.css: -------------------------------------------------------------------------------- 1 | /************* 2 | Ice Theme (by thezoggy) 3 | *************/ 4 | /* overall */ 5 | .tablesorter-ice { 6 | width: 100%; 7 | background-color: #fff; 8 | margin: 10px 0 15px; 9 | text-align: left; 10 | border-spacing: 0; 11 | border: #ccc 1px solid; 12 | border-width: 1px 0 0 1px; 13 | } 14 | .tablesorter-ice th, 15 | .tablesorter-ice td { 16 | border: #ccc 1px solid; 17 | border-width: 0 1px 1px 0; 18 | } 19 | 20 | /* header */ 21 | .tablesorter-ice th, 22 | .tablesorter-ice thead td { 23 | font: 12px/18px Arial, Sans-serif; 24 | color: #555; 25 | background-color: #f6f8f9; 26 | border-collapse: collapse; 27 | padding: 4px; 28 | text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7); 29 | } 30 | .tablesorter-ice tbody td, 31 | .tablesorter-ice tfoot th, 32 | .tablesorter-ice tfoot td { 33 | padding: 4px; 34 | vertical-align: top; 35 | } 36 | .tablesorter-ice .header, 37 | .tablesorter-ice .tablesorter-header { 38 | background: #f6f8f9 no-repeat center right; 39 | background-image: url(data:image/gif;base64,R0lGODlhDAAMAMQAAAJEjAJCiwJBigJAiANFjgNGjgNEjQRIkQRHkANIkAVMlAVQmAZWnQZUnAdYoAhdpAhZoAlhqQlepQliqQppsApmrQxutgtutQtutAxwtwxwtg1yug1zugxtsw1yuP8A/yH5BAEAAB8ALAAAAAAMAAwAAAUx4Cd+3GiOW4ado2d9VMVm1xg9ptadTsP+QNZEcjoQTBDGCAFgLRSfQgCYMAiCn8EvBAA7); 40 | /* background-image: url(images/ice-unsorted.gif) */ 41 | padding: 4px 20px 4px 4px; 42 | white-space: normal; 43 | cursor: pointer; 44 | } 45 | .tablesorter-ice .headerSortUp, 46 | .tablesorter-ice .tablesorter-headerSortUp, 47 | .tablesorter-ice .tablesorter-headerAsc { 48 | color: #333; 49 | background: #ebedee no-repeat center right; 50 | background-image: url(data:image/gif;base64,R0lGODlhDAAMANUAAAJCiwNHkANFjgNEjQRIkQNJkQRMlARKkwRKkgVPlwZSmgdaogdYnwhfpghcowlhqgliqglgqAlgpwljqwporwpmrQplrAtsswtqsgtrsgtqsQxttAtvtQtttAxyuQxwtwxxtwxvtg10uw1zuQ1xuP8A/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAACUALAAAAAAMAAwAAAY6wJKwJBoahyNQ6Dj0fDoZCpPEuWgqk4jxs8FQLI+Gg8Esm5kQydFQMC7IwkOAqUiUCAIzIjA4lwBlQQA7); 51 | /* background-image: url(images/ice-desc.gif) */ 52 | } 53 | .tablesorter-ice .headerSortDown, 54 | .tablesorter-ice .tablesorter-headerSortDown, 55 | .tablesorter-ice .tablesorter-headerDesc { 56 | color: #333; 57 | background: #ebedee no-repeat center right; 58 | background-image: url(data:image/gif;base64,R0lGODlhDAAMANUAAAE/iAJBigNFjgNEjQNFjQNDiwRHkQRHjwNHjwROlgRMlQRMlARJkgRKkgZQmAVPlgZWnQZSmgZRmAdXoAdXnwdUnAdbogdZoQhbowlhqAlepglkrAliqQtstAtqsQxyugxyuQxwuAxxuAxxtwxwtgxvtQ10vA12vA10u/8A/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAACkALAAAAAAMAAwAAAY6wJQwdRoah6bP6DhEiVIdDxNEGm4yxlDpiJkwv2AmR2OhVCSJBsJ4gUQeCwOB6VAwBAXwYRAIpwBfQQA7); 59 | /* background-image: url(images/ice-asc.gif); */ 60 | } 61 | .tablesorter-ice thead .sorter-false { 62 | background-image: none; 63 | padding: 4px; 64 | } 65 | 66 | /* tfoot */ 67 | .tablesorter-ice tfoot .tablesorter-headerSortUp, 68 | .tablesorter-ice tfoot .tablesorter-headerSortDown, 69 | .tablesorter-ice tfoot .tablesorter-headerAsc, 70 | .tablesorter-ice tfoot .tablesorter-headerDesc { 71 | background: #ebedee; 72 | } 73 | 74 | /* tbody */ 75 | .tablesorter-ice td { 76 | color: #333; 77 | } 78 | 79 | /* hovered row colors */ 80 | .tablesorter-ice tbody > tr:hover > td, 81 | .tablesorter-ice tbody > tr.even:hover > td, 82 | .tablesorter-ice tbody > tr.odd:hover > td { 83 | background: #ebf2fa; 84 | } 85 | 86 | /* table processing indicator */ 87 | .tablesorter-ice .tablesorter-processing { 88 | background-position: center center !important; 89 | background-repeat: no-repeat !important; 90 | /* background-image: url(../addons/pager/icons/loading.gif) !important; */ 91 | background-image: url('data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=') !important; 92 | } 93 | 94 | /* Zebra Widget - row alternating colors */ 95 | .tablesorter-ice tr.odd td { 96 | background-color: #dfdfdf; 97 | } 98 | .tablesorter-ice tr.even td { 99 | background-color: #efefef; 100 | } 101 | 102 | /* Column Widget - column sort colors */ 103 | .tablesorter-ice td.primary, 104 | .tablesorter-ice tr.odd td.primary { 105 | background-color: #9ae5e5; 106 | } 107 | .tablesorter-ice tr.even td.primary { 108 | background-color: #c2f0f0; 109 | } 110 | .tablesorter-ice td.secondary, 111 | .tablesorter-ice tr.odd td.secondary { 112 | background-color: #c2f0f0; 113 | } 114 | .tablesorter-ice tr.even td.secondary { 115 | background-color: #d5f5f5; 116 | } 117 | .tablesorter-ice td.tertiary, 118 | .tablesorter-ice tr.odd td.tertiary { 119 | background-color: #d5f5f5; 120 | } 121 | .tablesorter-ice tr.even td.tertiary { 122 | background-color: #ebfafa; 123 | } 124 | 125 | /* caption */ 126 | caption { 127 | background: #fff; 128 | } 129 | 130 | /* filter widget */ 131 | .tablesorter-ice .tablesorter-filter-row td { 132 | background: #eee; 133 | line-height: normal; 134 | text-align: center; /* center the input */ 135 | -webkit-transition: line-height 0.1s ease; 136 | -moz-transition: line-height 0.1s ease; 137 | -o-transition: line-height 0.1s ease; 138 | transition: line-height 0.1s ease; 139 | } 140 | /* optional disabled input styling */ 141 | .tablesorter-ice .tablesorter-filter-row .disabled { 142 | opacity: 0.5; 143 | filter: alpha(opacity=50); 144 | cursor: not-allowed; 145 | } 146 | /* hidden filter row */ 147 | .tablesorter-ice .tablesorter-filter-row.hideme td { 148 | /*** *********************************************** ***/ 149 | /*** change this padding to modify the thickness ***/ 150 | /*** of the closed filter row (height = padding x 2) ***/ 151 | padding: 2px; 152 | /*** *********************************************** ***/ 153 | margin: 0; 154 | line-height: 0; 155 | cursor: pointer; 156 | } 157 | .tablesorter-ice .tablesorter-filter-row.hideme .tablesorter-filter { 158 | height: 1px; 159 | min-height: 0; 160 | border: 0; 161 | padding: 0; 162 | margin: 0; 163 | /* don't use visibility: hidden because it disables tabbing */ 164 | opacity: 0; 165 | filter: alpha(opacity=0); 166 | } 167 | /* filters */ 168 | .tablesorter-ice .tablesorter-filter { 169 | width: 98%; 170 | height: auto; 171 | margin: 4px; 172 | padding: 4px; 173 | background-color: #fff; 174 | border: 1px solid #bbb; 175 | color: #333; 176 | -webkit-box-sizing: border-box; 177 | -moz-box-sizing: border-box; 178 | box-sizing: border-box; 179 | -webkit-transition: height 0.1s ease; 180 | -moz-transition: height 0.1s ease; 181 | -o-transition: height 0.1s ease; 182 | transition: height 0.1s ease; 183 | } 184 | 185 | /* ajax error row */ 186 | .tablesorter .tablesorter-errorRow td { 187 | cursor: pointer; 188 | background-color: #e6bf99; 189 | } 190 | -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/theme.blue.css: -------------------------------------------------------------------------------- 1 | /************* 2 | Blue Theme 3 | *************/ 4 | /* overall */ 5 | .tablesorter-blue { 6 | width: 100%; 7 | background-color: #fff; 8 | margin: 10px 0 15px; 9 | text-align: left; 10 | border-spacing: 0; 11 | border: #cdcdcd 1px solid; 12 | border-width: 1px 0 0 1px; 13 | } 14 | .tablesorter-blue th, 15 | .tablesorter-blue td { 16 | border: #cdcdcd 1px solid; 17 | border-width: 0 1px 1px 0; 18 | } 19 | 20 | /* header */ 21 | .tablesorter-blue th, 22 | .tablesorter-blue thead td { 23 | font: bold 12px/18px Arial, Sans-serif; 24 | color: #000; 25 | background-color: #99bfe6; 26 | border-collapse: collapse; 27 | padding: 4px; 28 | text-shadow: 0 1px 0 rgba(204, 204, 204, 0.7); 29 | } 30 | .tablesorter-blue tbody td, 31 | .tablesorter-blue tfoot th, 32 | .tablesorter-blue tfoot td { 33 | padding: 4px; 34 | vertical-align: top; 35 | } 36 | .tablesorter-blue .header, 37 | .tablesorter-blue .tablesorter-header { 38 | /* black (unsorted) double arrow */ 39 | background-image: url(data:image/gif;base64,R0lGODlhFQAJAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAkAAAIXjI+AywnaYnhUMoqt3gZXPmVg94yJVQAAOw==); 40 | /* white (unsorted) double arrow */ 41 | /* background-image: url(data:image/gif;base64,R0lGODlhFQAJAIAAAP///////yH5BAEAAAEALAAAAAAVAAkAAAIXjI+AywnaYnhUMoqt3gZXPmVg94yJVQAAOw==); */ 42 | /* image */ 43 | /* background-image: url(images/black-unsorted.gif); */ 44 | background-repeat: no-repeat; 45 | background-position: center right; 46 | padding: 4px 18px 4px 4px; 47 | white-space: normal; 48 | cursor: pointer; 49 | } 50 | .tablesorter-blue .headerSortUp, 51 | .tablesorter-blue .tablesorter-headerSortUp, 52 | .tablesorter-blue .tablesorter-headerAsc { 53 | background-color: #9fbfdf; 54 | /* black asc arrow */ 55 | background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7); 56 | /* white asc arrow */ 57 | /* background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7); */ 58 | /* image */ 59 | /* background-image: url(images/black-asc.gif); */ 60 | } 61 | .tablesorter-blue .headerSortDown, 62 | .tablesorter-blue .tablesorter-headerSortDown, 63 | .tablesorter-blue .tablesorter-headerDesc { 64 | background-color: #8cb3d9; 65 | /* black desc arrow */ 66 | background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7); 67 | /* white desc arrow */ 68 | /* background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7); */ 69 | /* image */ 70 | /* background-image: url(images/black-desc.gif); */ 71 | } 72 | .tablesorter-blue thead .sorter-false { 73 | background-image: none; 74 | padding: 4px; 75 | } 76 | 77 | /* tfoot */ 78 | .tablesorter-blue tfoot .tablesorter-headerSortUp, 79 | .tablesorter-blue tfoot .tablesorter-headerSortDown, 80 | .tablesorter-blue tfoot .tablesorter-headerAsc, 81 | .tablesorter-blue tfoot .tablesorter-headerDesc { 82 | /* remove sort arrows from footer */ 83 | background-image: none; 84 | } 85 | 86 | /* tbody */ 87 | .tablesorter-blue td { 88 | color: #3d3d3d; 89 | background-color: #fff; 90 | padding: 4px; 91 | vertical-align: top; 92 | } 93 | 94 | /* hovered row colors 95 | you'll need to add additional lines for 96 | rows with more than 2 child rows 97 | */ 98 | .tablesorter-blue tbody > tr:hover > td, 99 | .tablesorter-blue tbody > tr:hover + tr.tablesorter-childRow > td, 100 | .tablesorter-blue tbody > tr:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td, 101 | .tablesorter-blue tbody > tr.even:hover > td, 102 | .tablesorter-blue tbody > tr.even:hover + tr.tablesorter-childRow > td, 103 | .tablesorter-blue tbody > tr.even:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td { 104 | background: #d9d9d9; 105 | } 106 | .tablesorter-blue tbody > tr.odd:hover > td, 107 | .tablesorter-blue tbody > tr.odd:hover + tr.tablesorter-childRow > td, 108 | .tablesorter-blue tbody > tr.odd:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td { 109 | background: #bfbfbf; 110 | } 111 | 112 | /* table processing indicator */ 113 | .tablesorter-blue .tablesorter-processing { 114 | background-position: center center !important; 115 | background-repeat: no-repeat !important; 116 | /* background-image: url(../addons/pager/icons/loading.gif) !important; */ 117 | background-image: url('data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=') !important; 118 | } 119 | 120 | /* Zebra Widget - row alternating colors */ 121 | .tablesorter-blue tbody tr.odd td { 122 | background-color: #ebf2fa; 123 | } 124 | .tablesorter-blue tbody tr.even td { 125 | background-color: #fff; 126 | } 127 | 128 | /* Column Widget - column sort colors */ 129 | .tablesorter-blue td.primary, 130 | .tablesorter-blue tr.odd td.primary { 131 | background-color: #99b3e6; 132 | } 133 | .tablesorter-blue tr.even td.primary { 134 | background-color: #c2d1f0; 135 | } 136 | .tablesorter-blue td.secondary, 137 | .tablesorter-blue tr.odd td.secondary { 138 | background-color: #c2d1f0; 139 | } 140 | .tablesorter-blue tr.even td.secondary { 141 | background-color: #d6e0f5; 142 | } 143 | .tablesorter-blue td.tertiary, 144 | .tablesorter-blue tr.odd td.tertiary { 145 | background-color: #d6e0f5; 146 | } 147 | .tablesorter-blue tr.even td.tertiary { 148 | background-color: #ebf0fa; 149 | } 150 | 151 | /* caption */ 152 | caption { 153 | background: #fff; 154 | } 155 | 156 | /* filter widget */ 157 | .tablesorter-blue .tablesorter-filter-row td { 158 | background: #eee; 159 | line-height: normal; 160 | text-align: center; /* center the input */ 161 | -webkit-transition: line-height 0.1s ease; 162 | -moz-transition: line-height 0.1s ease; 163 | -o-transition: line-height 0.1s ease; 164 | transition: line-height 0.1s ease; 165 | } 166 | /* optional disabled input styling */ 167 | .tablesorter-blue .tablesorter-filter-row .disabled { 168 | opacity: 0.5; 169 | filter: alpha(opacity=50); 170 | cursor: not-allowed; 171 | } 172 | /* hidden filter row */ 173 | .tablesorter-blue .tablesorter-filter-row.hideme td { 174 | /*** *********************************************** ***/ 175 | /*** change this padding to modify the thickness ***/ 176 | /*** of the closed filter row (height = padding x 2) ***/ 177 | padding: 2px; 178 | /*** *********************************************** ***/ 179 | margin: 0; 180 | line-height: 0; 181 | cursor: pointer; 182 | } 183 | .tablesorter-blue .tablesorter-filter-row.hideme .tablesorter-filter { 184 | height: 1px; 185 | min-height: 0; 186 | border: 0; 187 | padding: 0; 188 | margin: 0; 189 | /* don't use visibility: hidden because it disables tabbing */ 190 | opacity: 0; 191 | filter: alpha(opacity=0); 192 | } 193 | /* filters */ 194 | .tablesorter-blue .tablesorter-filter { 195 | width: 98%; 196 | height: auto; 197 | margin: 0; 198 | padding: 4px; 199 | background-color: #fff; 200 | border: 1px solid #bbb; 201 | color: #333; 202 | -webkit-box-sizing: border-box; 203 | -moz-box-sizing: border-box; 204 | box-sizing: border-box; 205 | -webkit-transition: height 0.1s ease; 206 | -moz-transition: height 0.1s ease; 207 | -o-transition: height 0.1s ease; 208 | transition: height 0.1s ease; 209 | } 210 | 211 | /* ajax error row */ 212 | .tablesorter .tablesorter-errorRow td { 213 | cursor: pointer; 214 | background-color: #e6bf99; 215 | } 216 | -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/theme.dropbox.css: -------------------------------------------------------------------------------- 1 | /************* 2 | Dropbox Theme (by thezoggy) 3 | *************/ 4 | /* overall */ 5 | .tablesorter-dropbox { 6 | width: 100%; 7 | font: 13px/32px "Open Sans","lucida grande","Segoe UI",arial,verdana,"lucida sans unicode",tahoma,sans-serif; 8 | color: #555; 9 | text-align: left; 10 | background-color: #fff; 11 | border-collapse: collapse; 12 | border-top: 1px solid #82cffa; 13 | border-spacing: 0; 14 | } 15 | 16 | /* header */ 17 | .tablesorter-dropbox th, 18 | .tablesorter-dropbox thead td, 19 | .tablesorter-dropbox tfoot th, 20 | .tablesorter-dropbox tfoot td { 21 | background-color: #f0f9ff; 22 | border-color: #82cffa #e7f2fb #96c4ea; 23 | border-style: solid; 24 | border-width: 1px; 25 | padding: 3px 6px; 26 | font-size: 13px; 27 | font-weight: normal; 28 | line-height: 29px; 29 | color: #2281CF; 30 | text-align: left; 31 | } 32 | .tablesorter-dropbox .header, 33 | .tablesorter-dropbox thead tr, 34 | .tablesorter-dropbox .tablesorter-headerRow { 35 | background-color: #f0f9ff; 36 | border-bottom: 1px solid #96c4ea; 37 | box-shadow: 0 1px 1px rgba(0, 0, 0, 0.12), 0 0 0 #000000 inset; 38 | cursor: pointer; 39 | white-space: normal; 40 | } 41 | .tablesorter-dropbox .tablesorter-headerSortUp, 42 | .tablesorter-dropbox .tablesorter-headerSortDown, 43 | .tablesorter-dropbox .tablesorter-headerAsc, 44 | .tablesorter-dropbox .tablesorter-headerDesc { 45 | font-weight: 600; 46 | } 47 | .tablesorter-dropbox .tablesorter-header i { 48 | width: 9px; 49 | height: 9px; 50 | padding: 4px 20px 4px 4px; 51 | cursor: pointer; 52 | background-position: center right; 53 | background-repeat: no-repeat; 54 | content: ""; 55 | } 56 | .tablesorter-dropbox .tablesorter-headerSortUp i, 57 | .tablesorter-dropbox .tablesorter-headerAsc i { 58 | background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAALhJREFUeNpi/P//PwMhwILMiexYx8bIxNTy/9+/muUVQb9g4kzIitg4edI4+YRLQTSyOCPMupjerUI8whK3OXgEhH58+fDuy9sXqkuKvd+hmMTOxdvCxS8sxMUvxACiQXwU6+Im7DDg5BNKY+fiY2BmYWMA0SA+SByuiJ2bbzIHrwAzMxsb0AGMDCAaxAeJg+SZ7wtaqfAISfQAdTIwMUM8ywhUyMTEzPD/71+5FXvPLWUkJpwAAgwAZqYvvHStbD4AAAAASUVORK5CYII='); 59 | /* background-image: url(images/dropbox-asc.png); */ 60 | } 61 | .tablesorter-dropbox .tablesorter-headerSortUp:hover i, 62 | .tablesorter-dropbox .tablesorter-headerAsc:hover i { 63 | background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAALVJREFUeNpi/P//PwMhwILMCc+qZGNkYmr5/+9fzcpp7b9g4kzIitjYOdM4uXlLQTSyOCPMuqi8OiEefsHbHFzcQj++fX335eN71WWTmt6hmMTOwdXCycMnBDSJAUSD+CjWxRQ0GHBw86Sxc3AyMDOzMIBoEB8kDlfEzsk1mYOLByjPCnQAIwOIBvFB4iB55rsfmVS4+QV7QNYwMTNDHApUyMTExPDv/z+5Feu3L2UkJpwAAgwA244u+I9CleAAAAAASUVORK5CYII='); 64 | /* background-image: url(images/dropbox-asc-hovered.png); */ 65 | } 66 | .tablesorter-dropbox .tablesorter-headerSortDown i, 67 | .tablesorter-dropbox .tablesorter-headerDesc i { 68 | background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAALdJREFUeNpi/P//PwMhwBLdtVGFhZ3zNhMzC4bkv79/GP78/K7KCDIpZ9mVw+xcfDaMTExwBf///WP4+e3TkSlROrZg7UxMLLns3HxnmFnZmGGK/v7+9ff3j2+5YHkQMSlC48Kv719m/f//D2IKkAbxQeJwRSDw4/OHmr+/fr0DqmAA0SA+TA6uaEq0zjugG+r//vkFcks9iA/3HbJvvn18O+vf379yP758mMXAoAAXZyQmnAACDADX316BiTFbMQAAAABJRU5ErkJggg=='); 69 | /* background-image: url(images/dropbox-desc.png); */ 70 | } 71 | .tablesorter-dropbox .tablesorter-headerSortDown:hover i, 72 | .tablesorter-dropbox .tablesorter-headerDesc:hover i { 73 | background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAALNJREFUeNpi/P//PwMhwBJf3uP879e3PUzMzBiS//7+ZWBi43JhBJmU2z7nIzMzEx8jIyNcAUj8799/nyZXpvCzgARYuXjTWBkZVjCzIEz7++cvw+//DGkgNiPMTWVT1l5hZvynDTINbMp/pqtdOcE6IDkmmM5fv3/5//v37z9QBQOIBvFhcnBFEwoj7/5jZFnz9+8fBhAN4sN9h+ybH9++JrGxscr/+vE1CVmckZhwAggwANvlUyq5Dd1wAAAAAElFTkSuQmCC'); 74 | /* background-image: url(images/dropbox-desc-hovered.png); */ 75 | } 76 | .tablesorter-dropbox thead .sorter-false i, 77 | .tablesorter-dropbox thead .sorter-false:hover i { 78 | background-image: none; 79 | padding: 4px; 80 | } 81 | 82 | /* tbody */ 83 | .tablesorter-dropbox td { 84 | padding: 5px 6px; 85 | line-height: 32px; 86 | color: #555; 87 | text-align: left; 88 | border-top: 1px solid #edf1f5; 89 | border-bottom: 1px solid #edf1f5; 90 | } 91 | 92 | /* hovered row colors */ 93 | .tablesorter-dropbox tbody > tr:hover > td, 94 | .tablesorter-dropbox tbody > tr.even:hover > td, 95 | .tablesorter-dropbox tbody > tr.odd:hover > td { 96 | background-color: rgba(230, 245, 255, 0.3); 97 | border-right: 0; 98 | border-left: 0; 99 | border-color: #c6d8e4; 100 | /* trick to do border-top and bottom colors */ 101 | border-style: double; 102 | } 103 | 104 | /* table processing indicator */ 105 | .tablesorter-dropbox .tablesorter-processing { 106 | background-position: center center !important; 107 | background-repeat: no-repeat !important; 108 | /* background-image: url(../addons/pager/icons/loading.gif) !important; */ 109 | background-image: url('data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=') !important; 110 | } 111 | 112 | /* Zebra Widget - row alternating colors */ 113 | .tablesorter-dropbox tr.odd td { 114 | } 115 | .tablesorter-dropbox tr.even td { 116 | } 117 | 118 | /* Column Widget - column sort colors */ 119 | .tablesorter-dropbox td.primary, 120 | .tablesorter-dropbox tr.odd td.primary { 121 | } 122 | .tablesorter-dropbox tr.even td.primary { 123 | } 124 | .tablesorter-dropbox td.secondary, 125 | .tablesorter-dropbox tr.odd td.secondary { 126 | } 127 | .tablesorter-dropbox tr.even td.secondary { 128 | } 129 | .tablesorter-dropbox td.tertiary, 130 | .tablesorter-dropbox tr.odd td.tertiary { 131 | } 132 | .tablesorter-dropbox tr.even td.tertiary { 133 | } 134 | 135 | /* caption */ 136 | caption { 137 | background: #fff; 138 | } 139 | 140 | /* Filter Widget */ 141 | .tablesorter-dropbox .tablesorter-filter-row td { 142 | background: #fff; 143 | line-height: normal; 144 | text-align: center; /* center the input */ 145 | -webkit-transition: line-height 0.1s ease; 146 | -moz-transition: line-height 0.1s ease; 147 | -o-transition: line-height 0.1s ease; 148 | transition: line-height 0.1s ease; 149 | } 150 | /* optional disabled input styling */ 151 | .tablesorter-dropbox .tablesorter-filter-row .disabled { 152 | opacity: 0.5; 153 | filter: alpha(opacity=50); 154 | cursor: not-allowed; 155 | } 156 | 157 | /* hidden filter row */ 158 | .tablesorter-dropbox .tablesorter-filter-row.hideme td { 159 | /*** *********************************************** ***/ 160 | /*** change this padding to modify the thickness ***/ 161 | /*** of the closed filter row (height = padding x 2) ***/ 162 | padding: 2px; 163 | /*** *********************************************** ***/ 164 | margin: 0; 165 | line-height: 0; 166 | cursor: pointer; 167 | } 168 | .tablesorter-dropbox .tablesorter-filter-row.hideme .tablesorter-filter { 169 | height: 1px; 170 | min-height: 0; 171 | border: 0; 172 | padding: 0; 173 | margin: 0; 174 | /* don't use visibility: hidden because it disables tabbing */ 175 | opacity: 0; 176 | filter: alpha(opacity=0); 177 | } 178 | 179 | /* filters */ 180 | .tablesorter-dropbox .tablesorter-filter { 181 | width: 98%; 182 | height: auto; 183 | margin: 4px; 184 | 185 | background-color: #fff; 186 | border: 1px solid #bbb; 187 | color: #333; 188 | -webkit-box-sizing: border-box; 189 | -moz-box-sizing: border-box; 190 | box-sizing: border-box; 191 | -webkit-transition: height 0.1s ease; 192 | -moz-transition: height 0.1s ease; 193 | -o-transition: height 0.1s ease; 194 | transition: height 0.1s ease; 195 | } 196 | 197 | /* ajax error row */ 198 | .tablesorter .tablesorter-errorRow td { 199 | cursor: pointer; 200 | background-color: #e6bf99; 201 | } 202 | -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/theme.grey.css: -------------------------------------------------------------------------------- 1 | /************* 2 | Grey Theme 3 | *************/ 4 | /* overall */ 5 | .tablesorter-grey { 6 | width: 100%; 7 | margin: 10px 0 15px; 8 | text-align: left; 9 | border-spacing: 0; 10 | border-left: #555 1px solid; 11 | } 12 | 13 | /* header */ 14 | .tablesorter-grey th, 15 | .tablesorter-grey thead td { 16 | font: bold 12px/18px Arial, Sans-serif; 17 | color: #c8c8c8; 18 | background-color: #3c3c3c; 19 | background-image: -moz-linear-gradient(top, #555, #3c3c3c); 20 | background-image: -ms-linear-gradient(top, #555, #3c3c3c); 21 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#555), to(#3c3c3c)); 22 | background-image: -webkit-linear-gradient(top, #555, #3c3c3c); 23 | background-image: -o-linear-gradient(top, #555, #3c3c3c); 24 | background-image: linear-gradient(to bottom, #555,#3c3c3c); 25 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#555555', endColorstr='#3c3c3c',GradientType=0 ); 26 | background-repeat: repeat-x; 27 | border-right: #555 1px solid; 28 | text-shadow: 0 1px 0 rgba(128, 128, 128, 0.7); 29 | -webkit-box-shadow: inset 0 1px 0 #222; 30 | -moz-box-shadow: inset 0 1px 0 #222; 31 | box-shadow: inset 0 1px 0 #222; 32 | padding: 4px; 33 | } 34 | .tablesorter-grey .tablesorter-header-inner, 35 | .tablesorter-grey .tablesorter-header-inner { 36 | position: relative; 37 | padding: 4px 15px 4px 4px; 38 | } 39 | .tablesorter-grey .header i, 40 | .tablesorter-grey .tablesorter-header i { 41 | width: 18px; 42 | height: 10px; 43 | position: absolute; 44 | right: 2px; 45 | top: 50%; 46 | margin-top: -10px; 47 | /* white (unsorted) double arrow */ 48 | background-image: url(data:image/gif;base64,R0lGODlhFQAJAIAAAP///////yH5BAEAAAEALAAAAAAVAAkAAAIXjI+AywnaYnhUMoqt3gZXPmVg94yJVQAAOw==); 49 | background-repeat: no-repeat; 50 | background-position: center right; 51 | padding: 4px; 52 | white-space: normal; 53 | cursor: pointer; 54 | } 55 | .tablesorter-grey th.headerSortUp, 56 | .tablesorter-grey th.tablesorter-headerSortUp, 57 | .tablesorter-grey th.headerSortDown, 58 | .tablesorter-grey th.tablesorter-headerSortDown { 59 | color: #ddd; 60 | background-color: #135185; 61 | background-image: -moz-linear-gradient(top, #195c93, #0e4776); 62 | background-image: -ms-linear-gradient(top, #195c93, #0e4776); 63 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#195c93), to(#0e4776)); 64 | background-image: -webkit-linear-gradient(top, #195c93, #0e4776); 65 | background-image: -o-linear-gradient(top, #195c93, #0e4776); 66 | background-image: linear-gradient(to bottom, #195c93, #0e4776); 67 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#195c93', endColorstr='#0e4776',GradientType=0 ); 68 | } 69 | .tablesorter-grey .headerSortUp i, 70 | .tablesorter-grey .tablesorter-headerSortUp i, 71 | .tablesorter-grey .tablesorter-headerAsc i { 72 | /* white asc arrow */ 73 | background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7); 74 | } 75 | .tablesorter-grey .headerSortDown i, 76 | .tablesorter-grey .tablesorter-headerSortDown i, 77 | .tablesorter-grey .tablesorter-headerDesc i { 78 | /* white desc arrow */ 79 | background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7); 80 | } 81 | .tablesorter-grey thead .sorter-false i { 82 | background-image: none; 83 | padding: 4px; 84 | } 85 | 86 | /* tfoot */ 87 | .tablesorter-grey tbody td, 88 | .tablesorter-grey tfoot th, 89 | .tablesorter-grey tfoot td { 90 | padding: 4px; 91 | vertical-align: top; 92 | border-right: #555 1px solid; 93 | } 94 | .tablesorter-grey tfoot th, 95 | .tablesorter-grey tfoot td { 96 | padding: 8px; 97 | } 98 | 99 | /* tbody */ 100 | .tablesorter-grey td { 101 | color: #eee; 102 | background-color: #6d6d6d; 103 | padding: 4px; 104 | vertical-align: top; 105 | } 106 | 107 | /* hovered row colors 108 | you'll need to add additional lines for 109 | rows with more than 2 child rows 110 | */ 111 | .tablesorter-grey tbody > tr:hover > td, 112 | .tablesorter-grey tbody > tr:hover + tr.tablesorter-childRow > td, 113 | .tablesorter-grey tbody > tr:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td, 114 | .tablesorter-grey tbody > tr.even:hover > td, 115 | .tablesorter-grey tbody > tr.even:hover + tr.tablesorter-childRow > td, 116 | .tablesorter-grey tbody > tr.even:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td { 117 | background: #134b78; 118 | } 119 | .tablesorter-grey tbody > tr.odd:hover > td, 120 | .tablesorter-grey tbody > tr.odd:hover + tr.tablesorter-childRow > td, 121 | .tablesorter-grey tbody > tr.odd:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td { 122 | background: #134b78; 123 | } 124 | 125 | /* table processing indicator */ 126 | .tablesorter-grey .tablesorter-processing { 127 | background-position: center center !important; 128 | background-repeat: no-repeat !important; 129 | /* background-image: url(../addons/pager/icons/loading.gif) !important; */ 130 | background-image: url('data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=') !important; 131 | } 132 | 133 | /* Zebra Widget - row alternating colors */ 134 | .tablesorter-grey tbody tr.odd td { 135 | background-color: #5e5e5e; 136 | } 137 | .tablesorter-grey tbody tr.even td { 138 | background-color: #6d6d6d; 139 | } 140 | 141 | /* Column Widget - column sort colors */ 142 | .tablesorter-grey td.primary, 143 | .tablesorter-grey tr.odd td.primary { 144 | color: #ddd; 145 | background-color: #165388; 146 | } 147 | .tablesorter-grey tr.even td.primary { 148 | color: #ddd; 149 | background-color: #195c93; 150 | } 151 | .tablesorter-grey td.secondary, 152 | .tablesorter-grey tr.odd td.secondary { 153 | color: #ddd; 154 | background-color: #185C9A; 155 | } 156 | .tablesorter-grey tr.even td.secondary { 157 | color: #ddd; 158 | background-color: #1D67A5; 159 | } 160 | .tablesorter-grey td.tertiary, 161 | .tablesorter-grey tr.odd td.tertiary { 162 | color: #ddd; 163 | background-color: #1B67AD; 164 | } 165 | .tablesorter-grey tr.even td.tertiary { 166 | color: #ddd; 167 | background-color: #2073B7; 168 | } 169 | 170 | /* caption */ 171 | caption { 172 | background: #fff; 173 | } 174 | 175 | /* filter widget */ 176 | .tablesorter-grey .tablesorter-filter-row td { 177 | background: #3c3c3c; 178 | line-height: normal; 179 | text-align: center; /* center the input */ 180 | -webkit-transition: line-height 0.1s ease; 181 | -moz-transition: line-height 0.1s ease; 182 | -o-transition: line-height 0.1s ease; 183 | transition: line-height 0.1s ease; 184 | } 185 | /* optional disabled input styling */ 186 | .tablesorter-grey .tablesorter-filter-row .disabled { 187 | opacity: 0.5; 188 | filter: alpha(opacity=50); 189 | cursor: not-allowed; 190 | } 191 | /* hidden filter row */ 192 | .tablesorter-grey .tablesorter-filter-row.hideme td { 193 | /*** *********************************************** ***/ 194 | /*** change this padding to modify the thickness ***/ 195 | /*** of the closed filter row (height = padding x 2) ***/ 196 | padding: 2px; 197 | /*** *********************************************** ***/ 198 | margin: 0; 199 | line-height: 0; 200 | cursor: pointer; 201 | } 202 | .tablesorter-grey .tablesorter-filter-row.hideme .tablesorter-filter { 203 | height: 1px; 204 | min-height: 0; 205 | border: 0; 206 | padding: 0; 207 | margin: 0; 208 | /* don't use visibility: hidden because it disables tabbing */ 209 | opacity: 0; 210 | filter: alpha(opacity=0); 211 | } 212 | /* filters */ 213 | .tablesorter-grey .tablesorter-filter { 214 | width: 98%; 215 | height: auto; 216 | margin: 0; 217 | padding: 4px; 218 | background-color: #6d6d6d; 219 | border: 1px solid #555; 220 | color: #ddd; 221 | -webkit-box-sizing: border-box; 222 | -moz-box-sizing: border-box; 223 | box-sizing: border-box; 224 | -webkit-transition: height 0.1s ease; 225 | -moz-transition: height 0.1s ease; 226 | -o-transition: height 0.1s ease; 227 | transition: height 0.1s ease; 228 | } 229 | 230 | /* ajax error row */ 231 | .tablesorter .tablesorter-errorRow td { 232 | cursor: pointer; 233 | background-color: #e6bf99; 234 | } 235 | -------------------------------------------------------------------------------- /jquery_tablesorter/static/js/tablesorter/widgets/widget-scroller.js: -------------------------------------------------------------------------------- 1 | /*! 2 | Copyright (C) 2011 T. Connell & Associates, Inc. 3 | 4 | Dual-licensed under the MIT and GPL licenses 5 | 6 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 7 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE 8 | FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 9 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | 11 | Resizable scroller widget for the jQuery tablesorter plugin 12 | 13 | Version 2.0 - modified by Rob Garrison (4/12/2013) 14 | Requires jQuery, v1.2.3 or higher 15 | Requires the tablesorter plugin, v2.0 or higher, available at http://mottie.github.com/tablesorter/docs/ 16 | 17 | Usage: 18 | 19 | $(function() { 20 | 21 | $('table.tablesorter').tablesorter({ 22 | widgets: ['zebra', 'scroller'], 23 | widgetOptions : { 24 | scroller_height : 300, // height of scroll window 25 | scroller_barWidth : 17, // scroll bar width 26 | scroller_jumpToHeader : true, // header snap to browser top when scrolling the tbody 27 | scroller_idPrefix : 's_' // cloned thead id prefix (random number added to end) 28 | } 29 | }); 30 | 31 | }); 32 | 33 | Website: www.tconnell.com 34 | */ 35 | /*jshint browser:true, jquery:true, unused:false */ 36 | ;(function($){ 37 | "use strict"; 38 | 39 | $.fn.hasScrollBar = function(){ 40 | return this.get(0).scrollHeight > this.height(); 41 | }; 42 | var ts = $.tablesorter; 43 | 44 | ts.window_resize = function(){ 45 | if (this.resize_timer) { 46 | clearTimeout(this.resize_timer); 47 | } 48 | this.resize_timer = setTimeout(function(){ 49 | $(this).trigger('resizeEnd'); 50 | }, 250); 51 | }; 52 | 53 | // Add extra scroller css 54 | $(function(){ 55 | var s = ''; 62 | $(s).appendTo('body'); 63 | }); 64 | 65 | ts.addWidget({ 66 | id: 'scroller', 67 | priority: 60, // run after the filter widget 68 | options: { 69 | scroller_height : 300, 70 | scroller_barWidth : 17, 71 | scroller_jumpToHeader: true, 72 | scroller_idPrefix : 's_' 73 | }, 74 | init: function(table, thisWidget, c, wo){ 75 | var $win = $(window); 76 | //Setup window.resizeEnd event 77 | $win 78 | .bind('resize', ts.window_resize) 79 | .bind('resizeEnd', function(e) { 80 | // init is run before format, so scroller_resizeWidth 81 | // won't be defined within the "c" or "wo" parameters 82 | if (typeof table.config.widgetOptions.scroller_resizeWidth === 'function') { 83 | //IE calls resize when you modify content, so we have to unbind the resize event 84 | //so we don't end up with an infinite loop. we can rebind after we're done. 85 | $win.unbind('resize', ts.window_resize); 86 | table.config.widgetOptions.scroller_resizeWidth(); 87 | $win.bind('resize', ts.window_resize); 88 | } 89 | }); 90 | }, 91 | format: function(table, c, wo) { 92 | var h, $hdr, id, t, resize, $cells, 93 | $win = $(window), 94 | $tbl = c.$table, 95 | flag = false, 96 | filterInputs = 'input, select'; 97 | 98 | if (!c.isScrolling) { 99 | h = wo.scroller_height || 300; 100 | t = $tbl.find('tbody').height(); 101 | if (t !== 0 && h > t) { h = t + 10; } // Table is less than h px 102 | id = wo.scroller_id = wo.scroller_idPrefix + Math.floor(Math.random() * 101); 103 | 104 | $hdr = $('' + $tbl.find('thead:first').html() + '
'); 105 | $tbl 106 | .wrap('
') 107 | .before($hdr) 108 | .find('.tablesorter-filter-row').addClass('hideme'); 109 | 110 | $cells = $hdr 111 | .wrap('
') 112 | .find('.' + ts.css.header) 113 | .bind('mousedown', function(){ 114 | this.onselectstart = function(){ return false; }; 115 | return false; 116 | }); 117 | 118 | $tbl 119 | .wrap('
') 120 | .unbind('sortEnd.tsScroller') 121 | .bind('sortEnd.tsScroller', function(){ 122 | c.$headers.each(function(i){ 123 | var t = $cells.eq(i); 124 | t 125 | .attr('class', $(this).attr('class')) 126 | // remove processing icon 127 | .removeClass(ts.css.processing + ' ' + c.cssProcessing); 128 | if (ts.css.icon){ 129 | t 130 | .find('.' + ts.css.icon) 131 | .attr('class', $(this).find('.' + ts.css.icon).attr('class')); 132 | } 133 | }); 134 | }); 135 | 136 | // make scroller header sortable 137 | c.$headers.find(c.selectorSort).add( c.$headers.filter(c.selectorSort) ).each(function(i){ 138 | var t = $(this); 139 | $cells.eq(i) 140 | // clicking on new header will trigger a sort 141 | .bind('mouseup', function(e){ 142 | t.trigger(e, true); // external mouseup flag (click timer is ignored) 143 | }) 144 | // prevent header text selection 145 | .bind('mousedown', function(){ 146 | this.onselectstart = function(){ return false; }; 147 | return false; 148 | }); 149 | }); 150 | 151 | // look for filter widget 152 | $tbl.bind('filterEnd', function(){ 153 | if (flag) { return; } 154 | $cells.each(function(i){ 155 | $(this).find(filterInputs).val( c.$filters.find(filterInputs).eq(i).val() ); 156 | }); 157 | }); 158 | $hdr.find(filterInputs).bind('keyup search', function(e){ 159 | // ignore arrow and meta keys; allow backspace 160 | if ((e.which < 32 && e.which !== 8) || (e.which >= 37 && e.which <=40)) { return; } 161 | flag = true; 162 | var $f = $(this), col = $f.attr('data-column'); 163 | c.$filters.find(filterInputs).eq(col) 164 | .val( $f.val() ) 165 | .trigger('search'); 166 | setTimeout(function(){ 167 | flag = false; 168 | }, wo.filter_searchDelay); 169 | }); 170 | 171 | resize = function(){ 172 | var d, 173 | //Hide other scrollers so we can resize 174 | $div = $('div.scroller[id != "' + id + '"]').hide(); 175 | 176 | $tbl.find('thead').show(); 177 | 178 | //Reset sizes so parent can resize. 179 | $hdr 180 | .width(0) 181 | .parent().width(0) 182 | .find('th,td').width(0); 183 | 184 | $tbl 185 | .width(0) 186 | .find('thead').find('th,td').width(0); 187 | d = $tbl.parent(); 188 | d.width(0); 189 | 190 | d.parent().trigger('resize'); 191 | // Shrink a bit to accommodate scrollbar 192 | d.width( d.parent().innerWidth() - ( d.parent().hasScrollBar() ? wo.scroller_barWidth : 0 ) ); 193 | 194 | $tbl.width( d.innerWidth() - ( d.hasScrollBar() ? wo.scroller_barWidth : 0 ) ); 195 | $tbl.find('thead').find('th,td').filter(':visible').each(function(i, c){ 196 | var $th = $(c), 197 | //Wrap in browser detect?? 198 | w = parseInt( $th.css('min-width').replace('auto', '0').replace(/(px|em)/, ''), 10 ); 199 | if ( $th.width() < w ) { 200 | $th.width(w); 201 | } else { 202 | w = $th.width(); 203 | } 204 | $hdr.find('th,td').eq(i).width(w); 205 | }); 206 | 207 | $hdr.width($tbl.innerWidth()); 208 | $div.show(); 209 | }; 210 | 211 | //Expose to external calls 212 | wo.scroller_resizeWidth = resize; 213 | 214 | resize(); 215 | 216 | $tbl.find('thead').css('visibility', 'hidden'); 217 | c.isScrolling = true; 218 | 219 | t = $tbl.parent().parent().height(); 220 | // The header will always jump into view if scrolling the table body 221 | $tbl.parent().bind('scroll', function(){ 222 | if (wo.scroller_jumpToHeader) { 223 | var pos = $win.scrollTop() - $hdr.offset().top; 224 | if ($(this).scrollTop() !== 0 && pos < t && pos > 0) { 225 | $win.scrollTop( $hdr.offset().top ); 226 | } 227 | } 228 | }); 229 | 230 | } 231 | 232 | //Sorting, so scroll to top 233 | $tbl.parent().animate({ scrollTop: 0 }, 'fast'); 234 | 235 | }, 236 | remove : function(table, c, wo){ 237 | 238 | } 239 | }); 240 | 241 | })(jQuery); 242 | -------------------------------------------------------------------------------- /jquery_tablesorter/static/css/tablesorter/theme.green.css: -------------------------------------------------------------------------------- 1 | /************* 2 | Green Theme 3 | *************/ 4 | /* overall */ 5 | .tablesorter-green { 6 | width: 100%; 7 | text-align: left; 8 | border-spacing: 0; 9 | } 10 | .tablesorter-green, 11 | .tablesorter-green th, 12 | .tablesorter-green td { 13 | font: 12px/18px Arial, Sans-serif; 14 | border: #cdcdcd 1px solid; 15 | border-spacing: 0; 16 | padding: 0; 17 | text-align: left; 18 | } 19 | 20 | /* header */ 21 | .tablesorter-green thead tr, 22 | .tablesorter-green tfoot tr { 23 | background: center center repeat-x; 24 | background-image: url(data:image/gif;base64,R0lGODlhAQBkAOYAAN/e39XU1fX19tTU1eXm5uTl5ePk5OLj4+Hi4vX29fT19PP08/Lz8vHy8fDx8O/w7+7v7uzt7Orr6ufo5/T08/Pz8ufn5uLi4eDg39/f3t3d3Nzc29HR0NDQz8/Pzuvq6urp6eno6Ojn5+fm5tfW1tbV1dTT09PS0tLR0dHQ0NDPz/f39/b29vX19fT09PPz8/Ly8vHx8e/v7+7u7u3t7ezs7Ovr6+rq6unp6ejo6Ofn5+bm5uXl5eTk5OPj4+Li4uHh4eDg4N/f397e3t3d3dzc3Nvb29ra2tnZ2djY2NfX19XV1dPT09LS0tHR0dDQ0M/Pz8rKysXFxf///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAFMALAAAAAABAGQAAAdegCsrLC0tLi+ILi6FCSwsCS0KkhQVDA0OMjM0NTYfICEiIzw9P0AYGUQaG0ZHSEoDTU9Qs08pTk1MSyRJR0VDQT8+PTw7Ojg3NTMyMTAvi4WOhC0vMTI1OT9GTlFSgQA7); 25 | /* background-image: url(images/green-header.gif); */ 26 | } 27 | .tablesorter-green th, 28 | .tablesorter-green thead td { 29 | font-weight: bold; 30 | border-right: #cdcdcd 1px solid; 31 | border-collapse: collapse; 32 | padding: 6px; 33 | } 34 | .tablesorter-green .header, 35 | .tablesorter-green .tablesorter-header { 36 | background: no-repeat 5px center; 37 | background-image: url(data:image/gif;base64,R0lGODlhEAAQAOYAAA5NDBBYDlWWUzRUM5DVjp7inJ/fnQ1ECiCsGhyYFxqKFRFdDhBXDQxCCiO8HSK2HCCqGh2aGByUFxuPFhqNFhmHFRZ2EhVvERRpEBBVDSS8HiGyHB+mGh6fGRuTFxiAFBd5Eww/Cgs5CRp7Fiu+JRx8GCy/JjHAKyynKCuhJzXCMDbCMDnDMyNuHz3EODy9N0LFPSl7JkvIRjycOFDKS1LKTVPLT1XLUFTCT17OWTBkLmbQYnDTbHXVcXnWdoXago/djGmUZ112XCJEIEdjRf///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAEUALAAAAAAQABAAAAdlgEWCg4SFhoIvh4cVLECKhCMeJjwFj0UlEwgaMD4Gii0WFAkRHQ47BIY6IQAZDAwBCyAPOJa1toRBGBAwNTY3OT0/AoZCDQoOKi4yNDOKRCIfGycrKZYDBxIkKLZDFxy3RTHgloEAOw==); 38 | /* background-image: url(images/green-unsorted.gif); */ 39 | border-collapse: collapse; 40 | white-space: normal; 41 | cursor: pointer; 42 | } 43 | .tablesorter-green thead .headerSortUp, 44 | .tablesorter-green thead .tablesorter-headerSortUp, 45 | .tablesorter-green thead .tablesorter-headerAsc { 46 | background-image: url(data:image/gif;base64,R0lGODlhEAAQANUAAA5NDBBYDpDVjp7inJ/fnSCsGhyYFxFdDhBXDSO8HSK2HB2aGBuPFhqNFhmHFRZ2EhBVDSS8Hh6fGRuTFxd5Eww/Chp7Fhx8GCy/JjnDMyNuHzy9N0LFPVTCTzBkLmbQYnDTbHnWdo/djP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAACMALAAAAAAQABAAAAY4wJFwSCwaj8ikcslMbpojR0bEtEwwoIHywihEOCECUvNoGBaSxEdg9FQAEAQicKAoOtC8fs8fBgEAOw==) 47 | /* background-image: url(images/green-asc.gif); */ 48 | } 49 | .tablesorter-green thead .headerSortDown, 50 | .tablesorter-green thead .tablesorter-headerSortDown, 51 | .tablesorter-green thead .tablesorter-headerDesc { 52 | background-image: url(data:image/gif;base64,R0lGODlhEAAQANUAAFWWUzRUMw1EChqKFQxCCiO8HSCqGhyUFxVvERRpECGyHB+mGhiAFAs5CSu+JTHAKyynKCuhJzXCMDbCMD3EOELFPSl7JkvIRjycOFDKS1LKTVPLT1XLUF7OWXXVcYXagmmUZ112XCJEIEdjRf///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAACQALAAAAAAQABAAAAY4QJJwSCwaj8ikcskkghKGimbD6Xg+AGOIMChIKJcMBjlqMBSPSUQZEBwcEKYIsWiSLPa8fs9HBgEAOw==) 53 | /* background-image: url(images/green-desc.gif); */ 54 | } 55 | .tablesorter-green th.tablesorter-header .tablesorter-header-inner, 56 | .tablesorter-green td.tablesorter-header .tablesorter-header-inner { 57 | padding-left: 23px; 58 | } 59 | .tablesorter-green thead .tablesorter-header.sorter-false { 60 | background-image: none; 61 | padding: 4px; 62 | } 63 | 64 | /* tfoot */ 65 | .tablesorter-green tbody td, 66 | .tablesorter-green tfoot th { 67 | padding: 6px; 68 | vertical-align: top; 69 | } 70 | 71 | /* tbody */ 72 | .tablesorter-green td { 73 | color: #3d3d3d; 74 | padding: 6px; 75 | } 76 | 77 | /* hovered row colors 78 | you'll need to add additional lines for 79 | rows with more than 2 child rows 80 | */ 81 | .tablesorter-green tbody > tr:hover > td, 82 | .tablesorter-green tbody > tr:hover + tr.tablesorter-childRow > td, 83 | .tablesorter-green tbody > tr:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td, 84 | .tablesorter-green tbody > tr.even:hover > td, 85 | .tablesorter-green tbody > tr.even:hover + tr.tablesorter-childRow > td, 86 | .tablesorter-green tbody > tr.even:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td { 87 | background: #d9d9d9; 88 | } 89 | .tablesorter-green tbody > tr.odd:hover > td, 90 | .tablesorter-green tbody > tr.odd:hover + tr.tablesorter-childRow > td, 91 | .tablesorter-green tbody > tr.odd:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td { 92 | background: #bfbfbf; 93 | } 94 | 95 | /* table processing indicator */ 96 | .tablesorter-green .tablesorter-processing { 97 | background-position: center center !important; 98 | background-repeat: no-repeat !important; 99 | /* background-image: url(../addons/pager/icons/loading.gif) !important; */ 100 | background-image: url('data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=') !important; 101 | } 102 | 103 | /* Zebra Widget - row alternating colors */ 104 | .tablesorter-green tr.odd td { 105 | background-color: #ebfaeb; 106 | } 107 | .tablesorter-green tr.even td { 108 | background-color: #fff; 109 | } 110 | 111 | /* Column Widget - column sort colors */ 112 | .tablesorter-green td.primary, 113 | .tablesorter-green tr.odd td.primary { 114 | background-color: #99e6a6; 115 | } 116 | .tablesorter-green tr.even td.primary { 117 | background-color: #c2f0c9; 118 | } 119 | .tablesorter-green td.secondary, 120 | .tablesorter-green tr.odd td.secondary { 121 | background-color: #c2f0c9; 122 | } 123 | .tablesorter-green tr.even td.secondary { 124 | background-color: #d6f5db; 125 | } 126 | .tablesorter-green td.tertiary, 127 | .tablesorter-green tr.odd td.tertiary { 128 | background-color: #d6f5db; 129 | } 130 | .tablesorter-green tr.even td.tertiary { 131 | background-color: #ebfaed; 132 | } 133 | 134 | /* caption */ 135 | caption { 136 | background: #fff; 137 | } 138 | 139 | /* filter widget */ 140 | .tablesorter-green .tablesorter-filter-row td { 141 | background: #eee; 142 | line-height: normal; 143 | text-align: center; /* center the input */ 144 | -webkit-transition: line-height 0.1s ease; 145 | -moz-transition: line-height 0.1s ease; 146 | -o-transition: line-height 0.1s ease; 147 | transition: line-height 0.1s ease; 148 | } 149 | /* optional disabled input styling */ 150 | .tablesorter-green .tablesorter-filter-row .disabled { 151 | opacity: 0.5; 152 | filter: alpha(opacity=50); 153 | cursor: not-allowed; 154 | } 155 | /* hidden filter row */ 156 | .tablesorter-green .tablesorter-filter-row.hideme td { 157 | /*** *********************************************** ***/ 158 | /*** change this padding to modify the thickness ***/ 159 | /*** of the closed filter row (height = padding x 2) ***/ 160 | padding: 2px; 161 | /*** *********************************************** ***/ 162 | margin: 0; 163 | line-height: 0; 164 | cursor: pointer; 165 | } 166 | .tablesorter-green .tablesorter-filter-row.hideme .tablesorter-filter { 167 | height: 1px; 168 | min-height: 0; 169 | border: 0; 170 | padding: 0; 171 | margin: 0; 172 | /* don't use visibility: hidden because it disables tabbing */ 173 | opacity: 0; 174 | filter: alpha(opacity=0); 175 | } 176 | /* filters */ 177 | .tablesorter-green .tablesorter-filter { 178 | width: 98%; 179 | height: auto; 180 | margin: 4px; 181 | padding: 4px; 182 | background-color: #fff; 183 | border: 1px solid #bbb; 184 | color: #333; 185 | -webkit-box-sizing: border-box; 186 | -moz-box-sizing: border-box; 187 | box-sizing: border-box; 188 | -webkit-transition: height 0.1s ease; 189 | -moz-transition: height 0.1s ease; 190 | -o-transition: height 0.1s ease; 191 | transition: height 0.1s ease; 192 | } 193 | 194 | /* ajax error row */ 195 | .tablesorter .tablesorter-errorRow td { 196 | cursor: pointer; 197 | background-color: #e6bf99; 198 | } 199 | -------------------------------------------------------------------------------- /jquery_tablesorter/static/js/tablesorter/addons/pager/jquery.tablesorter.pager.min.js: -------------------------------------------------------------------------------- 1 | /*! tablesorter pager plugin minified - updated 10/18/2013 */ 2 | ;(function(g){var l=g.tablesorter;g.extend({tablesorterPager:new function(){this.defaults={container:null,ajaxUrl:null,customAjaxUrl:function(b,a){return a},ajaxObject:{dataType:"json"},ajaxProcessing:function(b){return[0,[],null]},output:"{startRow} to {endRow} of {totalRows} rows",updateArrows:!0,page:0,size:10,savePages:!0,fixedHeight:!1,removeRows:!1,cssFirst:".first",cssPrev:".prev",cssNext:".next",cssLast:".last",cssGoto:".gotoPage",cssPageDisplay:".pagedisplay",cssPageSize:".pagesize",cssErrorRow:"tablesorter-errorRow", cssDisabled:"disabled",totalRows:0,totalPages:0,filteredRows:0,filteredPages:0,currentFilters:[],startRow:0,endRow:0,$size:null,last:{}};var w=this,x=function(b,a){var c=b.cssDisabled,f=!!a,e=Math.min(b.totalPages,b.filteredPages);b.updateArrows&&(b.$container.find(b.cssFirst+","+b.cssPrev)[f||0===b.page?"addClass":"removeClass"](c),b.$container.find(b.cssNext+","+b.cssLast)[f||b.page===e-1?"addClass":"removeClass"](c))},r=function(b,a,c){var f,e,h,d=b.config;f=d.$table.hasClass("hasFilters")&&!a.ajaxUrl; h=(d.widgetOptions&&d.widgetOptions.filter_filteredRow||"filtered")+","+d.selectorRemove;e=a.size||10;a.totalPages=Math.ceil(a.totalRows/e);a.filteredRows=f?d.$tbodies.eq(0).children("tr:not(."+h+")").length:a.totalRows;a.filteredPages=f?Math.ceil(a.filteredRows/e)||1:a.totalPages;if(0<=Math.min(a.totalPages,a.filteredPages)&&(h=a.size*a.page>a.filteredRows,a.startRow=h?1:0===a.filteredRows?0:a.size*a.page+1,a.page=h?0:a.page,a.endRow=Math.min(a.filteredRows,a.totalRows,a.size*(a.page+1)),f=a.$container.find(a.cssPageDisplay), h=(a.ajaxData&&a.ajaxData.output?a.ajaxData.output||a.output:a.output).replace(/\{page([\-+]\d+)?\}/gi,function(b,c){return a.page+(c?parseInt(c,10):1)}).replace(/\{\w+(\s*:\s*\w+)?\}/gi,function(b){b=b.replace(/[{}\s]/g,"");var c=b.split(":"),d=a.ajaxData;return 1"+f+"";a.$goto.html(h).val(a.page+ 1)}x(a);a.initialized&&!1!==c&&(d.$table.trigger("pagerComplete",a),a.savePages&&l.storage&&l.storage(b,"tablesorter-pager",{page:a.page,size:a.size}))},t=function(b,a){var c,f=b.config,e=f.$tbodies.eq(0);a.fixedHeight&&(e.find("tr.pagerSavedHeightSpacer").remove(),c=g.data(b,"pagerSavedHeight"))&&(c-=e.height(),5'))},A=function(b,a){var c=b.config.$tbodies.eq(0);c.find("tr.pagerSavedHeightSpacer").remove();g.data(b,"pagerSavedHeight",c.height());t(b,a);g.data(b,"pagerLastSize",a.size)},u=function(b,a){if(!a.ajaxUrl){var c,f=b.config,e=f.$tbodies.eq(0).children(),h=e.length,d=a.page*a.size,g=d+a.size,n=f.widgetOptions&&f.widgetOptions.filter_filteredRow||"filtered",m=0;for(c=0;c=d&&m'+(0===f.status?"Not connected, verify Network": 404===f.status?"Requested page not found [404]":500===f.status?"Internal Server Error [500]":"parsererror"===e?"Requested JSON parse failed":"timeout"===e?"Time out error":"abort"===e?"Ajax Request aborted":"Uncaught error: "+f.statusText+" ["+f.status+"]")+"").click(function(){g(this).remove()}).appendTo(p.find("thead:first")),k.$tbodies.eq(0).empty();else{g.isArray(h)?(f=isNaN(h[0])&&!isNaN(h[1]),e=h[f?1:0],c.totalRows=isNaN(e)?c.totalRows||0:e,f=h[f?0:1]||[],m=h[2]):(c.ajaxData=h,c.totalRows= h.total,m=h.headers,f=h.rows);v=f.length;if(f instanceof jQuery)k.$tbodies.eq(0).empty().append(f);else if(v){if(0";for(e=0;e"+f[h][e]+"";q+=""}k.$tbodies.eq(0).html(q)}m&&m.length===b&&(n=(d=p.hasClass("hasStickyHeaders"))?k.$sticky.children("thead:first").children().children():"",s=p.find("tfoot tr:first").children(),k.$headers.filter("th").each(function(a){var b=g(this),c;b.find("."+l.css.icon).length?(c=b.find("."+l.css.icon).clone(!0), b.find(".tablesorter-header-inner").html(m[a]).append(c),d&&n.length&&(c=n.eq(a).find("."+l.css.icon).clone(!0),n.eq(a).find(".tablesorter-header-inner").html(m[a]).append(c))):(b.find(".tablesorter-header-inner").html(m[a]),d&&n.length&&n.eq(a).find(".tablesorter-header-inner").html(m[a]));s.eq(a).html(m[a])}))}k.showProcessing&&l.isProcessing(a);c.totalPages=Math.ceil(c.totalRows/(c.size||10));r(a,c);t(a,c);c.initialized?(p.trigger("pagerChange",c),p.trigger("updateComplete")):p.trigger("update")}c.initialized|| (c.initialized=!0,g(a).trigger("pagerInitialized",c))},H=function(b,a){var c=G(b,a),f=g(document),e=b.config;""!==c&&(e.showProcessing&&l.isProcessing(b,!0),f.bind("ajaxError.pager",function(c,d,e,g){C(null,b,a,d,g);f.unbind("ajaxError.pager")}),a.ajaxObject.url=c,a.ajaxObject.success=function(c){C(c,b,a);f.unbind("ajaxError.pager");"function"===typeof a.oldAjaxSuccess&&a.oldAjaxSuccess(c)},g.ajax(a.ajaxObject))},G=function(b,a){var c=a.ajaxUrl?a.ajaxUrl.replace(/\{page([\-+]\d+)?\}/,function(c,b){return a.page+ (b?parseInt(b,10):0)}).replace(/\{size\}/g,a.size):"",f=b.config.sortList,e=a.currentFilters||[],h=c.match(/\{\s*sort(?:List)?\s*:\s*(\w*)\s*\}/),d=c.match(/\{\s*filter(?:List)?\s*:\s*(\w*)\s*\}/),k=[];h&&(h=h[1],g.each(f,function(a,b){k.push(h+"["+b[0]+"]="+b[1])}),c=c.replace(/\{\s*sort(?:List)?\s*:\s*(\w*)\s*\}/g,k.length?k.join("&"):h),k=[]);d&&(d=d[1],g.each(e,function(a,b){b&&k.push(d+"["+a+"]="+encodeURIComponent(b))}),c=c.replace(/\{\s*filter(?:List)?\s*:\s*(\w*)\s*\}/g,k.length?k.join("&"): d));"function"===typeof a.customAjaxUrl&&(c=a.customAjaxUrl(b,c));return c},y=function(b,a,c){var f,e;f=c.page*c.size;var h=f+c.size;if(!(1>(a&&a.length||0))){c.page>=c.totalPages&&D(b,c);c.isDisabled=!1;c.initialized&&g(b).trigger("pagerChange",c);if(c.removeRows){h>a.length&&(h=a.length);l.clearTableBody(b);for(e=l.processTbody(b,b.config.$tbodies.eq(0),!0);fa.page&&(a.page=0);a.page>e-1&&0!==e&&(a.page=e-1);if(f.page!==a.page||f.size!==a.size|| f.total!==a.totalPages||f.filters!==a.currentFilters)a.last={page:a.page,size:a.size,totalPages:a.totalPages,currentFilters:a.currentFilters},a.ajax?H(b,a):a.ajax||y(b,b.config.rowsCopy,a),g.data(b,"pagerLastPage",a.page),g.data(b,"pagerUpdateTriggered",!0),a.initialized&&!1!==c&&g(b).trigger("pageMoved",a)}},z=function(b,a,c){c.size=a;c.$size.val(a);g.data(b,"pagerLastPage",c.page);g.data(b,"pagerLastSize",c.size);c.totalPages=Math.ceil(c.totalRows/(c.size||10));k(b,c)},I=function(b,a){a.page=0; k(b,a)},D=function(b,a){a.page=Math.min(a.totalPages,a.filteredPages)-1;k(b,a)},J=function(b,a){a.page++;a.page>=Math.min(a.totalPages,a.filteredPages)-1&&(a.page=Math.min(a.totalPages,a.filteredPages)-1);k(b,a)},K=function(b,a){a.page--;0>=a.page&&(a.page=0);k(b,a)},F=function(b,a,c){var f=a.$size.removeClass(a.cssDisabled).removeAttr("disabled");a.$goto.removeClass(a.cssDisabled).removeAttr("disabled");a.isDisabled=!1;a.page=g.data(b,"pagerLastPage")||a.page||0;a.size=g.data(b,"pagerLastSize")|| parseInt(f.find("option[selected]").val(),10)||a.size;f.val(a.size);a.totalPages=Math.ceil(Math.min(a.totalPages,a.filteredPages)/(a.size||10));c&&(g(b).trigger("update"),z(b,a.size,a),B(b,a),t(b,a))};w.appender=function(b,a){var c=b.config.pager;c.ajax||(b.config.rowsCopy=a,c.totalRows=a.length,c.size=g.data(b,"pagerLastSize")||c.size,c.totalPages=Math.ceil(c.totalRows/(c.size||10)),y(b,a,c))};w.construct=function(b){return this.each(function(){if(this.config&&this.hasInitialized){var a,c,f,e=this, h=e.config,d=h.pager=g.extend({},g.tablesorterPager.defaults,b),s=h.$table,n=d.$container=g(d.container).addClass("tablesorter-pager").show();d.oldAjaxSuccess=d.oldAjaxSuccess||d.ajaxObject.success;h.appender=w.appender;d.savePages&&l.storage&&(a=l.storage(e,"tablesorter-pager")||{},d.page=isNaN(a.page)?d.page:a.page,d.size=(isNaN(a.size)?d.size:a.size)||10);s.unbind("filterStart.pager filterEnd.pager sortEnd.pager disable.pager enable.pager destroy.pager update.pager pageSize.pager").bind("filterStart.pager", function(a,b){g.data(e,"pagerUpdateTriggered",!1);d.currentFilters=b}).bind("filterEnd.pager sortEnd.pager",function(a){g.data(e,"pagerUpdateTriggered")?g.data(e,"pagerUpdateTriggered",!1):(("filterEnd"===a.type||"sortEnd"===a.type&&h.serverSideSorting)&&k(e,d,!1),r(e,d,!1),t(e,d))}).bind("disable.pager",function(a){a.stopPropagation();E(e,d)}).bind("enable.pager",function(a){a.stopPropagation();F(e,d,!0)}).bind("destroy.pager",function(a){a.stopPropagation();E(e,d);d.$container.hide();e.config.appender= null;d.initialized=!1;g(e).unbind("destroy.pager sortEnd.pager filterEnd.pager enable.pager disable.pager");l.storage&&l.storage(e,"tablesorter-pager","")}).bind("update.pager",function(a){a.stopPropagation();u(e,d)}).bind("pageSize.pager",function(a,b){a.stopPropagation();z(e,parseInt(b,10)||10,d);u(e,d);r(e,d,!1);d.$size.length&&d.$size.val(d.size)}).bind("pageSet.pager",function(a,b){a.stopPropagation();d.page=(parseInt(b,10)||1)-1;d.$goto.length&&d.$goto.val(d.size);k(e,d);r(e,d,!1)});c=[d.cssFirst, d.cssPrev,d.cssNext,d.cssLast];f=[I,K,J,D];n.find(c.join(",")).unbind("click.pager").bind("click.pager",function(a){var b=g(this),h=c.length;if(!b.hasClass(d.cssDisabled))for(a=0;a tr:hover td, 233 | tbody > tr:hover + tr.tablesorter-childRow > td, 234 | tbody > tr:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td, 235 | tbody > tr.even:hover > td, 236 | tbody > tr.even:hover + tr.tablesorter-childRow > td, 237 | tbody > tr.even:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td { 238 | .evenHovered; 239 | } 240 | tbody > tr.odd:hover > td, 241 | tbody > tr.odd:hover + tr.tablesorter-childRow > td, 242 | tbody > tr.odd:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td { 243 | .oddHovered; 244 | } 245 | 246 | /* table processing indicator - indeterminate spinner */ 247 | .tablesorter-processing { 248 | background-image: @processingIcon; 249 | background-position: center center; 250 | background-repeat: no-repeat; 251 | position: absolute; 252 | z-index: 1000; 253 | } 254 | 255 | /* Column Widget - column sort colors */ 256 | tr.odd td.primary { 257 | background-color: @primaryOdd; 258 | } 259 | td.primary, tr.even td.primary { 260 | background-color: @primaryEven; 261 | } 262 | tr.odd td.secondary { 263 | background-color: @secondaryOdd; 264 | } 265 | td.secondary, tr.even td.secondary { 266 | background-color: @secondaryEven; 267 | } 268 | tr.odd td.tertiary { 269 | background-color: @tertiaryOdd; 270 | } 271 | td.tertiary, tr.even td.tertiary { 272 | background-color: @tertiaryEven; 273 | } 274 | 275 | /* caption (non-theme matching) */ 276 | caption { 277 | background: @captionBackground ; 278 | } 279 | 280 | /* filter widget */ 281 | .tablesorter-filter-row input, 282 | .tablesorter-filter-row select{ 283 | width: 98%; 284 | height: auto; 285 | margin: 0; 286 | padding: @overallPadding; 287 | color: @filterElementTextColor; 288 | background: @filterElementBkgd; 289 | border: @filterElementBorder; 290 | -webkit-box-sizing: border-box; 291 | -moz-box-sizing: border-box; 292 | box-sizing: border-box; 293 | .filterWidgetTransition; 294 | } 295 | .tablesorter-filter-row td { 296 | text-align: center; 297 | background: @filterCellBackground; 298 | line-height: normal; 299 | text-align: center; /* center the input */ 300 | .filterWidgetTransition; 301 | } 302 | /* hidden filter row */ 303 | .tablesorter-filter-row.hideme td { 304 | padding: @filterRowHiddenHeight / 2; 305 | margin: 0; 306 | line-height: 0; 307 | cursor: pointer; 308 | } 309 | .tablesorter-filter-row.hideme .tablesorter-filter { 310 | height: 1px; 311 | min-height: 0; 312 | border: 0; 313 | padding: 0; 314 | margin: 0; 315 | /* don't use visibility: hidden because it disables tabbing */ 316 | opacity: 0; 317 | filter: alpha(opacity=0); 318 | } 319 | 320 | /* ajax error row */ 321 | .tablesorter-errorRow td { 322 | cursor: pointer; 323 | background-color: @errorBackground; 324 | } 325 | 326 | } 327 | -------------------------------------------------------------------------------- /jquery_tablesorter/static/js/tablesorter/jquery.tablesorter.widgets-filter-formatter.min.js: -------------------------------------------------------------------------------- 1 | /*! Filter widget formatter functions - updated 10/10/2013 2 | * requires: tableSorter 2.7.7+ and jQuery 1.4.3+ 3 | * jQuery UI spinner, silder, range slider & datepicker (range) 4 | * HTML5 number (spinner), range slider & color selector 5 | */ 6 | ;(function(k){k.tablesorter=k.tablesorter||{};k.tablesorter.filterFormatter={uiSpinner:function(b,e,h){var a=k.extend({min:0,max:100,step:1,value:1,delayed:!0,addToggle:!0,disabled:!1,exactMatch:!0,compare:""},h);h=k('').appendTo(b).bind("change.tsfilter",function(){c({value:this.value,delayed:!1})});var d=[],l=b.closest("table")[0].config,c=function(f){var g=!0,c,e=f&&f.value&&k.tablesorter.formatFloat((f.value+"").replace(/[><=]/g,""))||b.find(".spinner").val()|| a.value;a.addToggle&&(g=b.find(".toggle").is(":checked"));c=a.disabled||!g?"disable":"enable";b.find(".filter").val(g?(a.compare?a.compare:a.exactMatch?"=":"")+e:"").trigger("search",f&&"boolean"===typeof f.delayed?f.delayed:a.delayed).end().find(".spinner").spinner(c).val(e);d.length&&(d.find(".spinner").spinner(c).val(e),a.addToggle&&(d.find(".toggle")[0].checked=g))};a.oldcreate=a.create;a.oldspin=a.spin;a.create=function(b,g){c();"function"===typeof a.oldcreate&&a.oldcreate(b,g)};a.spin=function(b, g){c(g);"function"===typeof a.oldspin&&a.oldspin(b,g)};a.addToggle&&k('
').appendTo(b).find(".toggle").bind("change",function(){c()});b.closest("thead").find("th[data-column="+e+"]").addClass("filter-parsed");k('').val(a.value).appendTo(b).spinner(a).bind("change keyup",function(a){c()});l.$table.bind("stickyHeadersInit",function(){d= l.widgetOptions.$sticky.find(".tablesorter-filter-row").children().eq(e).empty();a.addToggle&&k('
').appendTo(d).find(".toggle").bind("change",function(){b.find(".toggle")[0].checked=this.checked;c()});k('').val(a.value).appendTo(d).spinner(a).bind("change keyup",function(a){b.find(".spinner").val(this.value);c()})}); l.$table.bind("filterReset",function(){a.addToggle&&(b.find(".toggle")[0].checked=!1);c()});c();return h},uiSlider:function(b,e,h){var a=k.extend({value:0,min:0,max:100,step:1,range:"min",delayed:!0,valueToHeader:!1,exactMatch:!0,compare:"",allText:"all"},h);h=k('').appendTo(b).bind("change.tsfilter",function(){c({value:this.value})});var d=[],l=b.closest("table")[0].config,c=function(f){var c="undefined"!==typeof f?k.tablesorter.formatFloat((f.value+"").replace(/[><=]/g, ""))||a.min:a.value,h=a.compare+(a.compare?c:c===a.min?a.allText:c);a.valueToHeader?b.closest("thead").find("th[data-column="+e+"]").find(".curvalue").html(" ("+h+")"):b.find(".ui-slider-handle").addClass("value-popup").attr("data-value",h);b.find(".filter").val(a.compare?a.compare+c:c===a.min?"":(a.exactMatch?"=":"")+c).trigger("search",f&&"boolean"===typeof f.delayed?f.delayed:a.delayed).end().find(".slider").slider("value",c);d.length&&(d.find(".slider").slider("value",c),a.valueToHeader?d.closest("thead").find("th[data-column="+ e+"]").find(".curvalue").html(" ("+h+")"):d.find(".ui-slider-handle").addClass("value-popup").attr("data-value",h))};b.closest("thead").find("th[data-column="+e+"]").addClass("filter-parsed");a.valueToHeader&&b.closest("thead").find("th[data-column="+e+"]").find(".tablesorter-header-inner").append('');a.oldcreate=a.create;a.oldslide=a.slide;a.create=function(b,d){c();"function"===typeof a.oldcreate&&a.oldcreate(b,d)};a.slide=function(b,d){c(d);"function"===typeof a.oldslide&& a.oldslide(b,d)};k('
').appendTo(b).slider(a);l.$table.bind("filterReset",function(){b.find(".slider").slider("value",a.value);c()});l.$table.bind("stickyHeadersInit",function(){d=l.widgetOptions.$sticky.find(".tablesorter-filter-row").children().eq(e).empty();k('
').val(a.value).appendTo(d).slider(a).bind("change keyup",function(a){b.find(".slider").val(this.value);c()})});return h},uiRange:function(b,e,h){var a=k.extend({values:[0, 100],min:0,max:100,range:!0,delayed:!0,valueToHeader:!1},h);h=k('').appendTo(b).bind("change.tsfilter",function(){var b=this.value.split(" - ");""===this.value&&(b=[a.min,a.max]);b&&b[1]&&c({values:b,delay:!1})});var d=[],l=b.closest("table")[0].config,c=function(c){var g=c&&c.values||a.values,h=g[0]+" - "+g[1],m=g[0]===a.min&&g[1]===a.max?"":h;a.valueToHeader?b.closest("thead").find("th[data-column="+e+"]").find(".currange").html(" ("+h+")"):b.find(".ui-slider-handle").addClass("value-popup").eq(0).attr("data-value", g[0]).end().eq(1).attr("data-value",g[1]);b.find(".filter").val(m).trigger("search",c&&"boolean"===typeof c.delayed?c.delayed:a.delayed).end().find(".range").slider("values",g);d.length&&(d.find(".range").slider("values",g),a.valueToHeader?d.closest("thead").find("th[data-column="+e+"]").find(".currange").html(" ("+h+")"):d.find(".ui-slider-handle").addClass("value-popup").eq(0).attr("data-value",g[0]).end().eq(1).attr("data-value",g[1]))};b.closest("thead").find("th[data-column="+e+"]").addClass("filter-parsed"); a.valueToHeader&&b.closest("thead").find("th[data-column="+e+"]").find(".tablesorter-header-inner").append('');a.oldcreate=a.create;a.oldslide=a.slide;a.create=function(b,d){c();"function"===typeof a.oldcreate&&a.oldcreate(b,d)};a.slide=function(b,d){c(d);"function"===typeof a.oldslide&&a.oldslide(b,d)};k('
').appendTo(b).slider(a);l.$table.bind("filterReset",function(){b.find(".range").slider("values",a.values);c()});l.$table.bind("stickyHeadersInit", function(){d=l.widgetOptions.$sticky.find(".tablesorter-filter-row").children().eq(e).empty();k('
').val(a.value).appendTo(d).slider(a).bind("change keyup",function(a){b.find(".range").val(this.value);c()})});return h},uiDateCompare:function(b,e,h){var a=k.extend({defaultDate:"",cellText:"",changeMonth:!0,changeYear:!0,numberOfMonths:1,compare:"",compareOptions:!1},h);h=b.closest("thead").find("th[data-column="+e+"]");var d=k('').appendTo(b).bind("change.tsfilter", function(){var b=this.value;if(b)a.onClose(b)}),l,c,f=[],g=b.closest("table")[0].config,n=function(c){var d=(new Date(b.find(".date").datepicker("getDate"))).getTime();b.find(".compare").val(c);b.find(".dateCompare").val(c+d).trigger("search",a.delayed).end();f.length&&f.find(".compare").val(c)};h.addClass("filter-parsed");if(a.compareOptions){c='"; b.append(c).find(".compare").bind("change",function(){n(k(this).val())})}else a.cellText&&(c="",b.append(c));l='';k(l).appendTo(b);a.oldonClose=a.onClose;a.onClose=function(c,d){var g=(new Date(b.find(".date").datepicker("getDate"))).getTime()||"",e=b.find(".compare").val()||a.compare;b.find(".dateCompare").val(e+g).trigger("search").end().find(".date").datepicker("setDate", c);f.length&&f.find(".date").datepicker("setDate",c);"function"===typeof a.oldonClose&&a.oldonClose(c,d)};b.find(".date").datepicker(a);a.filterDate&&b.find(".date").datepicker("setDate",a.filterDate);g.$table.bind("filterReset",function(){b.find(".date").val("").datepicker("option","currentText","");f.length&&f.find(".date").val("").datepicker("option","currentText","")});g.$table.bind("stickyHeadersInit",function(){f=g.widgetOptions.$sticky.find(".tablesorter-filter-row").children().eq(e).empty(); a.compareOptions?f.append(c).find(".compare").bind("change",function(){n(k(this).val())}):a.cellText&&f.append(c);f.append(l).find(".date").datepicker(a)});return d.val(a.defaultDate?a.defaultDate:"")},uiDatepicker:function(b,e,h){var a=k.extend({from:"",to:"",textFrom:"from",textTo:"to",changeMonth:!0,changeYear:!0,numberOfMonths:1},h),d,l,c,f=[];h=k('').appendTo(b).bind("change.tsfilter",function(){var a=this.value;a.match(" - ")?(a=a.split(" - "),b.find(".dateTo").val(a[1]), c(a[0])):a.match(">=")?c(a.replace(">=","")):a.match("<=")&&l(a.replace("<=",""))});var g=b.closest("table")[0].config;b.closest("thead").find("th[data-column="+e+"]").addClass("filter-parsed");d="';k(d).appendTo(b);a.oldonClose=a.onClose;var n=a.defaultDate=a.from||a.defaultDate;c=a.onClose=function(c,d){var g=(new Date(c)).getTime()||"",e=(new Date(b.find(".dateTo").datepicker("getDate"))).getTime()|| "",g=g?e?g+" - "+e:">="+g:e?"<="+e:"";b.find(".dateRange").val(g).trigger("search").end().find(".dateTo").datepicker("option","minDate",c).end().find(".dateFrom").val(c);f.length&&f.find(".dateTo").datepicker("option","minDate",c).end().find(".dateFrom").val(c);"function"===typeof a.oldonClose&&a.oldonClose(c,d)};b.find(".dateFrom").datepicker(a);a.defaultDate=a.to||"+7d";l=a.onClose=function(c,d){var g=(new Date(b.find(".dateFrom").datepicker("getDate"))).getTime()||"",e=(new Date(c)).getTime()|| "",g=g?e?g+" - "+e:">="+g:e?"<="+e:"";b.find(".dateRange").val(g).trigger("search").end().find(".dateFrom").datepicker("option","maxDate",c).end().find(".dateTo").val(c);f.length&&f.find(".dateFrom").datepicker("option","maxDate",c).end().find(".dateTo").val(c);"function"===typeof a.oldonClose&&a.oldonClose(c,d)};b.find(".dateTo").datepicker(a);g.$table.bind("stickyHeadersInit",function(){f=g.widgetOptions.$sticky.find(".tablesorter-filter-row").children().eq(e).empty();f.append(d);a.onClose=l;f.find(".dateTo").datepicker(a); a.defaultDate=n;a.onClose=c;f.find(".dateFrom").datepicker(a)});b.closest("table").bind("filterReset",function(){b.find(".dateFrom, .dateTo").val("").datepicker("option","currentText","");f.length&&f.find(".dateFrom, .dateTo").val("").datepicker("option","currentText","")});return h.val(a.from?a.to?a.from+" - "+a.to:">="+a.from:a.to?"<="+a.to:"")},html5Number:function(b,e,h){var a,d=k.extend({value:0,min:0,max:100,step:1,delayed:!0,disabled:!1,addToggle:!0,exactMatch:!0,compare:"",compareOptions:!1, skipTest:!1},h);h=k('').appendTo(b);var l=d.skipTest||"number"===h.attr("type")&&"test"!==h.val(),c,f=[],g=b.closest("table")[0].config,n=function(a){var c=b.find(".number").val();b.find(".compare").val(a);b.find("input[type=hidden]").val(a+c).trigger("search",d.delayed).end();f.length&&f.find(".compare").val(a)},m=function(a,c){var g=d.addToggle?b.find(".toggle").is(":checked"):!0,e=b.find(".compare").val()||d.compare;b.find("input[type=hidden]").val(!d.addToggle|| g?(d.compare?d.compare:d.exactMatch?"=":"")+a:"").val(!d.addToggle||g?e+a:"").trigger("search",c?c:d.delayed).end().find(".number").val(a);b.find(".number").length&&(b.find(".number")[0].disabled=d.disabled||!g);f.length&&(f.find(".number").val(a)[0].disabled=d.disabled||!g,d.addToggle&&(f.find(".toggle")[0].checked=g))};h.remove();l&&(c=d.addToggle?'
':"");if(d.compareOptions){c= '";b.append(c).find(".compare").bind("change",function(){n(k(this).val())})}else c&&b.append(c);l&&(a='',b.append(a+'').find(".toggle, .number").bind("change",function(){m(b.find(".number").val())}).closest("thead").find("th[data-column="+ e+"]").addClass("filter-parsed").closest("table").bind("filterReset",function(){d.addToggle&&(b.find(".toggle")[0].checked=!1,f.length&&(f.find(".toggle")[0].checked=!1));m(b.find(".number").val())}),g.$table.bind("stickyHeadersInit",function(){f=g.widgetOptions.$sticky.find(".tablesorter-filter-row").children().eq(e).empty();d.compareOptions?f.append(c).find(".compare").bind("change",function(){n(k(this).val())}):f.append(c);f.append(a).find(".toggle, .number").bind("change",function(){m(f.find(".number").val())}); m(b.find(".number").val())}),m(b.find(".number").val()));return l?b.find('input[type="hidden"]'):k('')},html5Range:function(b,e,h){var a=k.extend({value:0,min:0,max:100,step:1,delayed:!0,valueToHeader:!0,exactMatch:!0,compare:"",allText:"all",skipTest:!1},h);h=k('').appendTo(b);var d=a.skipTest||"range"===h.attr("type")&&"test"!==h.val(),l=[],c=b.closest("table")[0].config,f=function(c,d){c=(c+"").replace(/[<>=]/g,"")|| a.min;var f=" ("+(a.compare?a.compare+c:c==a.min?a.allText:c)+")";b.find("input[type=hidden]").val(a.compare?a.compare+c:c==a.min?"":(a.exactMatch?"=":"")+c).trigger("search",d?d:a.delayed).end().find(".range").val(c);b.closest("thead").find("th[data-column="+e+"]").find(".curvalue").html(f);l.length&&(l.find(".range").val(c),l.closest("thead").find("th[data-column="+e+"]").find(".curvalue").html(f))};h.remove();d&&(b.html('').closest("thead").find("th[data-column="+e+"]").addClass("filter-parsed").find(".tablesorter-header-inner").append(''),b.find(".range").bind("change",function(){f(this.value)}),b.find("input[type=hidden]").bind("change.tsfilter",function(){var b=this.value;b!==this.lastValue&&(this.value=this.lastValue=a.compare?a.compare+b:b==a.min?"":(a.exactMatch?"=":"")+b,f(b))}),c.$table.bind("stickyHeadersInit",function(){l=c.widgetOptions.$sticky.find(".tablesorter-filter-row").children().eq(e).empty(); l.html('').find(".range").bind("change",function(){f(l.find(".range").val())});f(b.find(".range").val())}),b.closest("table").bind("filterReset",function(){f(a.value)}),f(b.find(".range").val()));return d?b.find('input[type="hidden"]'):k('')},html5Color:function(b,e,h){var a,d=k.extend({value:"#000000",disabled:!1,addToggle:!0,exactMatch:!0,valueToHeader:!1,skipTest:!1},h);h=k('').appendTo(b); var l=d.skipTest||"color"===h.attr("type")&&"test"!==h.val(),c=[],f=b.closest("table")[0].config,g=function(a){a=a||d.value;var f=!0,g=" ("+a+")";d.addToggle&&(f=b.find(".toggle").is(":checked"));b.find(".colorpicker").length&&(b.find(".colorpicker").val(a)[0].disabled=d.disabled||!f);b.find("input[type=hidden]").val(f?a+(d.exactMatch?"=":""):"").trigger("search");d.valueToHeader?b.closest("thead").find("th[data-column="+e+"]").find(".curcolor").html(g):b.find(".currentColor").html(g);c.length&&(c.find(".colorpicker").val(a)[0].disabled= d.disabled||!f,d.addToggle&&(c.find(".toggle")[0].checked=f),d.valueToHeader?c.closest("thead").find("th[data-column="+e+"]").find(".curcolor").html(g):c.find(".currentColor").html(g))};h.remove();l&&(a='
',a+=d.addToggle?'
':"",a+='',a+=(d.valueToHeader?"":'(#000000)')+ "
",b.html(a),d.valueToHeader&&b.closest("thead").find("th[data-column="+e+"]").find(".tablesorter-header-inner").append(''),b.find(".toggle, .colorpicker").bind("change",function(){g(b.find(".colorpicker").val())}),b.find("input[type=hidden]").bind("change.tsfilter",function(){g(this.value)}),b.closest("table").bind("filterReset",function(){b.find(".toggle")[0].checked=!1;g(b.find(".colorpicker").val())}),f.$table.bind("stickyHeadersInit",function(){c=f.widgetOptions.$sticky.find(".tablesorter-filter-row").children().eq(e); c.html(a).find(".toggle, .colorpicker").bind("change",function(){g(c.find(".colorpicker").val())});g(c.find(".colorpicker").val())}),g(d.value));return l?b.find('input[type="hidden"]'):k('')}}})(jQuery); 7 | -------------------------------------------------------------------------------- /jquery_tablesorter/static/js/tablesorter/widgets/widget-build-table.js: -------------------------------------------------------------------------------- 1 | /*! Build Table widget * by Rob Garrison */ 2 | /*jshint browser:true, jquery:true, unused:false */ 3 | /*global jQuery: false */ 4 | ;(function($){ 5 | "use strict"; 6 | var ts = $.tablesorter = $.tablesorter || {}, 7 | 8 | // build a table from data (requires existing tag) 9 | // data.header contains an array of header titles 10 | // data.rows contains an array of rows which contains an array of cells 11 | bt = ts.buildTable = function(tar, c){ 12 | // add table if one doesn't exist 13 | var $tbl = tar.tagName === 'TABLE' ? $(tar) : $('
').appendTo(tar), 14 | table = $tbl[0], 15 | wo = c.widgetOptions = $.extend( true, {}, bt.defaults, c.widgetOptions ), 16 | p = wo.build_processing, 17 | typ = wo.build_type, 18 | d = wo.build_source || c.data, 19 | 20 | // determine type: html, json, array, csv, object 21 | runType = function(d){ 22 | var t = $.type(d), 23 | jq = d instanceof jQuery; 24 | // run any processing if set 25 | if ( typeof p === 'function' ) { d = p(d, wo); } 26 | // store processed data in table.config.data 27 | c.data = d; 28 | // String (html or unprocessed json) or jQuery object 29 | if ( jq || t === 'string' ) { 30 | // look for closing tag, then we have an HTML string 31 | if ( jq || /<\s*\/tr\s*>/.test(d) ) { 32 | return bt.html( table, d, wo ); 33 | } 34 | try { 35 | d = $.parseJSON(d); 36 | if (d) { 37 | // valid JSON! 38 | return bt.object( table, d, wo ); 39 | } 40 | } catch(ignore) {} 41 | // fall through in case it's a csv string 42 | } 43 | // Array 44 | if (t === 'array' || t === 'string' || typ === 'array' || typ === 'csv') { 45 | // build table using an array (csv & array combined script) 46 | return bt.csv( table, d, wo ); 47 | } 48 | // if we got here, it's an object, or nothing 49 | return bt.object( table, d, wo ); 50 | }; 51 | 52 | // store config 53 | table.config = c; 54 | 55 | // even if wo.build_type is undefined, we can try to figure out the type 56 | if ( !ts.buildTable.hasOwnProperty(typ) && typ !== '' ) { 57 | if (c.debug) { ts.log('aborting build table widget, incorrect build type'); } 58 | return false; 59 | } 60 | 61 | if ( d instanceof jQuery ) { 62 | // get data from within a jQuery object (csv) 63 | runType( $.trim( d.html() ) ); 64 | } else if ( d && ( d.hasOwnProperty('url') || typ === 'json' ) ) { 65 | // load data via ajax 66 | $.ajax( wo.build_source ) 67 | .done(function(data) { 68 | runType(data); 69 | }) 70 | .fail(function( jqXHR, textStatus, errorThrown) { 71 | if (c.debug) { ts.log('aborting build table widget, failed ajax load'); } 72 | $tbl.html(''); 73 | }); 74 | } else { 75 | runType(d); 76 | } 77 | }; 78 | 79 | bt.defaults = { 80 | // *** build widget core *** 81 | build_type : '', // array, csv, object, json, html 82 | build_source : '', // array, object, jQuery Object or ajaxObject { url: '', dataType: 'json' }, 83 | build_processing : null, // function that returns a useable build_type (e.g. string to array) 84 | build_complete : 'tablesorter-build-complete', // triggered event when build completes 85 | 86 | // *** CSV & Array *** 87 | build_headers : { 88 | rows : 1, // Number of header rows from the csv 89 | classes : [], // Header classes to apply to cells 90 | text : [], // Header cell text 91 | widths : [] // set header cell widths (set in colgroup) 92 | }, 93 | build_footers : { 94 | rows : 1, // Number of header rows from the csv 95 | classes : [], // Footer classes to apply to cells 96 | text : [] // Footer cell text 97 | }, 98 | build_numbers : { 99 | addColumn : false, // include row numbering column? 100 | sortable : false // make column sortable? 101 | }, 102 | 103 | // *** CSV only options *** 104 | build_csvStartLine : 0, // line within the csv to start adding to table 105 | build_csvSeparator : ",", // csv separator 106 | 107 | // *** build object options *** 108 | build_objectRowKey : 'rows', // object key containing table rows 109 | build_objectCellKey : 'cells', // object key containing table cells (within the rows object) 110 | build_objectHeaderKey : 'headers', // object key containing table headers 111 | build_objectFooterKey : 'footers' // object key containing table footers 112 | }; 113 | 114 | bt.build = { 115 | colgroup : function(widths) { 116 | var t = ''; 117 | // add colgroup if widths set 118 | if (widths && widths.length) { 119 | t += ''; 120 | $.each(widths, function(i, w){ 121 | t += ''; 122 | }); 123 | t += ''; 124 | } 125 | return t; 126 | }, 127 | // d = cell data; typ = 'th' or 'td'; first = save widths from first header row only 128 | cell : function(d, wo, typ, col, first){ 129 | var j, $td, 130 | $col = first ? $('') : '', 131 | cls = wo.build_headers.classes, 132 | cw = wo.build_headers.widths; 133 | // d is just an array 134 | if (/string|number/.test(typeof d)) { 135 | // add classes from options, but not text 136 | $td = $('<' + typ + (cls && cls[col] ? ' class="' + cls[col] + '"' : '') + '>' + d + ''); 137 | // get widths from options (only from first row) 138 | if (first && cw && cw[col]) { 139 | $col.width(cw[col] || ''); 140 | } 141 | } else { 142 | // assume we have an object 143 | $td = $('<' + typ + '>'); 144 | for (j in d) { 145 | if (d.hasOwnProperty(j)){ 146 | if (j === 'text' || j === 'html') { 147 | $td[j]( d[j] ); 148 | } else if (first && j === 'width') { 149 | // set column width, but only from first row 150 | $col.width(d[j] || ''); 151 | } else { 152 | $td.attr(j, d[j]); 153 | } 154 | } 155 | } 156 | } 157 | return [ $td, $col ]; 158 | }, 159 | // h1 = header text from data 160 | header : function(h1, wo){ 161 | var h2 = wo.build_headers.text, 162 | cls = wo.build_headers.classes, 163 | t = '' + (wo.build_numbers.addColumn ? '' + wo.build_numbers.addColumn + '' : ''); 165 | $.each(h1, function(i, h) { 166 | t += '' + 167 | (h2 && h2[i] ? h2[i] : h) + ''; 168 | }); 169 | return t + ''; 170 | }, 171 | rows : function(items, txt, c, wo, num, ftr){ 172 | var h = (ftr ? 'th' : 'td'), 173 | t = '' + (wo.build_numbers.addColumn ? '<' + h + '>' + (ftr ? '' : num) + '' : ''); 174 | $.each(items, function(i, item) { 175 | t += '<' + (ftr ? h + (c && c[i] ? ' class="' + c[i] + '"' : '') : h) + '>' + 176 | (ftr && txt && txt.length && txt[i] ? txt[i] : item) + ''; 177 | }); 178 | return t + ''; 179 | } 180 | }; 181 | 182 | bt.buildComplete = function(table, wo){ 183 | $(table).trigger(wo.build_complete); 184 | ts.setup(table, table.config); 185 | }; 186 | 187 | /* ==== Array example ==== 188 | [ 189 | [ "header1", "header2", ... "headerN" ], 190 | [ "row1cell1", "row1cell2", ... "row1cellN" ], 191 | [ "row2cell1", "row2cell2", ... "row2cellN" ], 192 | ... 193 | [ "rowNcell1", "rowNcell2", ... "rowNcellN" ] 194 | ] 195 | */ 196 | bt.array = function(table, data, wo) { 197 | return bt.csv(table, data, wo); 198 | }; 199 | 200 | /* ==== CSV example ==== 201 | ID, Name, Age, Date 202 | A42b, Parker, 28, "Jul 6, 2006 8:14 AM" 203 | A255, Hood, 33, "Dec 10, 2002 5:14 AM" 204 | A33, Kent, 18, "Jan 12, 2003 11:14 AM" 205 | A1, Franklin, 45, "Jan 18, 2001 9:12 AM" 206 | A102, Evans, 22, "Jan 18, 2007 9:12 AM" 207 | A42a, Everet, 22, "Jan 18, 2007 9:12 AM" 208 | ID, Name, Age, Date 209 | */ 210 | // Adapted & modified from csvToTable.js by Steve Sobel 211 | // MIT license: https://code.google.com/p/jquerycsvtotable/ 212 | bt.csv = function(table, data, wo) { 213 | var c, h, 214 | csv = wo.build_type === 'csv' || typeof data === 'string', 215 | $t = $(table), 216 | lines = csv ? data.replace('\r','').split('\n') : data, 217 | len = lines.length, 218 | printedLines = 0, 219 | infooter = false, 220 | r = wo.build_headers.rows + (csv ? wo.build_csvStartLine : 0), 221 | f = wo.build_footers.rows, 222 | headerCount = 0, 223 | error = '', 224 | items, 225 | tableHTML = bt.build.colgroup( wo.build_headers.widths ) + ''; 226 | 227 | $.each(lines, function(n, line) { 228 | if ( n >= len - f ) { infooter = true; } 229 | // build header 230 | if ( (csv ? n >= wo.build_csvStartLine : true) && ( n < r ) ) { 231 | h = csv ? bt.splitCSV( line, wo.build_csvSeparator ) : line; 232 | headerCount = h.length; 233 | tableHTML += bt.build.header(h, wo); 234 | } else if ( n >= r ) { 235 | // build tbody & tfoot rows 236 | if (n === r) { 237 | tableHTML += ''; 238 | } 239 | items = csv ? bt.splitCSV( line, wo.build_csvSeparator ) : line; 240 | if (infooter && f > 0) { 241 | tableHTML += (n === len - f ? '' : '') + 242 | (n === len ? '' : ''); 243 | } 244 | if (items.length > 1) { 245 | printedLines++; 246 | if ( items.length !== headerCount ) { 247 | error += 'error on line ' + n + ': Item count (' + items.length + 248 | ') does not match header count (' + headerCount + ') \n'; 249 | } 250 | c = infooter ? wo.build_footers.classes : ''; 251 | tableHTML += bt.build.rows(items, wo.build_footers.text, c, wo, printedLines, infooter); 252 | } 253 | } 254 | }); 255 | tableHTML += (f > 0 ? '' : ''); 256 | if (error) { 257 | $t.html(error); 258 | } else { 259 | $t.html(tableHTML); 260 | bt.buildComplete(table, wo); 261 | } 262 | }; 263 | 264 | // CSV Parser by Brian Huisman (http://www.greywyvern.com/?post=258) 265 | bt.splitCSV = function(str, sep) { 266 | var x, tl, 267 | thisCSV = $.trim(str).split(sep = sep || ","); 268 | for ( x = thisCSV.length - 1; x >= 0; x-- ) { 269 | if ( thisCSV[x].replace(/\"\s+$/, '"').charAt(thisCSV[x].length - 1) === '"' ) { 270 | if ( (tl = thisCSV[x].replace(/^\s+\"/, '"')).length > 1 && tl.charAt(0) === '"' ) { 271 | thisCSV[x] = thisCSV[x].replace(/^\s*"|"\s*$/g, '').replace(/""/g, '"'); 272 | } else if (x) { 273 | thisCSV.splice(x - 1, 2, [thisCSV[x - 1], thisCSV[x]].join(sep)); 274 | } else { 275 | thisCSV = thisCSV.shift().split(sep).concat(thisCSV); 276 | } 277 | } else { 278 | thisCSV[x].replace(/""/g, '"'); 279 | } 280 | } 281 | return thisCSV; 282 | }; 283 | 284 | // data may be a jQuery object after processing 285 | bt.html = function(table, data, wo) { 286 | var $t = $(table); 287 | if ( data instanceof jQuery ) { 288 | $t.empty().append(data); 289 | } else { 290 | $t.html(data); 291 | } 292 | bt.buildComplete(table, wo); 293 | }; 294 | 295 | /* ==== Object example ==== 296 | data : { 297 | headers : [ 298 | [ 299 | { text: 'First Name', class: 'fname', width: '20%' }, // row 1 cell 1 300 | 'Last Name', 301 | { text: 'Age', class: 'age', 'data-sorter' : false }, 302 | 'Total', 303 | { text: 'Discount', class : 'sorter-false' }, 304 | { text: 'Date', class : 'date' } // row 1 cell 6 305 | ] 306 | ], 307 | footers : 'clone', // clone headers or assign array like headers 308 | rows : [ 309 | // TBODY 1 310 | [ 'Peter', 'Parker', 28, '$9.99', '20%', 'Jul 6, 2006 8:14 AM' ], // row 1 311 | [ 'John', 'Hood', 33, '$19.99', '25%', 'Dec 10, 2002 5:14 AM' ], // row 2 312 | [ 'Clark', 'Kent', 18, '$15.89', '44%', 'Jan 12, 2003 11:14 AM' ], // row 3 313 | 314 | // TBODY 2 315 | { newTbody: true, class: 'tablesorter-infoOnly' }, 316 | { cells : [ { text: 'Info Row', colSpan: 6 } ] }, // row 4 317 | 318 | // TBODY 3 319 | { newTbody: true }, 320 | [ 'Bruce', 'Evans', 22, '$13.19', '11%', 'Jan 18, 2007 9:12 AM' ], // row 5 321 | [ 'Brice', 'Almighty', 45, '$153.19', '44%', 'Jan 18, 2001 9:12 AM' ], // row 6 322 | 323 | { class: 'specialRow', // row 7 324 | cells: [ 325 | { text: 'Fred', class: 'fname' }, 326 | { text: 'Smith', class: 'lname' }, 327 | { text: 18, class: 'age', 'data-info': 'fake ID!, he is really 16' }, 328 | { text: '$22.44', class: 'total' }, 329 | { text: '8%', class: 'discount' }, 330 | { text: 'Aug 20, 2012 10:15 AM', class: 'date' } 331 | ], 332 | 'data-info' : 'This row likes turtles' 333 | } 334 | ] 335 | } 336 | */ 337 | bt.object = function(table, data, wo) { 338 | // "rows" 339 | var j, l, t, $c, $t, $tb, $tr, 340 | c = table.config, 341 | kh = wo.build_objectHeaderKey, 342 | kr = wo.build_objectRowKey, 343 | h = data.hasOwnProperty(kh) && !$.isEmptyObject(data.kh) ? data.kh : data.hasOwnProperty('headers') ? data.headers : false, 344 | r = data.hasOwnProperty(kr) && !$.isEmptyObject(data.kr) ? data.kr : data.hasOwnProperty('rows') ? data.rows : false; 345 | 346 | if (!h || !r || h.length === 0 || r.length === 0) { 347 | if (c.debug) { ts.log('aborting build table widget, missing data for object build'); } 348 | return false; 349 | } 350 | 351 | $c = $(''); 352 | $t = $('
' + jqXHR.status + ' ' + textStatus + '
'); 353 | 354 | // Build thead 355 | // h = [ ['headerRow1Cell1', 'headerRow1Cell2', ... 'headerRow1CellN' ], ['headerRow2Cell1', ... ] ] 356 | // or h = [ [ { text: 'firstCell', class: 'fc', width: '20%' }, ..., { text: 'last Cell' } ], [ /* second row */ ] ] 357 | $.each(h, function(i, d){ 358 | $tr = $('').appendTo( $t.find('thead') ); 359 | l = d.length; // header row 360 | for ( j = 0; j < l; j++ ) { 361 | // cell(cellData, widgetOptions, 'th', first row) 362 | t = bt.build.cell(d[j], wo, 'th', j, i === 0); 363 | if (t[0] && t[0].length) { t[0].appendTo( $tr ); } // add cell 364 | if (i === 0 && t[1]) { t[1].appendTo( $c ); } // add col to colgroup 365 | } 366 | }); 367 | if ($c.find('col[style]').length) { 368 | // add colgroup if it contains col elements 369 | $t.prepend( $c ); 370 | } 371 | 372 | $tb = $(''); 373 | // Build tbody 374 | $.each(r, function(i, d){ 375 | t = $.type(d) === 'object'; 376 | // add new tbody 377 | if (t && d.newTbody) { 378 | $tb = $('').appendTo( $t ); 379 | for (j in d) { 380 | if (d.hasOwnProperty(j) && j !== 'newTbody'){ 381 | $tb.attr(j, d[j]); 382 | } 383 | } 384 | } else { 385 | if (i === 0) { 386 | // add tbody, if the first item in the object isn't a call for a new tbody 387 | $tb.appendTo( $t ); 388 | } 389 | 390 | $tr = $('').appendTo( $tb ); 391 | if (t) { 392 | // row defined by object 393 | for (j in d) { 394 | if (d.hasOwnProperty(j) && j !== wo.build_objectCellKey){ 395 | $tr.attr(j, d[j]); 396 | } 397 | } 398 | if (d.hasOwnProperty(wo.build_objectCellKey)) { 399 | // cells contains each cell info 400 | d = d.cells; 401 | } 402 | } 403 | 404 | l = d.length; 405 | for ( j = 0; j < l; j++ ) { 406 | // cell(cellData, widgetOptions, 'td') 407 | $c = bt.build.cell(d[j], wo, 'td', j); 408 | if ($c[0] && $c[0].length) { $c[0].appendTo( $tr ); } // add cell 409 | } 410 | } 411 | }); 412 | 413 | // add footer 414 | if (data.hasOwnProperty(wo.build_objectFooterKey)) { 415 | t = data[wo.build_objectFooterKey]; 416 | if (t === 'clone') { 417 | $c = $t.find('thead').html(); 418 | $t.append('' + $c + ''); 419 | } else { 420 | $c = $('').appendTo( $t ); 421 | $.each(t, function(i, d) { 422 | $tr = $('').appendTo( $c ); 423 | l = d.length; // footer cells 424 | for ( j = 0; j < l; j++ ) { 425 | // cell(cellData, widgetOptions, 'th') 426 | $tb = bt.build.cell(d[j], wo, 'th', j); 427 | if ($tb[0] && $tb[0].length) { $tb[0].appendTo( $tr ); } // add cell 428 | } 429 | }); 430 | } 431 | } 432 | 433 | $(table).html( $t.html() ); 434 | bt.buildComplete(table, wo); 435 | }; 436 | 437 | bt.ajax = bt.json = function(table, data, wo) { 438 | return bt.object(table, data, wo); 439 | }; 440 | 441 | })(jQuery); 442 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | tablesorter is a jQuery plugin for turning a standard HTML table with THEAD and TBODY tags into a sortable table without page refreshes. 2 | tablesorter can successfully parse and sort many types of data including linked data in a cell. 3 | 4 | ### [Documentation](http://mottie.github.io/tablesorter/docs/) 5 | 6 | * See the [full documentation](http://mottie.github.io/tablesorter/docs/). 7 | * All of the [original document pages](http://tablesorter.com/docs/) have been included. 8 | * Information from my blog post on [undocumented options](http://wowmotty.blogspot.com/2011/06/jquery-tablesorter-missing-docs.html) and lots of new demos have also been included. 9 | * Change log moved from included text file into the [wiki documentation](https://github.com/Mottie/tablesorter/wiki/Change). 10 | 11 | ### Demos 12 | 13 | * [Basic alpha-numeric sort Demo](http://mottie.github.com/tablesorter/). 14 | * Links to demo pages can be found within the main [documentation](http://mottie.github.io/tablesorter/docs/). 15 | * More demos & playgrounds - updated in the [wiki pages](https://github.com/Mottie/tablesorter/wiki). 16 | 17 | ### Features 18 | 19 | * Multi-column alphanumeric sorting. 20 | * Multi-tbody sorting - see the [options](http://mottie.github.io/tablesorter/docs/index.html#options) table on the main document page. 21 | * Parsers for sorting text, alphanumeric text, URIs, integers, currency, floats, IP addresses, dates (ISO, long and short formats) & time. [Add your own easily](http://mottie.github.io/tablesorter/docs/example-parsers.html). 22 | * Support for ROWSPAN and COLSPAN on TH elements. 23 | * Support secondary "hidden" sorting (e.g., maintain alphabetical sort when sorting on other criteria). 24 | * Extensibility via [widget system](http://mottie.github.io/tablesorter/docs/example-widgets.html). 25 | * Cross-browser: IE 6.0+, FF 2+, Safari 2.0+, Opera 9.0+. 26 | * Small code size. 27 | * Works with jQuery 1.2.6+ (jQuery 1.4.1+ needed with some widgets). 28 | * Works with jQuery 1.9+ ($.browser.msie was removed; needed in the original version). 29 | 30 | ### Licensing 31 | 32 | * Copyright (c) 2007 Christian Bach. 33 | * Original examples and docs at: [http://tablesorter.com](http://tablesorter.com). 34 | * Dual licensed under the [MIT](http://www.opensource.org/licenses/mit-license.php) and [GPL](http://www.gnu.org/licenses/gpl.html) licenses. 35 | 36 | ### Special Thanks 37 | 38 | * Big shout-out to [Nick Craver](https://github.com/NickCraver) for getting rid of the `eval()` function that was previously needed for multi-column sorting. 39 | * Big thanks to [thezoggy](https://github.com/thezoggy) for helping with code, themes and providing valuable feedback. 40 | * Big thanks to [ThsSin-](https://github.com/TheSin-) for taking over for a while and also providing valuable feedback. 41 | * And, of course thanks to everyone else that has contributed, and continues to contribute to this forked project! 42 | 43 | ### Change Log 44 | 45 | View the [complete listing here](https://github.com/Mottie/tablesorter/wiki/Change). 46 | 47 | #### Version 2.12 (10/18/2013) 48 | 49 | **Core** 50 | * Added `numberSorter` option allowing you to modify the overall numeric sorter. 51 | * Updated the `textSorter` option to allow setting a text sorter for each column. 52 | * The `textSorter` functon parameters have changed from `(a, b, table, column)` to `(a, b, direction, column, table)`. 53 | * Restructured & combined sorting functions internally so that tablesorter will always sort empty cells no matter what sorting algorithm is used by the `textSorter`. 54 | * Renamed `$.tablesorter.sortText()` to `$.tablesorter.sortNatural()` 55 | * Added a new basic alphabetical sort algorithm `$.tablesorter.sortText = function(a, b) { return a > b ? 1 : (a < b ? -1 : 0); };` which can be set using the `textSorter` option. 56 | * New examples can be found in the updated [custom sort demo](http://mottie.github.io/tablesorter/docs/example-option-custom-sort.html). 57 | 58 | * Added `fixedUrl` option for use with the `$.tablesorter.storage()` function. 59 | * Setting this with a fixed name (it doesn't need to be a url) allows saving table data (`saveSort` widget, `savePages` in pager widget) for tables on multiple pages in a domain. 60 | * Additional storage options are described below under "Storage". 61 | * An accurate number of table columns is now contained within `table.config.columns`. This accounts for multiple header rows, tds, ths, etc. 62 | * Replaced `.innerHTML` with jQuery's `.html()` to fix issues in IE8. Fixes [issue #385](https://github.com/Mottie/tablesorter/issues/385). 63 | * Version numbers should now all be accurate, even in the comments.. at least this time ;). Fixes [issue #386](https://github.com/Mottie/tablesorter/issues/386). 64 | 65 | **Pager** 66 | * In attempts to initialize the pager after the filter widget: 67 | * Added a pager widget (still beta testing) to allow initializing the pager after certain widgets (filter widget). 68 | * Updated tablesorter core (properly count table columns) & filter widget code to allow it to initialize on an empty table (thanks @stanislavprokopov!). 69 | * Hopefully one or both of these changes fixes [issue #388](https://github.com/Mottie/tablesorter/issues/388). 70 | * New pager widget demos: [basic](http://mottie.github.io/tablesorter/docs/example-widget-pager.html) & [ajax](http://mottie.github.io/tablesorter/docs/example-widget-pager-ajax.html). 71 | * `savePages` option 72 | * Should no longer cause an error if stored data is malformed or unrecognized. Fixes [issue #387](https://github.com/Mottie/tablesorter/issues/387). 73 | * The stored size and page is now cleared if the table is destroyed. 74 | * Fixed an error occuring in IE when trying to determine if a variable is an array (`toString` function call not recognized). Fixes [issue #390](https://github.com/Mottie/tablesorter/issues/390). 75 | * Updated pager rendering to prevent multiple ajax calls. 76 | * During this update, the pager page size would return as zero and set the totalPages value to inifinity. Yeah, it doesn't do that anymore; but you can still set the pager size to zero if you want! 77 | 78 | **Widgets** 79 | * Filter widget: 80 | * Should now properly initialize when the pager plugin/widget is used with ajax and/or the `filter_serversideFiltering` option is `true`. Fixes [issue #388](https://github.com/Mottie/tablesorter/issues/388). 81 | * Please note that the select dropdowns still sort using the natural sort algorithm, but since it is using the function directly, empty cells will not sort based on the `emptyTo` option. If this is a big problem, let me know! 82 | * Grouping widget: 83 | * Added `group_callback` option - this sets a callback function which allows modification of each group header label - like adding a subtotal for each group, or something. See the [updated demo](http://mottie.github.io/tablesorter/docs/example-widget-grouping.html). 84 | * Added `group_complete` option which is `"groupingComplete"` by default. This is the name of the event that is triggered once the grouping widget has completed updating. 85 | * Updated the editable widget: 86 | * Added `editable_editComplete` option which names the event that is triggered after tablesorter has completed updating the recent edit. 87 | * You can also bind to the `change` event for that editable element, but it may occur before tablesorter has updated its internal data cache. 88 | * Storage 89 | * The `$.tablesorter.storage()` function now has options including the `fixedUrl` option described in the core section above. 90 | * Also added storage options which can be used for custom widgets: `$.tablesorter.storage(table, key, value, { url : 'mydomain', id : 'table-group' })`. 91 | * Additionally, for already build-in widgets, you can apply data-attributes to the table: `...
`. 92 | * For more details, please see [issue #389](https://github.com/Mottie/tablesorter/issues/389). 93 | 94 | **Parsers** 95 | * Added an IPv6 parser 96 | * This parser will auto-detect (the `is` function checks for valid IPv6 addresses). 97 | * Added a new [IPv6 parser demo](http://mottie.github.io/tablesorter/docs/example-parsers-ip-address.html). 98 | * Included rather extensive unit tests for just this parser o.O. 99 | 100 | #### Version 2.11.1 (10/11/2013) 101 | 102 | * Fixed an updating bug: 103 | * The pager was not updating properly 104 | * The `updateComplete` event was not firing when not using ajax. 105 | * Thanks @sbine for sharing the fix! 106 | 107 | #### Version 2.11 (10/10/2013) 108 | 109 | **Core** 110 | * Initialized widgets (widgets with options) are now tracked to ensure widget options are extended when using "applyWidgets". Fixes [issue #330](https://github.com/Mottie/tablesorter/issues/330). 111 | * An javascript error no longer pops up when setting the `delayInit` option to `true` and using the `saveSort` widget (or triggering a `sorton` method). Fixes [issue #346](https://github.com/Mottie/tablesorter/issues/346). 112 | * Only visible columns will be considered when fixing column widths. Fixes [issue #371](https://github.com/Mottie/tablesorter/issues/371). 113 | * Merged in fix for jQuery version check ([pull #338](https://github.com/Mottie/tablesorter/pull/338)). This also fixes [issue #379](https://github.com/Mottie/tablesorter/issues/379). Thanks @lemoinem! 114 | * Removed natural sort's ability to sort dates. This shouldn't be a problem since tablesorter uses parsers detect & parse date columns automatically. Fixes [issue #373](https://github.com/Mottie/tablesorter/issues/373). 115 | * Fixed [issue #381](https://github.com/Mottie/tablesorter/issues/381). 116 | * Any class name that is set by an option and is later used to search for that element now has an empty default class name. 117 | * The reasoning is that if a developer adds two class names to the option, the jQuery find breaks. 118 | * All default single class name options are now contained within `$.tablesorter.css` 119 | * Options affected include: tableClass, cssAsc, cssDesc, cssHeader, cssIcon, cssHeaderRow, cssProcessing in the core. 120 | * Note that the `cssIcon` option retains it's default class name & functionality to not add an `` inside the table cell if this *extra class name* is undefined. 121 | * Widget options affected include: filter_cssFilter and stickyHeaders. 122 | * Removed `return false` from header mouse/keyboard interaction. Fixes [issue #305](https://github.com/Mottie/tablesorter/pull/305) & [issue #366](https://github.com/Mottie/tablesorter/issues/366). 123 | 124 | **Parsers** 125 | * Fixed sugar date parser demo to point to the correct parser file and sugarjs resource. 126 | * General cleaned up date, fraction and metric parsers & fixing of minor bugs. 127 | 128 | **Build Table Widget (new)** 129 | * Build a table starting with an assortment of data types ( array, text (CSV, HTML) or object (json) ). 130 | * This widget isn't really a widget because it is run and does it's processing before tablesorter has initialized; but the options for it are contained within the tablesorter `widgetOptions`. 131 | 132 | **Column Widget** 133 | * General cleanup 134 | 135 | **Filter Widget** 136 | * Exact matches can still be made if the user enters an exact match indicator twice (i.e. `John==` will still find `John` in the column; before it would think the user was looking for `John=` after the second `=` was typed) 137 | * Dynamically added filter reset buttons will now work automatically. Added by [pull #327](https://github.com/Mottie/tablesorter/pull/327). Thanks @riker09! 138 | * Chrome appears to have fixed the hidden input bug, so reverted changes to the basic filter demo. Fixes [issue #341](https://github.com/Mottie/tablesorter/issues/341). 139 | * The filter widget will work properly with sub-tables. Fixes [issue #354](https://github.com/Mottie/tablesorter/issues/354). Thanks @johngrogg! 140 | * Fixed issues with `filter_columnFilters` set to `false`. Fixes [issue #355](https://github.com/Mottie/tablesorter/issues/355). 141 | * Searches now have accents replaced if the `sortLocaleCompare` option is `true`. Fixes [issue #357](https://github.com/Mottie/tablesorter/issues/357). 142 | * Merged in enhancement for the filter widget & updated docs - add row to `filter_functions` parameters ([issue #367](https://github.com/Mottie/tablesorter/issues/367), [pull #368](https://github.com/Mottie/tablesorter/pull/368)). Thanks @gknights! 143 | * FilterFormatter jQuery UI Datepicker now includes the user selected time for comparisons. Thanks @TheSin-! 144 | * Another fix to the filteFormatter jQuery UI Datepicker to make it work properly with the sticky header widget. Thanks @TheSin-! 145 | * Removed filter_cssFilter default class name. The "tablesorter-filter" class name is automatically added, and this option now contains any additional class names to add. Fixes [issue #381](https://github.com/Mottie/tablesorter/issues/381). 146 | 147 | **Grouping Widget** 148 | * The grouping widget now works across multiple tbodies. 149 | * Added `group-false` header option which disables the grouping widget for a specific column. Fixes [issue #344](https://github.com/Mottie/tablesorter/issues/344). 150 | * Added the `group_collapsed` option which when true and the `group_collapsible` option is also true, all groups will start collapsed. Fulfills [issue #352](https://github.com/Mottie/tablesorter/issues/352). 151 | * You can now toggle *all* group rows by holding down the shift key while clicking on a group header. 152 | * This widget now works properly with the pager addon (pager addon updated). Fixes [issue #281](https://github.com/Mottie/tablesorter/issues/281). 153 | 154 | **StickyHeaders Widget** 155 | * Caption outerheight now used to get the correct full height of the caption. Thanks @TheSin-! 156 | * `stickyHeaders_zIndex` option added to allow users to customize their sticky header z-index. Fixes [issue #332](https://github.com/Mottie/tablesorter/pull/332). Thanks @TheSin-! 157 | 158 | **UITheme widget** 159 | * Updated Bootstrap theme to work with Bootstrap v3 160 | * Only additions were made to the sorting icons class names within in the `$.tablesorter.themes.bootstrap` defaults (contained in the `jquery.tablesorter.widgets.js` file). 161 | * So the theme will support all current versions of Bootstrap, just make sure you are using the appropriate icon class name (`icon-{name}` = v2; `glyphicon glyphicon-{name}` = v3). 162 | * Removed the gradient background from the header & footer cells. 163 | * Added a reduced icon font side for header sort icons. 164 | * Renamed the pager class from `pager` to `ts-pager` as Bootstrap adds a lot of padding to that class. See [Bootstrap theme demo](http://mottie.github.io/tablesorter/docs/example-widget-bootstrap-theme.html). 165 | * Thanks @YeaYeah for sharing how to fix the top border in [issue #365](https://github.com/Mottie/tablesorter/issues/365). 166 | 167 | **Pager** 168 | * Fixed the `removeRows` option error when set to `true`. 169 | * The pager now stores any object returned by the `ajaxProcessing` function in `table.config.pager.ajaxData` 170 | * The object should contain attributes for `total` (numeric), `headers` (array) and `rows` (array of arrays). 171 | * A replacement `output` option can also be loaded via this method and must be included in the `output` attribute (i.e. `ajaxData.output`). 172 | * Additional attributes are also available to the output display by using the attribute key wrapped in curly brackets (e.g. `{extra}` from `ajaxData.extra`). 173 | * Additional attributes can also be objects or arrays and can be accessed via the output string as `{extra:0}` (for arrays) or `{extra:key}` for objects. 174 | * The page number is processed first, so it would be possible to use this string `{extra:{page}}` (`{page}` is a one-based index), or if you need a different value use `{page+1}` (zero-based index plus any number), or `{page-1}` (zero-based index minus any number). 175 | * For more details, please see [issue #326](https://github.com/Mottie/tablesorter/issues/326). 176 | * Thanks @camallen for the suggestions & feedback! 177 | * The "updateComplete" event should now properly trigger after an ansynchronous ajax call has completed. Fixes [issue #343](https://github.com/Mottie/tablesorter/issues/343). 178 | * Added a new `savePages` option 179 | * Requires requires the `$.tablesorter.storage` script within the `jquery.tablesorter.widget.js` file to work properly. 180 | * When `true`, it saves pager page & size if the storage script is loaded (requires $.tablesorter.storage in jquery.tablesorter.widgets.js). 181 | * The pager will continue to function properly without the storage script, it just won't save the current page or pager size. 182 | * Fulfills enhancement request from [issue #345](https://github.com/Mottie/tablesorter/issues/345). 183 | * Removed table update when using ajax with a server that is already doing all of the work. Fixes [issue #372](https://github.com/Mottie/tablesorter/issues/372) & [issue #361](https://github.com/Mottie/tablesorter/issues/361). Thanks @sbine! 184 | * Merged in change to count table th length after ajaxProcessing ([pull #383](https://github.com/Mottie/tablesorter/pull/383)). Thanks @harryxu! 185 | * Reverted changes made in [pull #349](https://github.com/Mottie/tablesorter/pull/349) as the error row was not showing because the urls did not exactly equal each other. 186 | * Child rows within the pager will now properly display/hide. Fixes [issue #348](https://github.com/Mottie/tablesorter/issues/348). 187 | * Merged in fix for pager redundant ajax requests ([pull #336](https://github.com/Mottie/tablesorter/pull/336)). Thanks @camallen! 188 | * Merged in fix for pager totalRows check ([pull #324](https://github.com/Mottie/tablesorter/pull/324)). Thanks @camallen! 189 | 190 | **Internal fixes** 191 | * Modified the pager plugin internal variables to use `p` for pager options and `c` for table config options - for consistency. 192 | * Cleaned up the formatting of a few parsers (mostly cosmetic!) 193 | * Some parser functions were added to the `$.tablesorter` object instead of keeping them as private functions, just because my OCD compelled me to do it. 194 | * Some of the changes made the parsers are no longer backward compatible to the original version of tablesorter. Break away man, just do it! 195 | 196 | **Thanks** 197 | * Thanks to @thezoggy and @TheSin- for help maintaining and supporting the tablesorter github project while I was away! 198 | * Also thanks to everyone else that contributed and even more thanks to those that helped troubleshoot and solve problems! 199 | 200 | #### Version 2.10.8 (6/3/2013) 201 | 202 | * Updated the percent parser to only detect if the content is shorter than 15 characters. This prevents columns with a lot of content and one percent sign (%) from being set to be parsed as a percent numeric column. Fixes [issue #320](https://github.com/Mottie/tablesorter/issues/320). 203 | * Updated filter widget & filter_formatter: 204 | * Added a new `filter_defaultAttrib` which points to the default `'data-value'` attribute in the table header which will contain the filter's default (starting) value and *will override* any set values within the filter_formatter functions. Updated the [custom filter widget function demo age column](http://mottie.github.io/tablesorter/docs/example-widget-filter-custom.html) to show this in action. 205 | * The `$.tablesorter.setFilter()` method now properly updates the filter formatter elements when set. 206 | * The `uiDateCompare` and `uiDatepicker` functions now adds a time of 11:59:59 to the "to" date or when a "less than" comparison is made so as to include all times within that selected day. 207 | * The `defaultDate` option (not `date` option, sorry) of the `uiDateCompare` now properly sets the value upon initialization. 208 | * The `from` and `to` options of the `uiDatepicker` now properly sets those values properly upon initialization. 209 | * Fixes [issue #321](https://github.com/Mottie/tablesorter/issues/321). 210 | * Fixed stickyHeaders widget: 211 | * When removing a sticky headers widget, it no longer unbinds scrolling when other sticky headers are still active. 212 | * Added `stickyHeaders_includeCaption` option (set as `true` by default). When this option is `false` and a caption exists, it will not be included in teh sticky header. Fixes [issue #322](https://github.com/Mottie/tablesorter/issues/322). 213 | 214 | #### Version 2.10.7 (5/31/2013) 215 | 216 | * Now using correct `closest()` function equivalent. Thanks to [isuTony](https://github.com/isuTony); Fixes [issue #319](https://github.com/Mottie/tablesorter/issues/319). 217 | * Anticipating my sabbitical, I've added a few "beta-testing" scripts into a new folder for feedback, code fixes and help: 218 | * [Custom pager control script](http://mottie.github.io/tablesorter/beta-testing/example-pager-custom-controls.html) - should be working properly. 219 | * [External filters using Select2 plugin](http://mottie.github.io/tablesorter/beta-testing/example-external-filters-using-select2.html) - should be working properly. 220 | * [Column reorder widget](http://mottie.github.io/tablesorter/beta-testing/example-widget-column-reorder.html) - not working 100% with sticky headers. 221 | * [Column sum widget](http://mottie.github.io/tablesorter/beta-testing/example-widget-sum-columns.html) - still needs LOTS of work! 222 | --------------------------------------------------------------------------------