Changeset 10161 for extensions/nbc_ThemeChanger
- Timestamp:
- Apr 8, 2011, 1:30:56 PM (14 years ago)
- Location:
- extensions/nbc_ThemeChanger
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
extensions/nbc_ThemeChanger/Version.txt
r10134 r10161 1 Version 2.2.0.b 2 [lang=fr] 3 Mise en compatibilité avec piwigo 2.2 4 ré-écriture de l'url lors d'une modification ou d'une suppression d'associations 5 6 Mise à jour de jquery.tablesorter en version 2.0.5b et correction d'un bug js quand le tableau est vide 7 8 fichiers modifiés : 9 main.inc.php 10 admin/nbc_themeChanger_admin.tpl 11 admin/nbc_themeChanger_admin.php 12 include/jquery.tablesorter.js 13 [/lang=fr] 14 [lang=en] 15 Piwigo 2.2 compatibility upgrade 16 url rewrite for modification and suppression actions. 17 18 Update in version 2.0.5b of jquery.tablesorter plugin and correction of the autosort js bug when the table is empty 19 20 Modified files: 21 main.inc.php 22 admin/nbc_themeChanger_admin.tpl 23 admin/nbc_themeChanger_admin.php 24 include/jquery.tablesorter.js 25 [/lang=en] 26 27 [lang=it] 28 Compatibilità con Piwigo 2.2 29 riscrittura del URL per le azioni di modificazione e eliminazione 30 31 aggiornamento della versione di jquery.tablesorter in 2.0.5b e correzione dell'anomalia sull'ordine quando la tabella è vuota 32 33 File modificati: 34 main.inc.php 35 admin/nbc_themeChanger_admin.tpl 36 admin/nbc_themeChanger_admin.php 37 include/jquery.tablesorter.js 38 [/lang=it] 39 40 -------------------------------------------------- 1 41 Version 2.2.0.a 2 42 [lang=fr] -
extensions/nbc_ThemeChanger/admin/nbc_ThemeChanger_admin.php
r6648 r10161 12 12 $me = get_plugin_data($plugin_id); 13 13 load_language('plugin.lang', NBC_ThemeChanger_PATH); 14 $page_ThemeChanger_admin = get_admin_plugin_menu_link(__FILE__); 15 14 $page_ThemeChanger_admin = 'admin.php?page=plugin-'.basename(NBC_ThemeChanger_PATH); 15 16 $my_base_url = $page_ThemeChanger_admin; 16 17 17 18 //chargement des catégories … … 26 27 echo '0 '.$themes[1]['id'] .':'. $themes[1]['name'] .'<br>'; 27 28 echo '0 '.$themes[2]['id'] .':'. $themes[2]['name'] .'<br>'; 28 echo '0 '.$themes[3]['id'] .':'. $themes[3]['name'] .'<br>'; 29 } 29 } 30 30 31 31 // Configuration du template … … 34 34 'U_HOME' => make_index_url(), 35 35 'F_ACTION' => add_url_params($page_ThemeChanger_admin, array()), 36 'U_ADD_ASSOC' => add_url_params($page_ThemeChanger_admin, array('action' => 'add_assoc')), 37 'U_HELP' => PHPWG_ROOT_PATH.'popuphelp.php?page=ThemeChanger', 36 //'U_ADD_ASSOC' => add_url_params($page_ThemeChanger_admin, array('tab' => 'add_assoc')), 38 37 'Themes' => $themes, 39 38 'Categories' => $categories, … … 53 52 // Mise a jour des paramètres du plugin 54 53 if (isset($_POST['submit']) and !is_adviser()) 55 if ( (isset($_POST['categorychoise']) or isset($_POST['category_id'])) and isset($_POST['template']))54 if ( isset($_POST['categorychoise']) and isset($_POST['template'])) 56 55 { 57 56 … … 62 61 $theme = $_POST['template']; 63 62 $applysubcategory = isset($_POST['ApplySubCategories']) ? $_POST['ApplySubCategories'] : ''; 64 $thecategory = isset($_POST['categorychoise']) ? $_POST['categorychoise'] : ( isset($_POST['category_id']) ? $_POST['category_id'] : '');63 $thecategory = isset($_POST['categorychoise']) ? $_POST['categorychoise'] : ''; 65 64 66 65 $_POST['categorychoise'] = ''; 67 $_POST['category_id'] = '';68 66 $_POST['template'] = ''; 69 $_GET[' action'] = '';67 $_GET['tab'] = ''; 70 68 $_POST['ApplySubCategories'] = ''; 71 69 … … 131 129 } 132 130 131 //DEBUG _GET 132 else if ($__BEBUG) 133 { 134 echo count($_GET).'<br/>'; 135 foreach ($_GET as $key => $value) { 136 if ($key != "C") { 137 $querystring = $key."=".$value; 138 echo $querystring .'<br/>'; 139 } 140 } 141 } 142 133 143 134 144 //delete an association 135 if ( isset($_GET[' action']) and ($_GET['action']=='del_assoc') and isset($_GET['id_cat']) and is_numeric($_GET['id_cat']) and !is_adviser() )145 if ( isset($_GET['tab']) and ($_GET['tab']=='del_assoc') and isset($_GET['cat']) and is_numeric($_GET['cat']) and !is_adviser() ) 136 146 { 137 147 … … 142 152 $element_ThemeChanger = explode("," , $Theme_Cat); 143 153 144 if ($element_ThemeChanger[0] <> $_GET[' id_cat'] and $element_ThemeChanger[0] <> '')154 if ($element_ThemeChanger[0] <> $_GET['cat'] and $element_ThemeChanger[0] <> '') 145 155 { 146 156 if ($newconf_nbc_ThemeChanger <> '') … … 162 172 array_push($page['infos'], l10n('nbc_ThemeChanger_save_config')); 163 173 } 164 174 165 175 //modify an association 166 else if ( isset($_GET[' action']) and ($_GET['action']=='mod_assoc') and isset($_GET['id_cat']) and is_numeric($_GET['id_cat']) and isset($_GET['id_theme']) )176 else if ( isset($_GET['tab']) and ($_GET['tab']=='mod_assoc') and isset($_GET['cat']) and is_numeric($_GET['cat']) and isset($_GET['theme']) ) 167 177 { 168 178 $template->assign('formulaire',array( 169 'DESCRIPION' => $lang['modify_assoc'].' : '.get_long_categorie_name($_GET[' id_cat']),170 'THEMETOMODIFY' => $_GET[' id_theme'],171 'NAMETOMODIFY' => get_long_categorie_name($_GET[' id_cat']),172 'IDTOMODIFY' => $_GET[' id_cat'],179 'DESCRIPION' => $lang['modify_assoc'].' : '.get_long_categorie_name($_GET['cat']), 180 'THEMETOMODIFY' => $_GET['theme'], 181 'NAMETOMODIFY' => get_long_categorie_name($_GET['cat']), 182 'IDTOMODIFY' => $_GET['cat'], 173 183 )); 174 184 } 175 185 176 186 //add an association 177 else if ( isset($_GET[' action']) and ($_GET['action']=='add_assoc') )187 else if ( isset($_GET['tab']) and ($_GET['tab']=='add_assoc') ) 178 188 { 179 189 $template->assign('formulaire', array( … … 209 219 210 220 array_push($assoc , array( 211 //'CLASS' => ($num++ % 2 == 1) ? 'row2' : 'row1',212 221 'CATEGORY_NAME' => get_cat_display_name_cache($row['uppercats'], null, false), 213 'CATEGORY_ID' => $element_ThemeChanger[0],214 222 'TEMPLATE' => $element_ThemeChanger[1], 215 223 'STATUS' => my_get_pwg_theme_status($element_ThemeChanger[1]), 216 'U_MODIFY' => add_url_params($page_ThemeChanger_admin, array( 217 'action' => 'mod_assoc', 218 'id_cat' => $element_ThemeChanger[0], 219 'id_theme' => $element_ThemeChanger[1], 220 )), 221 'U_DELETE' => add_url_params($page_ThemeChanger_admin, array( 222 'action' => 'del_assoc', 223 'id_cat' => $element_ThemeChanger[0], 224 'U_MODIFY' => add_url_params($page_ThemeChanger_admin.'-mod_assoc', array( 225 'cat' => $element_ThemeChanger[0], 226 'theme' => $element_ThemeChanger[1], 227 )), 228 'U_DELETE' => add_url_params($page_ThemeChanger_admin.'-del_assoc', array( 229 'cat' => $element_ThemeChanger[0], 224 230 )), 225 231 )); -
extensions/nbc_ThemeChanger/admin/nbc_ThemeChanger_admin.tpl
r10099 r10161 6 6 jQuery(document).ready(function() { 7 7 // call the tablesorter plugin 8 jQuery(" #tablesorter").tablesorter({8 jQuery("table#TCtablesorter").tablesorter({ 9 9 // extend the default setting to always sort on the first column 10 10 sortList : [[0,0]], … … 44 44 <h3>Theme Changer</h3> 45 45 </div> 46 <ul class="categoryActions">47 <!--li><a href="{$params.U_HELP}" onclick="popuphelp(this.href); return false;" title="{'HELP'|@translate}"><img src="{$themeconf.icon_dir}/help.png" class="button" alt="(?)"></a></li-->48 </ul>49 46 50 47 <!--br> … … 52 49 <br--> 53 50 54 <table class="table2" id=" tablesorter">51 <table class="table2" id="TCtablesorter"> 55 52 <thead> 56 53 <tr class="throw"> … … 86 83 </tr> 87 84 {/foreach} 88 85 </tbody> 89 86 <!-- END assoc --> 90 87 </table> … … 94 91 <fieldset> 95 92 <legend>{$formulaire.DESCRIPION}</legend> 96 <table class="table2"> 93 <table class="table2" id="TCassoc"> 94 <thead> 97 95 <tr class="throw"> 98 96 <th>{'Album'|@translate}</th> … … 100 98 <th>{'subAlbumsApply'|@translate}</th> 101 99 </tr> 100 </thead> 101 <tbody> 102 102 <tr> 103 103 <td> … … 136 136 </td> 137 137 </tr> 138 138 </tbody> 139 139 </table> 140 141 140 <div align="center"><input class="submit" type="submit" value="{'submit'|@translate}" name="submit" {$TAG_INPUT_ENABLED} /></div> 142 143 141 </fieldset> 144 142 </form> -
extensions/nbc_ThemeChanger/include/jquery.tablesorter.js
r6642 r10161 2 2 * 3 3 * TableSorter 2.0 - Client-side table sorting with ease! 4 * Version 2.0. 34 * Version 2.0.5b-jqz WARNING Modified version specific for Piwigo nbc_ThemeChanger plugin 5 5 * @requires jQuery v1.2.3 6 6 * … … 13 13 */ 14 14 /** 15 * 15 * 16 16 * @description Create a sortable table with multi-column sorting capabilitys 17 17 * 18 18 * @example $('table').tablesorter(); 19 19 * @desc Create a simple tablesorter interface. 20 * 20 * 21 21 * @example $('table').tablesorter({ sortList:[[0,0],[1,0]] }); 22 * @desc Create a tablesorter interface and sort on the first and secound column in ascending order.22 * @desc Create a tablesorter interface and sort on the first and secound column column headers. 23 23 * 24 24 * @example $('table').tablesorter({ headers: { 0: { sorter: false}, 1: {sorter: false} } }); 25 * @desc Create a tablesorter interface and disableing the first and secound column headers. 26 * 27 * @example $('table').tablesorter({ 0: {sorter:"integer"}, 1: {sorter:"currency"} }); 28 * @desc Create a tablesorter interface and set a column parser for the first and secound column. 29 * 30 * 31 * @param Object settings An object literal containing key/value pairs to provide optional settings. 32 * 33 * @option String cssHeader (optional) A string of the class name to be appended to sortable tr elements in the thead of the table. 34 * Default value: "header" 35 * 36 * @option String cssAsc (optional) A string of the class name to be appended to sortable tr elements in the thead on a ascending sort. 37 * Default value: "headerSortUp" 38 * 39 * @option String cssDesc (optional) A string of the class name to be appended to sortable tr elements in the thead on a descending sort. 40 * Default value: "headerSortDown" 41 * 42 * @option String sortInitialOrder (optional) A string of the inital sorting order can be asc or desc. 43 * Default value: "asc" 44 * 45 * @option String sortMultisortKey (optional) A string of the multi-column sort key. 46 * Default value: "shiftKey" 47 * 48 * @option String textExtraction (optional) A string of the text-extraction method to use. 49 * For complex html structures inside td cell set this option to "complex", 50 * on large tables the complex option can be slow. 51 * Default value: "simple" 52 * 53 * @option Object headers (optional) An array containing the forces sorting rules. 54 * This option let's you specify a default sorting rule. 55 * Default value: null 56 * 57 * @option Array sortList (optional) An array containing the forces sorting rules. 58 * This option let's you specify a default sorting rule. 59 * Default value: null 60 * 61 * @option Array sortForce (optional) An array containing forced sorting rules. 62 * This option let's you specify a default sorting rule, which is prepended to user-selected rules. 63 * Default value: null 64 * 65 * @option Array sortAppend (optional) An array containing forced sorting rules. 66 * This option let's you specify a default sorting rule, which is appended to user-selected rules. 67 * Default value: null 68 * 69 * @option Boolean widthFixed (optional) Boolean flag indicating if tablesorter should apply fixed widths to the table columns. 70 * This is usefull when using the pager companion plugin. 71 * This options requires the dimension jquery plugin. 72 * Default value: false 73 * 74 * @option Boolean cancelSelection (optional) Boolean flag indicating if tablesorter should cancel selection of the table headers text. 75 * Default value: true 76 * 77 * @option Boolean debug (optional) Boolean flag indicating if tablesorter should display debuging information usefull for development. 78 * 25 * 26 * @desc Create a tablesorter interface and disableing the first and second column headers. 27 * 28 * 29 * @example $('table').tablesorter({ headers: { 0: {sorter:"integer"}, 1: {sorter:"currency"} } }); 30 * 31 * @desc Create a tablesorter interface and set a column parser for the first 32 * and second column. 33 * 34 * 35 * @param Object 36 * settings An object literal containing key/value pairs to provide 37 * optional settings. 38 * 39 * 40 * @option String cssHeader (optional) A string of the class name to be appended 41 * to sortable tr elements in the thead of the table. Default value: 42 * "header" 43 * 44 * @option String cssAsc (optional) A string of the class name to be appended to 45 * sortable tr elements in the thead on a ascending sort. Default value: 46 * "headerSortUp" 47 * 48 * @option String cssDesc (optional) A string of the class name to be appended 49 * to sortable tr elements in the thead on a descending sort. Default 50 * value: "headerSortDown" 51 * 52 * @option String sortInitialOrder (optional) A string of the inital sorting 53 * order can be asc or desc. Default value: "asc" 54 * 55 * @option String sortMultisortKey (optional) A string of the multi-column sort 56 * key. Default value: "shiftKey" 57 * 58 * @option String textExtraction (optional) A string of the text-extraction 59 * method to use. For complex html structures inside td cell set this 60 * option to "complex", on large tables the complex option can be slow. 61 * Default value: "simple" 62 * 63 * @option Object headers (optional) An array containing the forces sorting 64 * rules. This option let's you specify a default sorting rule. Default 65 * value: null 66 * 67 * @option Array sortList (optional) An array containing the forces sorting 68 * rules. This option let's you specify a default sorting rule. Default 69 * value: null 70 * 71 * @option Array sortForce (optional) An array containing forced sorting rules. 72 * This option let's you specify a default sorting rule, which is 73 * prepended to user-selected rules. Default value: null 74 * 75 * @option Boolean sortLocaleCompare (optional) Boolean flag indicating whatever 76 * to use String.localeCampare method or not. Default set to true. 77 * 78 * 79 * @option Array sortAppend (optional) An array containing forced sorting rules. 80 * This option let's you specify a default sorting rule, which is 81 * appended to user-selected rules. Default value: null 82 * 83 * @option Boolean widthFixed (optional) Boolean flag indicating if tablesorter 84 * should apply fixed widths to the table columns. This is usefull when 85 * using the pager companion plugin. This options requires the dimension 86 * jquery plugin. Default value: false 87 * 88 * @option Boolean cancelSelection (optional) Boolean flag indicating if 89 * tablesorter should cancel selection of the table headers text. 90 * Default value: true 91 * 92 * @option Boolean debug (optional) Boolean flag indicating if tablesorter 93 * should display debuging information usefull for development. 94 * 79 95 * @type jQuery 80 * 96 * 81 97 * @name tablesorter 82 98 * … … 86 102 */ 87 103 88 (function($) { 89 $.extend({ 90 tablesorter: new function() { 104 (function ($) { 105 $.extend({ 106 tablesorter: new 107 function () { 108 109 var parsers = [], 110 widgets = []; 111 112 this.defaults = { 113 cssHeader: "header", 114 cssAsc: "headerSortUp", 115 cssDesc: "headerSortDown", 116 cssChildRow: "expand-child", 117 sortInitialOrder: "asc", 118 sortMultiSortKey: "shiftKey", 119 sortForce: null, 120 sortAppend: null, 121 sortLocaleCompare: true, 122 textExtraction: "simple", 123 parsers: {}, widgets: [], 124 widgetZebra: { 125 css: ["even", "odd"] 126 }, headers: {}, widthFixed: false, 127 cancelSelection: true, 128 sortList: [], 129 headerList: [], 130 dateFormat: "us", 131 decimal: '/\.|\,/g', 132 onRenderHeader: null, 133 selectorHeaders: 'thead th', 134 debug: false 135 }; 136 137 /* debuging utils */ 138 139 function benchmark(s, d) { 140 log(s + "," + (new Date().getTime() - d.getTime()) + "ms"); 141 } 142 143 this.benchmark = benchmark; 144 145 function log(s) { 146 if (typeof console != "undefined" && typeof console.debug != "undefined") { 147 console.log(s); 148 } else { 149 alert(s); 150 } 151 } 152 153 /* parsers utils */ 154 155 function buildParserCache(table, $headers) { 156 157 if (table.config.debug) { 158 var parsersDebug = ""; 159 } 160 161 if (table.tBodies.length == 0) return; // In the case of empty tables 162 var rows = table.tBodies[0].rows; 163 164 if (rows[0]) { 165 166 var list = [], 167 cells = rows[0].cells, 168 l = cells.length; 169 170 for (var i = 0; i < l; i++) { 171 172 var p = false; 173 174 if ($.metadata && ($($headers[i]).metadata() && $($headers[i]).metadata().sorter)) { 175 176 p = getParserById($($headers[i]).metadata().sorter); 177 178 } else if ((table.config.headers[i] && table.config.headers[i].sorter)) { 179 180 p = getParserById(table.config.headers[i].sorter); 181 } 182 if (!p) { 183 184 p = detectParserForColumn(table, rows, -1, i); 185 } 186 187 if (table.config.debug) { 188 parsersDebug += "column:" + i + " parser:" + p.id + "\n"; 189 } 190 191 list.push(p); 192 } 193 } 194 195 if (table.config.debug) { 196 log(parsersDebug); 197 } 198 199 return list; 200 }; 201 202 function detectParserForColumn(table, rows, rowIndex, cellIndex) { 203 var l = parsers.length, 204 node = false, 205 nodeValue = false, 206 keepLooking = true; 207 while (nodeValue == '' && keepLooking) { 208 rowIndex++; 209 if (rows[rowIndex]) { 210 node = getNodeFromRowAndCellIndex(rows, rowIndex, cellIndex); 211 nodeValue = trimAndGetNodeText(table.config, node); 212 if (table.config.debug) { 213 log('Checking if value was empty on row:' + rowIndex); 214 } 215 } else { 216 keepLooking = false; 217 } 218 } 219 for (var i = 1; i < l; i++) { 220 if (parsers[i].is(nodeValue, table, node)) { 221 return parsers[i]; 222 } 223 } 224 // 0 is always the generic parser (text) 225 return parsers[0]; 226 } 227 228 function getNodeFromRowAndCellIndex(rows, rowIndex, cellIndex) { 229 return rows[rowIndex].cells[cellIndex]; 230 } 231 232 function trimAndGetNodeText(config, node) { 233 return $.trim(getElementText(config, node)); 234 } 235 236 function getParserById(name) { 237 var l = parsers.length; 238 for (var i = 0; i < l; i++) { 239 if (parsers[i].id.toLowerCase() == name.toLowerCase()) { 240 return parsers[i]; 241 } 242 } 243 return false; 244 } 245 246 /* utils */ 247 248 function buildCache(table) { 249 250 if (table.config.debug) { 251 var cacheTime = new Date(); 252 } 91 253 92 var parsers = [], widgets = []; 254 // Check the column exists - jqz 255 if (table.tBodies[0].rows.length < 1) { 256 return;} 257 var totalRows = (table.tBodies[0] && table.tBodies[0].rows.length) || 0, 258 totalCells = (table.tBodies[0].rows[0] && table.tBodies[0].rows[0].cells.length) || 0, 259 parsers = table.config.parsers, 260 cache = { 261 row: [], 262 normalized: [] 263 }; 264 265 for (var i = 0; i < totalRows; ++i) { 266 267 /** Add the table data to main data array */ 268 var c = $(table.tBodies[0].rows[i]), 269 cols = []; 270 271 // if this is a child row, add it to the last row's children and 272 // continue to the next row 273 if (c.hasClass(table.config.cssChildRow)) { 274 cache.row[cache.row.length - 1] = cache.row[cache.row.length - 1].add(c); 275 // go to the next for loop 276 continue; 277 } 278 279 cache.row.push(c); 280 281 for (var j = 0; j < totalCells; ++j) { 282 cols.push(parsers[j].format(getElementText(table.config, c[0].cells[j]), table, c[0].cells[j])); 283 } 284 285 cols.push(cache.normalized.length); // add position for rowCache 286 cache.normalized.push(cols); 287 cols = null; 288 }; 289 290 if (table.config.debug) { 291 benchmark("Building cache for " + totalRows + " rows:", cacheTime); 292 } 293 294 return cache; 295 }; 296 297 function getElementText(config, node) { 298 299 var text = ""; 300 301 if (!node) return ""; 302 303 if (!config.supportsTextContent) config.supportsTextContent = node.textContent || false; 304 305 if (config.textExtraction == "simple") { 306 if (config.supportsTextContent) { 307 text = node.textContent; 308 } else { 309 if (node.childNodes[0] && node.childNodes[0].hasChildNodes()) { 310 text = node.childNodes[0].innerHTML; 311 } else { 312 text = node.innerHTML; 313 } 314 } 315 } else { 316 if (typeof(config.textExtraction) == "function") { 317 text = config.textExtraction(node); 318 } else { 319 text = $(node).text(); 320 } 321 } 322 return text; 323 } 324 325 function appendToTable(table, cache) { 326 327 if (table.config.debug) { 328 var appendTime = new Date() 329 } 330 331 // Check the column exists - jqz 332 if (table.tBodies[0].rows.length < 1) { 333 return;} 334 335 var c = cache, 336 r = c.row, 337 n = c.normalized, 338 totalRows = n.length, 339 checkCell = (n[0].length - 1), 340 tableBody = $(table.tBodies[0]), 341 rows = []; 342 343 344 for (var i = 0; i < totalRows; i++) { 345 var pos = n[i][checkCell]; 346 347 rows.push(r[pos]); 348 349 if (!table.config.appender) { 350 351 //var o = ; 352 var l = r[pos].length; 353 for (var j = 0; j < l; j++) { 354 tableBody[0].appendChild(r[pos][j]); 355 } 356 357 // 358 } 359 } 360 361 362 363 if (table.config.appender) { 364 365 table.config.appender(table, rows); 366 } 367 368 rows = null; 369 370 if (table.config.debug) { 371 benchmark("Rebuilt table:", appendTime); 372 } 373 374 // apply table widgets 375 applyWidget(table); 376 377 // trigger sortend 378 setTimeout(function () { 379 $(table).trigger("sortEnd"); 380 }, 0); 381 382 }; 383 384 function buildHeaders(table) { 385 386 if (table.config.debug) { 387 var time = new Date(); 388 } 389 390 var meta = ($.metadata) ? true : false; 391 392 var header_index = computeTableHeaderCellIndexes(table); 393 394 $tableHeaders = $(table.config.selectorHeaders, table).each(function (index) { 395 396 this.column = header_index[this.parentNode.rowIndex + "-" + this.cellIndex]; 397 // this.column = index; 398 this.order = formatSortingOrder(table.config.sortInitialOrder); 399 400 401 this.count = this.order; 402 403 if (checkHeaderMetadata(this) || checkHeaderOptions(table, index)) this.sortDisabled = true; 404 if (checkHeaderOptionsSortingLocked(table, index)) this.order = this.lockedOrder = checkHeaderOptionsSortingLocked(table, index); 405 406 if (!this.sortDisabled) { 407 var $th = $(this).addClass(table.config.cssHeader); 408 if (table.config.onRenderHeader) table.config.onRenderHeader.apply($th); 409 } 410 411 // add cell to headerList 412 table.config.headerList[index] = this; 413 }); 414 415 if (table.config.debug) { 416 benchmark("Built headers:", time); 417 log($tableHeaders); 418 } 419 420 return $tableHeaders; 421 422 }; 423 424 // from: 425 // http://www.javascripttoolbox.com/lib/table/examples.php 426 // http://www.javascripttoolbox.com/temp/table_cellindex.html 427 428 429 function computeTableHeaderCellIndexes(t) { 430 var matrix = []; 431 var lookup = {}; 432 var thead = t.getElementsByTagName('THEAD')[0]; 433 var trs = thead.getElementsByTagName('TR'); 434 435 for (var i = 0; i < trs.length; i++) { 436 var cells = trs[i].cells; 437 for (var j = 0; j < cells.length; j++) { 438 var c = cells[j]; 439 440 var rowIndex = c.parentNode.rowIndex; 441 var cellId = rowIndex + "-" + c.cellIndex; 442 var rowSpan = c.rowSpan || 1; 443 var colSpan = c.colSpan || 1 444 var firstAvailCol; 445 if (typeof(matrix[rowIndex]) == "undefined") { 446 matrix[rowIndex] = []; 447 } 448 // Find first available column in the first row 449 for (var k = 0; k < matrix[rowIndex].length + 1; k++) { 450 if (typeof(matrix[rowIndex][k]) == "undefined") { 451 firstAvailCol = k; 452 break; 453 } 454 } 455 lookup[cellId] = firstAvailCol; 456 for (var k = rowIndex; k < rowIndex + rowSpan; k++) { 457 if (typeof(matrix[k]) == "undefined") { 458 matrix[k] = []; 459 } 460 var matrixrow = matrix[k]; 461 for (var l = firstAvailCol; l < firstAvailCol + colSpan; l++) { 462 matrixrow[l] = "x"; 463 } 464 } 465 } 466 } 467 return lookup; 468 } 469 470 function checkCellColSpan(table, rows, row) { 471 var arr = [], 472 r = table.tHead.rows, 473 c = r[row].cells; 474 475 for (var i = 0; i < c.length; i++) { 476 var cell = c[i]; 477 478 if (cell.colSpan > 1) { 479 arr = arr.concat(checkCellColSpan(table, headerArr, row++)); 480 } else { 481 if (table.tHead.length == 1 || (cell.rowSpan > 1 || !r[row + 1])) { 482 arr.push(cell); 483 } 484 // headerArr[row] = (i+row); 485 } 486 } 487 return arr; 488 }; 489 490 function checkHeaderMetadata(cell) { 491 if (($.metadata) && ($(cell).metadata().sorter === false)) { 492 return true; 493 }; 494 return false; 495 } 496 497 function checkHeaderOptions(table, i) { 498 if ((table.config.headers[i]) && (table.config.headers[i].sorter === false)) { 499 return true; 500 }; 501 return false; 502 } 93 503 94 this.defaults = { 95 cssHeader: "header", 96 cssAsc: "headerSortUp", 97 cssDesc: "headerSortDown", 98 sortInitialOrder: "asc", 99 sortMultiSortKey: "shiftKey", 100 sortForce: null, 101 sortAppend: null, 102 textExtraction: "simple", 103 parsers: {}, 104 widgets: [], 105 widgetZebra: {css: ["even","odd"]}, 106 headers: {}, 107 widthFixed: false, 108 cancelSelection: true, 109 sortList: [], 110 headerList: [], 111 dateFormat: "us", 112 decimal: '.', 113 debug: false 114 }; 504 function checkHeaderOptionsSortingLocked(table, i) { 505 if ((table.config.headers[i]) && (table.config.headers[i].lockedOrder)) return table.config.headers[i].lockedOrder; 506 return false; 507 } 115 508 116 /* debuging utils */ 117 function benchmark(s,d) { 118 log(s + "," + (new Date().getTime() - d.getTime()) + "ms"); 119 } 120 121 this.benchmark = benchmark; 122 123 function log(s) { 124 if (typeof console != "undefined" && typeof console.debug != "undefined") { 125 console.log(s); 126 } else { 127 alert(s); 128 } 129 } 130 131 /* parsers utils */ 132 function buildParserCache(table,$headers) { 509 function applyWidget(table) { 510 var c = table.config.widgets; 511 var l = c.length; 512 for (var i = 0; i < l; i++) { 513 514 getWidgetById(c[i]).format(table); 515 } 516 517 } 518 519 function getWidgetById(name) { 520 var l = widgets.length; 521 for (var i = 0; i < l; i++) { 522 if (widgets[i].id.toLowerCase() == name.toLowerCase()) { 523 return widgets[i]; 524 } 525 } 526 }; 527 528 function formatSortingOrder(v) { 529 if (typeof(v) != "Number") { 530 return (v.toLowerCase() == "desc") ? 1 : 0; 531 } else { 532 return (v == 1) ? 1 : 0; 533 } 534 } 535 536 function isValueInArray(v, a) { 537 var l = a.length; 538 for (var i = 0; i < l; i++) { 539 if (a[i][0] == v) { 540 return true; 541 } 542 } 543 return false; 544 } 545 546 function setHeadersCss(table, $headers, list, css) { 547 // remove all header information 548 $headers.removeClass(css[0]).removeClass(css[1]); 549 550 var h = []; 551 $headers.each(function (offset) { 552 if (!this.sortDisabled) { 553 h[this.column] = $(this); 554 } 555 }); 556 557 var l = list.length; 558 for (var i = 0; i < l; i++) { 559 h[list[i][0]].addClass(css[list[i][1]]); 560 } 561 } 562 563 function fixColumnWidth(table, $headers) { 564 var c = table.config; 565 if (c.widthFixed) { 566 var colgroup = $('<colgroup>'); 567 $("tr:first td", table.tBodies[0]).each(function () { 568 colgroup.append($('<col>').css('width', $(this).width())); 569 }); 570 $(table).prepend(colgroup); 571 }; 572 } 573 574 function updateHeaderSortCount(table, sortList) { 575 var c = table.config, 576 l = sortList.length; 577 for (var i = 0; i < l; i++) { 578 var s = sortList[i], 579 o = c.headerList[s[0]]; 580 o.count = s[1]; 581 o.count++; 582 } 583 } 584 585 /* sorting methods */ 586 587 function multisort(table, sortList, cache) { 588 589 if (table.config.debug) { 590 var sortTime = new Date(); 591 } 592 var dynamicExp = "var sortWrapper = function(a,b) {", 593 l = sortList.length; 594 595 // TODO: inline functions. 596 for (var i = 0; i < l; i++) { 133 597 134 if(table.config.debug) { var parsersDebug = ""; } 135 136 var rows = table.tBodies[0].rows; 137 138 if(table.tBodies[0].rows[0]) { 139 140 var list = [], cells = rows[0].cells, l = cells.length; 141 142 for (var i=0;i < l; i++) { 143 var p = false; 144 145 if($.metadata && ($($headers[i]).metadata() && $($headers[i]).metadata().sorter) ) { 146 147 p = getParserById($($headers[i]).metadata().sorter); 148 149 } else if((table.config.headers[i] && table.config.headers[i].sorter)) { 150 151 p = getParserById(table.config.headers[i].sorter); 152 } 153 if(!p) { 154 p = detectParserForColumn(table,cells[i]); 155 } 156 157 if(table.config.debug) { parsersDebug += "column:" + i + " parser:" +p.id + "\n"; } 158 159 list.push(p); 160 } 161 } 162 163 if(table.config.debug) { log(parsersDebug); } 164 165 return list; 166 }; 167 168 function detectParserForColumn(table,node) { 169 var l = parsers.length; 170 for(var i=1; i < l; i++) { 171 if(parsers[i].is($.trim(getElementText(table.config,node)),table,node)) { 172 return parsers[i]; 173 } 174 } 175 // 0 is always the generic parser (text) 176 return parsers[0]; 177 } 178 179 function getParserById(name) { 180 var l = parsers.length; 181 for(var i=0; i < l; i++) { 182 if(parsers[i].id.toLowerCase() == name.toLowerCase()) { 183 return parsers[i]; 184 } 185 } 186 return false; 187 } 188 189 /* utils */ 190 function buildCache(table) { 191 192 if(table.config.debug) { var cacheTime = new Date(); } 193 194 195 var totalRows = (table.tBodies[0] && table.tBodies[0].rows.length) || 0, 196 totalCells = (table.tBodies[0].rows[0] && table.tBodies[0].rows[0].cells.length) || 0, 197 parsers = table.config.parsers, 198 cache = {row: [], normalized: []}; 199 200 for (var i=0;i < totalRows; ++i) { 201 202 /** Add the table data to main data array */ 203 var c = table.tBodies[0].rows[i], cols = []; 204 205 cache.row.push($(c)); 206 207 for(var j=0; j < totalCells; ++j) { 208 cols.push(parsers[j].format(getElementText(table.config,c.cells[j]),table,c.cells[j])); 209 } 210 211 cols.push(i); // add position for rowCache 212 cache.normalized.push(cols); 213 cols = null; 214 }; 215 216 if(table.config.debug) { benchmark("Building cache for " + totalRows + " rows:", cacheTime); } 217 218 return cache; 219 }; 220 221 function getElementText(config,node) { 222 223 if(!node) return ""; 224 225 var t = ""; 226 227 if(config.textExtraction == "simple") { 228 if(node.childNodes[0] && node.childNodes[0].hasChildNodes()) { 229 t = node.childNodes[0].innerHTML; 230 } else { 231 t = node.innerHTML; 232 } 233 } else { 234 if(typeof(config.textExtraction) == "function") { 235 t = config.textExtraction(node); 236 } else { 237 t = $(node).text(); 238 } 239 } 240 return t; 241 } 242 243 function appendToTable(table,cache) { 244 245 if(table.config.debug) {var appendTime = new Date()} 246 247 var c = cache, 248 r = c.row, 249 n= c.normalized, 250 totalRows = n.length, 251 checkCell = (n[0].length-1), 252 tableBody = $(table.tBodies[0]), 253 rows = []; 254 255 for (var i=0;i < totalRows; i++) { 256 rows.push(r[n[i][checkCell]]); 257 if(!table.config.appender) { 258 259 var o = r[n[i][checkCell]]; 260 var l = o.length; 261 for(var j=0; j < l; j++) { 598 // Check the column exists - jqz 599 if (table.tBodies[0].rows.length < 1) { 600 return;} 601 var c = sortList[i][0]; 602 var order = sortList[i][1]; 603 // var s = (getCachedSortType(table.config.parsers,c) == "text") ? 604 // ((order == 0) ? "sortText" : "sortTextDesc") : ((order == 0) ? 605 // "sortNumeric" : "sortNumericDesc"); 606 // var s = (table.config.parsers[c].type == "text") ? ((order == 0) 607 // ? makeSortText(c) : makeSortTextDesc(c)) : ((order == 0) ? 608 // makeSortNumeric(c) : makeSortNumericDesc(c)); 609 var s = (table.config.parsers[c].type == "text") ? ((order == 0) ? makeSortFunction("text", "asc", c) : makeSortFunction("text", "desc", c)) : ((order == 0) ? makeSortFunction("numeric", "asc", c) : makeSortFunction("numeric", "desc", c)); 610 var e = "e" + i; 611 612 dynamicExp += "var " + e + " = " + s; // + "(a[" + c + "],b[" + c 613 // + "]); "; 614 dynamicExp += "if(" + e + ") { return " + e + "; } "; 615 dynamicExp += "else { "; 616 617 } 618 619 // if value is the same keep orignal order 620 var orgOrderCol = cache.normalized[0].length - 1; 621 dynamicExp += "return a[" + orgOrderCol + "]-b[" + orgOrderCol + "];"; 622 623 for (var i = 0; i < l; i++) { 624 dynamicExp += "}; "; 625 } 626 627 dynamicExp += "return 0; "; 628 dynamicExp += "}; "; 629 630 if (table.config.debug) { 631 benchmark("Evaling expression:" + dynamicExp, new Date()); 632 } 633 634 eval(dynamicExp); 635 636 cache.normalized.sort(sortWrapper); 637 638 if (table.config.debug) { 639 benchmark("Sorting on " + sortList.toString() + " and dir " + order + " time:", sortTime); 640 } 641 642 return cache; 643 }; 644 645 function makeSortFunction(type, direction, index) { 646 var a = "a[" + index + "]", 647 b = "b[" + index + "]"; 648 if (type == 'text' && direction == 'asc') { 649 return "(" + a + " == " + b + " ? 0 : (" + a + " === null ? Number.POSITIVE_INFINITY : (" + b + " === null ? Number.NEGATIVE_INFINITY : (" + a + " < " + b + ") ? -1 : 1 )));"; 650 } else if (type == 'text' && direction == 'desc') { 651 return "(" + a + " == " + b + " ? 0 : (" + a + " === null ? Number.POSITIVE_INFINITY : (" + b + " === null ? Number.NEGATIVE_INFINITY : (" + b + " < " + a + ") ? -1 : 1 )));"; 652 } else if (type == 'numeric' && direction == 'asc') { 653 return "(" + a + " === null && " + b + " === null) ? 0 :(" + a + " === null ? Number.POSITIVE_INFINITY : (" + b + " === null ? Number.NEGATIVE_INFINITY : " + a + " - " + b + "));"; 654 } else if (type == 'numeric' && direction == 'desc') { 655 return "(" + a + " === null && " + b + " === null) ? 0 :(" + a + " === null ? Number.POSITIVE_INFINITY : (" + b + " === null ? Number.NEGATIVE_INFINITY : " + b + " - " + a + "));"; 656 } 657 }; 658 659 function makeSortText(i) { 660 return "((a[" + i + "] < b[" + i + "]) ? -1 : ((a[" + i + "] > b[" + i + "]) ? 1 : 0));"; 661 }; 662 663 function makeSortTextDesc(i) { 664 return "((b[" + i + "] < a[" + i + "]) ? -1 : ((b[" + i + "] > a[" + i + "]) ? 1 : 0));"; 665 }; 666 667 function makeSortNumeric(i) { 668 return "a[" + i + "]-b[" + i + "];"; 669 }; 670 671 function makeSortNumericDesc(i) { 672 return "b[" + i + "]-a[" + i + "];"; 673 }; 674 675 function sortText(a, b) { 676 if (table.config.sortLocaleCompare) return a.localeCompare(b); 677 return ((a < b) ? -1 : ((a > b) ? 1 : 0)); 678 }; 679 680 function sortTextDesc(a, b) { 681 if (table.config.sortLocaleCompare) return b.localeCompare(a); 682 return ((b < a) ? -1 : ((b > a) ? 1 : 0)); 683 }; 684 685 function sortNumeric(a, b) { 686 return a - b; 687 }; 688 689 function sortNumericDesc(a, b) { 690 return b - a; 691 }; 692 693 function getCachedSortType(parsers, i) { 694 return parsers[i].type; 695 }; /* public methods */ 696 this.construct = function (settings) { 697 return this.each(function () { 698 // if no thead or tbody quit. 699 if (!this.tHead || !this.tBodies) return; 700 // declare 701 var $this, $document, $headers, cache, config, shiftDown = 0, 702 sortOrder; 703 // new blank config object 704 this.config = {}; 705 // merge and extend. 706 config = $.extend(this.config, $.tablesorter.defaults, settings); 707 // store common expression for speed 708 $this = $(this); 709 // save the settings where they read 710 $.data(this, "tablesorter", config); 711 // build headers 712 $headers = buildHeaders(this); 713 // try to auto detect column type, and store in tables config 714 this.config.parsers = buildParserCache(this, $headers); 715 // build the cache for the tbody cells 716 cache = buildCache(this); 717 // get the css class names, could be done else where. 718 var sortCSS = [config.cssDesc, config.cssAsc]; 719 // fixate columns if the users supplies the fixedWidth option 720 fixColumnWidth(this); 721 // apply event handling to headers 722 // this is to big, perhaps break it out? 723 $headers.click( 724 725 function (e) { 726 var totalRows = ($this[0].tBodies[0] && $this[0].tBodies[0].rows.length) || 0; 727 if (!this.sortDisabled && totalRows > 0) { 728 // Only call sortStart if sorting is 729 // enabled. 730 $this.trigger("sortStart"); 731 // store exp, for speed 732 var $cell = $(this); 733 // get current column index 734 var i = this.column; 735 // get current column sort order 736 this.order = this.count++ % 2; 737 // always sort on the locked order. 738 if(this.lockedOrder) this.order = this.lockedOrder; 262 739 263 tableBody[0].appendChild(o[j]); 264 265 } 266 267 //tableBody.append(r[n[i][checkCell]]); 268 } 269 } 270 271 if(table.config.appender) { 272 273 table.config.appender(table,rows); 274 } 275 276 rows = null; 277 278 if(table.config.debug) { benchmark("Rebuilt table:", appendTime); } 279 280 //apply table widgets 281 applyWidget(table); 282 283 // trigger sortend 284 setTimeout(function() { 285 $(table).trigger("sortEnd"); 286 },0); 287 288 }; 289 290 function buildHeaders(table) { 291 292 if(table.config.debug) { var time = new Date(); } 293 294 var meta = ($.metadata) ? true : false, tableHeadersRows = []; 295 296 for(var i = 0; i < table.tHead.rows.length; i++) { tableHeadersRows[i]=0; }; 297 298 $tableHeaders = $("thead th",table); 299 300 $tableHeaders.each(function(index) { 301 302 this.count = 0; 303 this.column = index; 304 this.order = formatSortingOrder(table.config.sortInitialOrder); 305 306 if(checkHeaderMetadata(this) || checkHeaderOptions(table,index)) this.sortDisabled = true; 307 308 if(!this.sortDisabled) { 309 $(this).addClass(table.config.cssHeader); 310 } 311 312 // add cell to headerList 313 table.config.headerList[index]= this; 314 }); 315 316 if(table.config.debug) { benchmark("Built headers:", time); log($tableHeaders); } 317 318 return $tableHeaders; 319 320 }; 321 322 function checkCellColSpan(table, rows, row) { 323 var arr = [], r = table.tHead.rows, c = r[row].cells; 324 325 for(var i=0; i < c.length; i++) { 326 var cell = c[i]; 327 328 if ( cell.colSpan > 1) { 329 arr = arr.concat(checkCellColSpan(table, headerArr,row++)); 330 } else { 331 if(table.tHead.length == 1 || (cell.rowSpan > 1 || !r[row+1])) { 332 arr.push(cell); 333 } 334 //headerArr[row] = (i+row); 335 } 336 } 337 return arr; 338 }; 339 340 function checkHeaderMetadata(cell) { 341 if(($.metadata) && ($(cell).metadata().sorter === false)) { return true; }; 342 return false; 343 } 344 345 function checkHeaderOptions(table,i) { 346 if((table.config.headers[i]) && (table.config.headers[i].sorter === false)) { return true; }; 347 return false; 348 } 349 350 function applyWidget(table) { 351 var c = table.config.widgets; 352 var l = c.length; 353 for(var i=0; i < l; i++) { 354 355 getWidgetById(c[i]).format(table); 356 } 357 358 } 359 360 function getWidgetById(name) { 361 var l = widgets.length; 362 for(var i=0; i < l; i++) { 363 if(widgets[i].id.toLowerCase() == name.toLowerCase() ) { 364 return widgets[i]; 365 } 366 } 367 }; 368 369 function formatSortingOrder(v) { 370 371 if(typeof(v) != "Number") { 372 i = (v.toLowerCase() == "desc") ? 1 : 0; 373 } else { 374 i = (v == (0 || 1)) ? v : 0; 375 } 376 return i; 377 } 378 379 function isValueInArray(v, a) { 380 var l = a.length; 381 for(var i=0; i < l; i++) { 382 if(a[i][0] == v) { 383 return true; 384 } 385 } 386 return false; 387 } 388 389 function setHeadersCss(table,$headers, list, css) { 390 // remove all header information 391 $headers.removeClass(css[0]).removeClass(css[1]); 392 393 var h = []; 394 $headers.each(function(offset) { 395 if(!this.sortDisabled) { 396 h[this.column] = $(this); 397 } 398 }); 399 400 var l = list.length; 401 for(var i=0; i < l; i++) { 402 h[list[i][0]].addClass(css[list[i][1]]); 403 } 404 } 405 406 function fixColumnWidth(table,$headers) { 407 var c = table.config; 408 if(c.widthFixed) { 409 var colgroup = $('<colgroup>'); 410 $("tr:first td",table.tBodies[0]).each(function() { 411 colgroup.append($('<col>').css('width',$(this).width())); 412 }); 413 $(table).prepend(colgroup); 414 }; 415 } 416 417 function updateHeaderSortCount(table,sortList) { 418 var c = table.config, l = sortList.length; 419 for(var i=0; i < l; i++) { 420 var s = sortList[i], o = c.headerList[s[0]]; 421 o.count = s[1]; 422 o.count++; 423 } 424 } 425 426 /* sorting methods */ 427 function multisort(table,sortList,cache) { 428 429 if(table.config.debug) { var sortTime = new Date(); } 430 431 var dynamicExp = "var sortWrapper = function(a,b) {", l = sortList.length; 432 433 for(var i=0; i < l; i++) { 434 435 var c = sortList[i][0]; 436 var order = sortList[i][1]; 437 var s = (getCachedSortType(table.config.parsers,c) == "text") ? ((order == 0) ? "sortText" : "sortTextDesc") : ((order == 0) ? "sortNumeric" : "sortNumericDesc"); 438 439 var e = "e" + i; 440 441 dynamicExp += "var " + e + " = " + s + "(a[" + c + "],b[" + c + "]); "; 442 dynamicExp += "if(" + e + ") { return " + e + "; } "; 443 dynamicExp += "else { "; 444 } 445 446 // if value is the same keep orignal order 447 var orgOrderCol = cache.normalized[0].length - 1; 448 dynamicExp += "return a[" + orgOrderCol + "]-b[" + orgOrderCol + "];"; 449 450 for(var i=0; i < l; i++) { 451 dynamicExp += "}; "; 452 } 453 454 dynamicExp += "return 0; "; 455 dynamicExp += "}; "; 456 457 eval(dynamicExp); 458 459 cache.normalized.sort(sortWrapper); 460 461 if(table.config.debug) { benchmark("Sorting on " + sortList.toString() + " and dir " + order+ " time:", sortTime); } 462 463 return cache; 464 }; 465 466 function sortText(a,b) { 467 return ((a < b) ? -1 : ((a > b) ? 1 : 0)); 468 }; 469 470 function sortTextDesc(a,b) { 471 return ((b < a) ? -1 : ((b > a) ? 1 : 0)); 472 }; 473 474 function sortNumeric(a,b) { 475 return a-b; 476 }; 477 478 function sortNumericDesc(a,b) { 479 return b-a; 480 }; 481 482 function getCachedSortType(parsers,i) { 483 return parsers[i].type; 484 }; 485 486 /* public methods */ 487 this.construct = function(settings) { 488 489 return this.each(function() { 490 491 if(!this.tHead || !this.tBodies) return; 492 493 var $this, $document,$headers, cache, config, shiftDown = 0, sortOrder; 494 495 this.config = {}; 496 497 config = $.extend(this.config, $.tablesorter.defaults, settings); 498 499 // store common expression for speed 500 $this = $(this); 501 502 // build headers 503 $headers = buildHeaders(this); 504 505 // try to auto detect column type, and store in tables config 506 this.config.parsers = buildParserCache(this,$headers); 507 508 509 // build the cache for the tbody cells 510 cache = buildCache(this); 511 512 // get the css class names, could be done else where. 513 var sortCSS = [config.cssDesc,config.cssAsc]; 514 515 // fixate columns if the users supplies the fixedWidth option 516 fixColumnWidth(this); 517 518 // apply event handling to headers 519 // this is to big, perhaps break it out? 520 $headers.click(function(e) { 521 522 $this.trigger("sortStart"); 523 524 var totalRows = ($this[0].tBodies[0] && $this[0].tBodies[0].rows.length) || 0; 525 526 if(!this.sortDisabled && totalRows > 0) { 527 528 529 // store exp, for speed 530 var $cell = $(this); 531 532 // get current column index 533 var i = this.column; 534 535 // get current column sort order 536 this.order = this.count++ % 2; 537 538 // user only whants to sort on one column 539 if(!e[config.sortMultiSortKey]) { 540 541 // flush the sort list 542 config.sortList = []; 543 544 if(config.sortForce != null) { 545 var a = config.sortForce; 546 for(var j=0; j < a.length; j++) { 547 if(a[j][0] != i) { 548 config.sortList.push(a[j]); 549 } 550 } 551 } 552 553 // add column to sort list 554 config.sortList.push([i,this.order]); 555 556 // multi column sorting 557 } else { 558 // the user has clicked on an all ready sortet column. 559 if(isValueInArray(i,config.sortList)) { 560 561 // revers the sorting direction for all tables. 562 for(var j=0; j < config.sortList.length; j++) { 563 var s = config.sortList[j], o = config.headerList[s[0]]; 564 if(s[0] == i) { 565 o.count = s[1]; 566 o.count++; 567 s[1] = o.count % 2; 568 } 569 } 570 } else { 571 // add column to sort list array 572 config.sortList.push([i,this.order]); 573 } 574 }; 575 setTimeout(function() { 576 //set css for headers 577 setHeadersCss($this[0],$headers,config.sortList,sortCSS); 578 appendToTable($this[0],multisort($this[0],config.sortList,cache)); 579 },1); 580 // stop normal event by returning false 581 return false; 582 } 583 // cancel selection 584 }).mousedown(function() { 585 if(config.cancelSelection) { 586 this.onselectstart = function() {return false}; 587 return false; 588 } 589 }); 590 591 // apply easy methods that trigger binded events 592 $this.bind("update",function() { 593 594 // rebuild parsers. 595 this.config.parsers = buildParserCache(this,$headers); 596 597 // rebuild the cache map 598 cache = buildCache(this); 599 600 }).bind("sorton",function(e,list) { 601 602 $(this).trigger("sortStart"); 603 604 config.sortList = list; 605 606 // update and store the sortlist 607 var sortList = config.sortList; 608 609 // update header count index 610 updateHeaderSortCount(this,sortList); 611 612 //set css for headers 613 setHeadersCss(this,$headers,sortList,sortCSS); 614 615 616 // sort the table and append it to the dom 617 appendToTable(this,multisort(this,sortList,cache)); 618 619 }).bind("appendCache",function() { 620 621 appendToTable(this,cache); 622 623 }).bind("applyWidgetId",function(e,id) { 624 625 getWidgetById(id).format(this); 626 627 }).bind("applyWidgets",function() { 628 // apply widgets 629 applyWidget(this); 630 }); 631 632 if($.metadata && ($(this).metadata() && $(this).metadata().sortlist)) { 633 config.sortList = $(this).metadata().sortlist; 634 } 635 // if user has supplied a sort list to constructor. 636 if(config.sortList.length > 0) { 637 $this.trigger("sorton",[config.sortList]); 638 } 639 640 // apply widgets 641 applyWidget(this); 642 }); 643 }; 644 645 this.addParser = function(parser) { 646 var l = parsers.length, a = true; 647 for(var i=0; i < l; i++) { 648 if(parsers[i].id.toLowerCase() == parser.id.toLowerCase()) { 649 a = false; 650 } 651 } 652 if(a) { parsers.push(parser); }; 653 }; 654 655 this.addWidget = function(widget) { 656 widgets.push(widget); 657 }; 658 659 this.formatFloat = function(s) { 660 var i = parseFloat(s); 661 return (isNaN(i)) ? 0 : i; 662 }; 663 this.formatInt = function(s) { 664 var i = parseInt(s); 665 return (isNaN(i)) ? 0 : i; 666 }; 667 668 this.isDigit = function(s,config) { 669 var DECIMAL = '\\' + config.decimal; 670 var exp = '/(^[+]?0(' + DECIMAL +'0+)?$)|(^([-+]?[1-9][0-9]*)$)|(^([-+]?((0?|[1-9][0-9]*)' + DECIMAL +'(0*[1-9][0-9]*)))$)|(^[-+]?[1-9]+[0-9]*' + DECIMAL +'0+$)/'; 671 return RegExp(exp).test($.trim(s)); 672 }; 673 674 this.clearTableBody = function(table) { 675 if($.browser.msie) { 676 function empty() { 677 while ( this.firstChild ) this.removeChild( this.firstChild ); 678 } 679 empty.apply(table.tBodies[0]); 680 } else { 681 table.tBodies[0].innerHTML = ""; 682 } 683 }; 684 } 685 }); 686 687 // extend plugin scope 688 $.fn.extend({ 740 // user only whants to sort on one 741 // column 742 if (!e[config.sortMultiSortKey]) { 743 // flush the sort list 744 config.sortList = []; 745 if (config.sortForce != null) { 746 var a = config.sortForce; 747 for (var j = 0; j < a.length; j++) { 748 if (a[j][0] != i) { 749 config.sortList.push(a[j]); 750 } 751 } 752 } 753 // add column to sort list 754 config.sortList.push([i, this.order]); 755 // multi column sorting 756 } else { 757 // the user has clicked on an all 758 // ready sortet column. 759 if (isValueInArray(i, config.sortList)) { 760 // revers the sorting direction 761 // for all tables. 762 for (var j = 0; j < config.sortList.length; j++) { 763 var s = config.sortList[j], 764 o = config.headerList[s[0]]; 765 if (s[0] == i) { 766 o.count = s[1]; 767 o.count++; 768 s[1] = o.count % 2; 769 } 770 } 771 } else { 772 // add column to sort list array 773 config.sortList.push([i, this.order]); 774 } 775 }; 776 setTimeout(function () { 777 // set css for headers 778 setHeadersCss($this[0], $headers, config.sortList, sortCSS); 779 appendToTable( 780 $this[0], multisort( 781 $this[0], config.sortList, cache) 782 ); 783 }, 1); 784 // stop normal event by returning false 785 return false; 786 } 787 // cancel selection 788 }).mousedown(function () { 789 if (config.cancelSelection) { 790 this.onselectstart = function () { 791 return false 792 }; 793 return false; 794 } 795 }); 796 // apply easy methods that trigger binded events 797 $this.bind("update", function () { 798 var me = this; 799 setTimeout(function () { 800 // rebuild parsers. 801 me.config.parsers = buildParserCache( 802 me, $headers); 803 // rebuild the cache map 804 cache = buildCache(me); 805 }, 1); 806 }).bind("updateCell", function (e, cell) { 807 var config = this.config; 808 // get position from the dom. 809 var pos = [(cell.parentNode.rowIndex - 1), cell.cellIndex]; 810 // update cache 811 cache.normalized[pos[0]][pos[1]] = config.parsers[pos[1]].format( 812 getElementText(config, cell), cell); 813 }).bind("sorton", function (e, list) { 814 $(this).trigger("sortStart"); 815 config.sortList = list; 816 // update and store the sortlist 817 var sortList = config.sortList; 818 // update header count index 819 updateHeaderSortCount(this, sortList); 820 // set css for headers 821 setHeadersCss(this, $headers, sortList, sortCSS); 822 // sort the table and append it to the dom 823 appendToTable(this, multisort(this, sortList, cache)); 824 }).bind("appendCache", function () { 825 appendToTable(this, cache); 826 }).bind("applyWidgetId", function (e, id) { 827 getWidgetById(id).format(this); 828 }).bind("applyWidgets", function () { 829 // apply widgets 830 applyWidget(this); 831 }); 832 if ($.metadata && ($(this).metadata() && $(this).metadata().sortlist)) { 833 config.sortList = $(this).metadata().sortlist; 834 } 835 // if user has supplied a sort list to constructor. 836 if (config.sortList.length > 0) { 837 $this.trigger("sorton", [config.sortList]); 838 } 839 // apply widgets 840 applyWidget(this); 841 }); 842 }; 843 this.addParser = function (parser) { 844 var l = parsers.length, 845 a = true; 846 for (var i = 0; i < l; i++) { 847 if (parsers[i].id.toLowerCase() == parser.id.toLowerCase()) { 848 a = false; 849 } 850 } 851 if (a) { 852 parsers.push(parser); 853 }; 854 }; 855 this.addWidget = function (widget) { 856 widgets.push(widget); 857 }; 858 this.formatFloat = function (s) { 859 var i = parseFloat(s); 860 return (isNaN(i)) ? 0 : i; 861 }; 862 this.formatInt = function (s) { 863 var i = parseInt(s); 864 return (isNaN(i)) ? 0 : i; 865 }; 866 this.isDigit = function (s, config) { 867 // replace all an wanted chars and match. 868 return /^[-+]?\d*$/.test($.trim(s.replace(/[,.']/g, ''))); 869 }; 870 this.clearTableBody = function (table) { 871 if ($.browser.msie) { 872 function empty() { 873 while (this.firstChild) 874 this.removeChild(this.firstChild); 875 } 876 empty.apply(table.tBodies[0]); 877 } else { 878 table.tBodies[0].innerHTML = ""; 879 } 880 }; 881 } 882 }); 883 884 // extend plugin scope 885 $.fn.extend({ 689 886 tablesorter: $.tablesorter.construct 690 }); 691 692 var ts = $.tablesorter; 693 694 // add default parsers 695 ts.addParser({ 696 id: "text", 697 is: function(s) { 698 return true; 699 }, 700 format: function(s) { 701 return $.trim(s.toLowerCase()); 702 }, 703 type: "text" 704 }); 705 706 ts.addParser({ 707 id: "digit", 708 is: function(s,table) { 709 var c = table.config; 710 return $.tablesorter.isDigit(s,c); 711 }, 712 format: function(s) { 713 return $.tablesorter.formatFloat(s); 714 }, 715 type: "numeric" 716 }); 717 718 ts.addParser({ 719 id: "currency", 720 is: function(s) { 721 return /^[£$€?.]/.test(s); 722 }, 723 format: function(s) { 724 return $.tablesorter.formatFloat(s.replace(new RegExp(/[^0-9.]/g),"")); 725 }, 726 type: "numeric" 727 }); 728 729 ts.addParser({ 730 id: "ipAddress", 731 is: function(s) { 732 return /^\d{2,3}[\.]\d{2,3}[\.]\d{2,3}[\.]\d{2,3}$/.test(s); 733 }, 734 format: function(s) { 735 var a = s.split("."), r = "", l = a.length; 736 for(var i = 0; i < l; i++) { 737 var item = a[i]; 738 if(item.length == 2) { 739 r += "0" + item; 740 } else { 741 r += item; 742 } 743 } 744 return $.tablesorter.formatFloat(r); 745 }, 746 type: "numeric" 747 }); 748 749 ts.addParser({ 750 id: "url", 751 is: function(s) { 752 return /^(https?|ftp|file):\/\/$/.test(s); 753 }, 754 format: function(s) { 755 return jQuery.trim(s.replace(new RegExp(/(https?|ftp|file):\/\//),'')); 756 }, 757 type: "text" 758 }); 759 760 ts.addParser({ 761 id: "isoDate", 762 is: function(s) { 763 return /^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(s); 764 }, 765 format: function(s) { 766 return $.tablesorter.formatFloat((s != "") ? new Date(s.replace(new RegExp(/-/g),"/")).getTime() : "0"); 767 }, 768 type: "numeric" 769 }); 770 771 ts.addParser({ 772 id: "percent", 773 is: function(s) { 774 return /\%$/.test($.trim(s)); 775 }, 776 format: function(s) { 777 return $.tablesorter.formatFloat(s.replace(new RegExp(/%/g),"")); 778 }, 779 type: "numeric" 780 }); 781 782 ts.addParser({ 783 id: "usLongDate", 784 is: function(s) { 785 return s.match(new RegExp(/^[A-Za-z]{3,10}\.? [0-9]{1,2}, ([0-9]{4}|'?[0-9]{2}) (([0-2]?[0-9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(AM|PM)))$/)); 786 }, 787 format: function(s) { 788 return $.tablesorter.formatFloat(new Date(s).getTime()); 789 }, 790 type: "numeric" 791 }); 792 793 ts.addParser({ 794 id: "shortDate", 795 is: function(s) { 796 return /\d{1,2}[\/\-]\d{1,2}[\/\-]\d{2,4}/.test(s); 797 }, 798 format: function(s,table) { 799 var c = table.config; 800 s = s.replace(/\-/g,"/"); 801 if(c.dateFormat == "us") { 802 // reformat the string in ISO format 803 s = s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{4})/, "$3/$1/$2"); 804 } else if(c.dateFormat == "uk") { 805 //reformat the string in ISO format 806 s = s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{4})/, "$3/$2/$1"); 807 } else if(c.dateFormat == "dd/mm/yy" || c.dateFormat == "dd-mm-yy") { 808 s = s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{2})/, "$1/$2/$3"); 809 } 810 return $.tablesorter.formatFloat(new Date(s).getTime()); 811 }, 812 type: "numeric" 813 }); 814 815 ts.addParser({ 816 id: "time", 817 is: function(s) { 818 return /^(([0-2]?[0-9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(am|pm)))$/.test(s); 819 }, 820 format: function(s) { 821 return $.tablesorter.formatFloat(new Date("2000/01/01 " + s).getTime()); 822 }, 823 type: "numeric" 824 }); 825 826 827 ts.addParser({ 828 id: "metadata", 829 is: function(s) { 830 return false; 831 }, 832 format: function(s,table,cell) { 833 var c = table.config, p = (!c.parserMetadataName) ? 'sortValue' : c.parserMetadataName; 834 return $(cell).metadata()[p]; 835 }, 836 type: "numeric" 837 }); 838 839 // add default widgets 840 ts.addWidget({ 841 id: "zebra", 842 format: function(table) { 843 if(table.config.debug) { var time = new Date(); } 844 $("tr:visible",table.tBodies[0]) 845 .filter(':even') 846 .removeClass(table.config.widgetZebra.css[1]).addClass(table.config.widgetZebra.css[0]) 847 .end().filter(':odd') 848 .removeClass(table.config.widgetZebra.css[0]).addClass(table.config.widgetZebra.css[1]); 849 if(table.config.debug) { $.tablesorter.benchmark("Applying Zebra widget", time); } 850 } 851 }); 887 }); 888 889 // make shortcut 890 var ts = $.tablesorter; 891 892 // add default parsers 893 ts.addParser({ 894 id: "text", 895 is: function (s) { 896 return true; 897 }, format: function (s) { 898 return $.trim(s.toLocaleLowerCase()); 899 }, type: "text" 900 }); 901 902 ts.addParser({ 903 id: "digit", 904 is: function (s, table) { 905 var c = table.config; 906 return $.tablesorter.isDigit(s, c); 907 }, format: function (s) { 908 return $.tablesorter.formatFloat(s); 909 }, type: "numeric" 910 }); 911 912 ts.addParser({ 913 id: "currency", 914 is: function (s) { 915 return /^[£$€?.]/.test(s); 916 }, format: function (s) { 917 return $.tablesorter.formatFloat(s.replace(new RegExp(/[£$€]/g), "")); 918 }, type: "numeric" 919 }); 920 921 ts.addParser({ 922 id: "ipAddress", 923 is: function (s) { 924 return /^\d{2,3}[\.]\d{2,3}[\.]\d{2,3}[\.]\d{2,3}$/.test(s); 925 }, format: function (s) { 926 var a = s.split("."), 927 r = "", 928 l = a.length; 929 for (var i = 0; i < l; i++) { 930 var item = a[i]; 931 if (item.length == 2) { 932 r += "0" + item; 933 } else { 934 r += item; 935 } 936 } 937 return $.tablesorter.formatFloat(r); 938 }, type: "numeric" 939 }); 940 941 ts.addParser({ 942 id: "url", 943 is: function (s) { 944 return /^(https?|ftp|file):\/\/$/.test(s); 945 }, format: function (s) { 946 return jQuery.trim(s.replace(new RegExp(/(https?|ftp|file):\/\//), '')); 947 }, type: "text" 948 }); 949 950 ts.addParser({ 951 id: "isoDate", 952 is: function (s) { 953 return /^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(s); 954 }, format: function (s) { 955 return $.tablesorter.formatFloat((s != "") ? new Date(s.replace( 956 new RegExp(/-/g), "/")).getTime() : "0"); 957 }, type: "numeric" 958 }); 959 960 ts.addParser({ 961 id: "percent", 962 is: function (s) { 963 return /\%$/.test($.trim(s)); 964 }, format: function (s) { 965 return $.tablesorter.formatFloat(s.replace(new RegExp(/%/g), "")); 966 }, type: "numeric" 967 }); 968 969 ts.addParser({ 970 id: "usLongDate", 971 is: function (s) { 972 return s.match(new RegExp(/^[A-Za-z]{3,10}\.? [0-9]{1,2}, ([0-9]{4}|'?[0-9]{2}) (([0-2]?[0-9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(AM|PM)))$/)); 973 }, format: function (s) { 974 return $.tablesorter.formatFloat(new Date(s).getTime()); 975 }, type: "numeric" 976 }); 977 978 ts.addParser({ 979 id: "shortDate", 980 is: function (s) { 981 return /\d{1,2}[\/\-]\d{1,2}[\/\-]\d{2,4}/.test(s); 982 }, format: function (s, table) { 983 var c = table.config; 984 s = s.replace(/\-/g, "/"); 985 if (c.dateFormat == "us") { 986 // reformat the string in ISO format 987 s = s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{4})/, "$3/$1/$2"); 988 } else if (c.dateFormat == "uk") { 989 // reformat the string in ISO format 990 s = s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{4})/, "$3/$2/$1"); 991 } else if (c.dateFormat == "dd/mm/yy" || c.dateFormat == "dd-mm-yy") { 992 s = s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{2})/, "$1/$2/$3"); 993 } 994 return $.tablesorter.formatFloat(new Date(s).getTime()); 995 }, type: "numeric" 996 }); 997 ts.addParser({ 998 id: "time", 999 is: function (s) { 1000 return /^(([0-2]?[0-9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(am|pm)))$/.test(s); 1001 }, format: function (s) { 1002 return $.tablesorter.formatFloat(new Date("2000/01/01 " + s).getTime()); 1003 }, type: "numeric" 1004 }); 1005 ts.addParser({ 1006 id: "metadata", 1007 is: function (s) { 1008 return false; 1009 }, format: function (s, table, cell) { 1010 var c = table.config, 1011 p = (!c.parserMetadataName) ? 'sortValue' : c.parserMetadataName; 1012 return $(cell).metadata()[p]; 1013 }, type: "numeric" 1014 }); 1015 // add default widgets 1016 ts.addWidget({ 1017 id: "zebra", 1018 format: function (table) { 1019 if (table.config.debug) { 1020 var time = new Date(); 1021 } 1022 var $tr, row = -1, 1023 odd; 1024 // loop through the visible rows 1025 $("tr:visible", table.tBodies[0]).each(function (i) { 1026 $tr = $(this); 1027 // style children rows the same way the parent 1028 // row was styled 1029 if (!$tr.hasClass(table.config.cssChildRow)) row++; 1030 odd = (row % 2 == 0); 1031 $tr.removeClass( 1032 table.config.widgetZebra.css[odd ? 0 : 1]).addClass( 1033 table.config.widgetZebra.css[odd ? 1 : 0]) 1034 }); 1035 if (table.config.debug) { 1036 $.tablesorter.benchmark("Applying Zebra widget", time); 1037 } 1038 } 1039 }); 852 1040 })(jQuery); -
extensions/nbc_ThemeChanger/main.inc.php
r10134 r10161 2 2 /* 3 3 Plugin Name: NBC ThemeChanger 4 Version: 2.2.0. A4 Version: 2.2.0.B 5 5 Description: Permet d'associer à chaque catégorie virtuel ou physique un thème spécifique. 6 6 ThemeChanger vous permet de spécifier pour chaque catérie un thème différent. -
extensions/nbc_ThemeChanger/theme/style.css
r6648 r10161 1 1 /* tables */ 2 2 3 table# tablesorter {3 table#TCtablesorter { 4 4 width: 80%; 5 5 } 6 6 7 table# tablesorter tbody .odd {7 table#TCtablesorter tbody .odd { 8 8 background-color:#ABBFFF; 9 9 } 10 10 11 table# tablesorter thead tr .header {11 table#TCtablesorter thead tr .header { 12 12 background-image: url(bg.gif); 13 13 background-repeat: no-repeat; … … 16 16 } 17 17 18 table# tablesorter thead tr .headerSortUp {18 table#TCtablesorter thead tr .headerSortUp { 19 19 background-image: url(asc.gif); 20 20 } 21 table# tablesorter thead tr .headerSortDown {21 table#TCtablesorter thead tr .headerSortDown { 22 22 background-image: url(desc.gif); 23 23 }
Note: See TracChangeset
for help on using the changeset viewer.