The branch, master has been updated via 3c0853dc681a7e4bdb463ab27009137d63325790 (commit) via 61ea5e765db6c9382ef8fba9ab27737664b2d6cc (commit) via c4ee218fb5c1eafce1cbe47168cb920f8bf5c902 (commit) via 2a5fee1aed801560bd1498e6270f5de19e7c7e55 (commit) via f0c322cbdd168d251a47ae7ed3200e4abde7cd8d (commit) via 9ae693eb066194304c632fc4be83dc45f2e6a122 (commit) via 24150ce3a929f64f5c2cd267372f6811de7e0296 (commit) via d6fce49ca0b9d0e8ebe7f4f061f1b16c67005d58 (commit) via b140a6091cb61230c7c13ac65b9fd287f47a458b (commit) via 6665c1a88918f210dbbe0cee9fab9c22c95574bd (commit) via 5184256f10fac2b3eb11ccb6a6e3c25133c10bfb (commit) via 5304f19396dccd12b000c1366eca06b6edb4b518 (commit) via b97aeef6b6a71519af3cf39b2866629a472ea283 (commit) via 14ffb9ae84c5f749d480a7d7e71e47345eca050d (commit) via 60a0334661c25b36ccbe7caa0248dec6d641dfb5 (commit) via c7892cf5bbb7790ea725196f4a01dd2c40f43013 (commit) via 216b4e80b28110d4150c486ff8690d737f5ce442 (commit) via 22ff715452ccd849a790f9ac4d429bf226777ff7 (commit) via ba4515212a24c1d81a7251e85a82d7c8649b7604 (commit) via 4932550801b853892f98bbcaa0dcb7607da2bbe5 (commit) via 8686c60c8b9c81b6b269d833c90e4d8d990315c5 (commit) via d7857edc285872ba0f4bc0e6197464e422261d80 (commit) via 96d7a3230f52c91b768c058102c9be55b0eb0107 (commit) via 6e7d46bd285bc1201e82a706054a58b8acd2781d (commit) via cab875f3df38bdbd6db959a7916dbd087be7307f (commit) via 66cb04ead51b1d88a3e95f7439b4b8687dde8398 (commit) from cfdf3aa7c346ca90768874bfb7dd5a44920d215f (commit)
- Log ----------------------------------------------------------------- commit 3c0853dc681a7e4bdb463ab27009137d63325790 Merge: cfdf3aa7c346ca90768874bfb7dd5a44920d215f 61ea5e765db6c9382ef8fba9ab27737664b2d6cc Author: Marc Delisle marc@infomarc.info Date: Sun Jul 3 07:29:03 2011 -0400
Merge commit '61ea5e765db6c9382ef8fba9ab27737664b2d6cc'
commit 61ea5e765db6c9382ef8fba9ab27737664b2d6cc Author: Aris Feryanto aris_feryanto@yahoo.com Date: Fri Jul 1 16:19:58 2011 +0800
Shift+click: fix bug 'shift+click not working after pressing next, end, etc.'
commit c4ee218fb5c1eafce1cbe47168cb920f8bf5c902 Author: Aris Feryanto aris_feryanto@yahoo.com Date: Fri Jul 1 11:31:30 2011 +0800
Navigation bar: more compact, display horizontal/vertical mode only when configured
commit 2a5fee1aed801560bd1498e6270f5de19e7c7e55 Author: Aris Feryanto aris_feryanto@yahoo.com Date: Thu Jun 30 17:04:42 2011 +0800
Navigation bar: better support for IE
commit f0c322cbdd168d251a47ae7ed3200e4abde7cd8d Author: Aris Feryanto aris_feryanto@yahoo.com Date: Thu Jun 30 13:15:13 2011 +0800
Modify the navigation bar to provide more intuitive UI
commit 9ae693eb066194304c632fc4be83dc45f2e6a122 Merge: 24150ce3a929f64f5c2cd267372f6811de7e0296 d6fce49ca0b9d0e8ebe7f4f061f1b16c67005d58 Author: Aris Feryanto aris_feryanto@yahoo.com Date: Wed Jun 29 10:29:17 2011 +0800
Merge branch 'hidecol' into aris
commit 24150ce3a929f64f5c2cd267372f6811de7e0296 Merge: b140a6091cb61230c7c13ac65b9fd287f47a458b eb8caa4b7742cda1816598f4b5cf18f4b0616fce Author: Aris Feryanto aris_feryanto@yahoo.com Date: Wed Jun 29 10:28:00 2011 +0800
Merge remote-tracking branch 'origin/master' into aris
commit d6fce49ca0b9d0e8ebe7f4f061f1b16c67005d58 Author: Aris Feryanto aris_feryanto@yahoo.com Date: Wed Jun 29 10:27:34 2011 +0800
Show/hide column: fix bug in IE8, checkbox in column visibility list not shown
commit b140a6091cb61230c7c13ac65b9fd287f47a458b Author: Aris Feryanto aris_feryanto@yahoo.com Date: Wed Jun 29 00:13:54 2011 +0800
Disable text selection only for shift-click enabled table
commit 6665c1a88918f210dbbe0cee9fab9c22c95574bd Merge: 5184256f10fac2b3eb11ccb6a6e3c25133c10bfb 5304f19396dccd12b000c1366eca06b6edb4b518 Author: Aris Feryanto aris_feryanto@yahoo.com Date: Tue Jun 28 17:52:31 2011 +0800
Merge branch 'hidecol' into aris
commit 5184256f10fac2b3eb11ccb6a6e3c25133c10bfb Merge: b97aeef6b6a71519af3cf39b2866629a472ea283 500daacd24292fdf2524eb2a99bf86ccaf1d9e2e Author: Aris Feryanto aris_feryanto@yahoo.com Date: Tue Jun 28 17:52:27 2011 +0800
Merge remote-tracking branch 'origin/master' into aris
commit 5304f19396dccd12b000c1366eca06b6edb4b518 Author: Aris Feryanto aris_feryanto@yahoo.com Date: Tue Jun 28 17:51:59 2011 +0800
Fix bug when hovering 'More' under 'Structure' tab
commit b97aeef6b6a71519af3cf39b2866629a472ea283 Author: Aris Feryanto aris_feryanto@yahoo.com Date: Tue Jun 28 10:25:11 2011 +0800
Fix bug in shift+click
commit 14ffb9ae84c5f749d480a7d7e71e47345eca050d Merge: 60a0334661c25b36ccbe7caa0248dec6d641dfb5 c7892cf5bbb7790ea725196f4a01dd2c40f43013 Author: Aris Feryanto aris_feryanto@yahoo.com Date: Tue Jun 28 09:57:25 2011 +0800
Merge branch 'hidecol' into aris
commit 60a0334661c25b36ccbe7caa0248dec6d641dfb5 Merge: 216b4e80b28110d4150c486ff8690d737f5ce442 49a39787c3d44817c4c9056e0488d420a0e000ab Author: Aris Feryanto aris_feryanto@yahoo.com Date: Tue Jun 28 09:50:54 2011 +0800
Fix merge conflict with origin/master
commit c7892cf5bbb7790ea725196f4a01dd2c40f43013 Author: Aris Feryanto aris_feryanto@yahoo.com Date: Tue Jun 28 09:42:26 2011 +0800
Change to and some code fix
commit 216b4e80b28110d4150c486ff8690d737f5ce442 Author: Aris Feryanto aris_feryanto@yahoo.com Date: Tue Jun 28 09:33:09 2011 +0800
Better shift+click handling
commit 22ff715452ccd849a790f9ac4d429bf226777ff7 Merge: 8686c60c8b9c81b6b269d833c90e4d8d990315c5 ba4515212a24c1d81a7251e85a82d7c8649b7604 Author: Aris Feryanto aris_feryanto@yahoo.com Date: Mon Jun 27 12:10:51 2011 +0800
Merge branch 'hidecol' into aris
commit ba4515212a24c1d81a7251e85a82d7c8649b7604 Author: Aris Feryanto aris_feryanto@yahoo.com Date: Mon Jun 27 12:10:04 2011 +0800
Remove 'too many' <th> when browsing table with vertical mode and repeat headers = small value
commit 4932550801b853892f98bbcaa0dcb7607da2bbe5 Author: Aris Feryanto aris_feryanto@yahoo.com Date: Mon Jun 27 11:53:57 2011 +0800
Show/hide column: remove hide button, add column visibility hint, and some prettification
commit 8686c60c8b9c81b6b269d833c90e4d8d990315c5 Merge: 96d7a3230f52c91b768c058102c9be55b0eb0107 d7857edc285872ba0f4bc0e6197464e422261d80 Author: Aris Feryanto aris_feryanto@yahoo.com Date: Sat Jun 25 00:58:03 2011 +0800
Merge branch 'hidecol' into aris
commit d7857edc285872ba0f4bc0e6197464e422261d80 Author: Aris Feryanto aris_feryanto@yahoo.com Date: Sat Jun 25 00:57:31 2011 +0800
Show/hide column: optimize background image prefetching
commit 96d7a3230f52c91b768c058102c9be55b0eb0107 Merge: cab875f3df38bdbd6db959a7916dbd087be7307f 6e7d46bd285bc1201e82a706054a58b8acd2781d Author: Aris Feryanto aris_feryanto@yahoo.com Date: Fri Jun 24 23:57:00 2011 +0800
Merge branch 'hidecol' into aris
commit 6e7d46bd285bc1201e82a706054a58b8acd2781d Author: Aris Feryanto aris_feryanto@yahoo.com Date: Fri Jun 24 23:56:46 2011 +0800
Add image file for show/hide column
commit cab875f3df38bdbd6db959a7916dbd087be7307f Merge: 0a6f2823bd46fc3f486c0b1ef557c1e1284626ba 66cb04ead51b1d88a3e95f7439b4b8687dde8398 Author: Aris Feryanto aris_feryanto@yahoo.com Date: Fri Jun 24 18:20:31 2011 +0800
Merge branch 'hidecol' into aris
commit 66cb04ead51b1d88a3e95f7439b4b8687dde8398 Author: Aris Feryanto aris_feryanto@yahoo.com Date: Fri Jun 24 18:18:43 2011 +0800
Add new feature: show/hide column(s) while browsing a table
-----------------------------------------------------------------------
Summary of changes: Documentation.html | 6 + js/functions.js | 188 ++++++---- js/makegrid.js | 398 ++++++++++++++++---- libraries/Table.class.php | 14 +- libraries/config.default.php | 5 + libraries/config/messages.inc.php | 2 + libraries/config/setup.forms.php | 1 + libraries/config/user_preferences.forms.php | 1 + libraries/display_tbl.lib.php | 191 +++++----- sql.php | 9 +- themes/original/css/theme_right.css.php | 119 ++++++- .../img/b_more.png => original/img/col_drop.png} | Bin 1002 -> 1002 bytes themes/pmahomme/css/theme_right.css.php | 143 +++++++- themes/pmahomme/img/{b_more.png => col_drop.png} | Bin 1002 -> 1002 bytes 14 files changed, 822 insertions(+), 255 deletions(-) copy themes/{pmahomme/img/b_more.png => original/img/col_drop.png} (100%) copy themes/pmahomme/img/{b_more.png => col_drop.png} (100%)
diff --git a/Documentation.html b/Documentation.html index eb840d2..29054a2 100644 --- a/Documentation.html +++ b/Documentation.html @@ -2143,6 +2143,12 @@ setfacl -d -m "g:www-data:rwx" tmp identify what they mean. </dd>
+ <dt id="cfg_ShowDisplayDir">$cfg['ShowDisplayDir'] boolean</dt> + <dd> + Defines whether or not type display direction option is shown + when browsing a table. + </dd> + <dt id="cfg_RepeatCells">$cfg['RepeatCells'] integer</dt> <dd> Repeat the headers every X cells, or 0 to deactivate. diff --git a/js/functions.js b/js/functions.js index 397f248..e25ec98 100644 --- a/js/functions.js +++ b/js/functions.js @@ -623,24 +623,75 @@ $(document).ready(function() { if ($(e.target).is('a, img, a *')) { return; } - // XXX: FF fires two click events for <label> (label and checkbox), so we need to handle this differently var $tr = $(this); - var $checkbox = $tr.find(':checkbox'); - if ($checkbox.length) { - // checkbox in a row, add or remove class depending on checkbox state - var checked = $checkbox.attr('checked'); - if (!$(e.target).is(':checkbox, label')) { - checked = !checked; - $checkbox.attr('checked', checked); - } - if (checked) { - $tr.addClass('marked'); + + // make the table unselectable (to prevent default highlighting when shift+click) + $tr.parents('table').noSelect(); + + if (!e.shiftKey || last_clicked_row == -1) { + // usual click + + // XXX: FF fires two click events for <label> (label and checkbox), so we need to handle this differently + var $checkbox = $tr.find(':checkbox'); + if ($checkbox.length) { + // checkbox in a row, add or remove class depending on checkbox state + var checked = $checkbox.attr('checked'); + if (!$(e.target).is(':checkbox, label')) { + checked = !checked; + $checkbox.attr('checked', checked); + } + if (checked) { + $tr.addClass('marked'); + } else { + $tr.removeClass('marked'); + } + last_click_checked = checked; } else { - $tr.removeClass('marked'); + // normaln data table, just toggle class + $tr.toggleClass('marked'); + last_click_checked = false; } + + // remember the last clicked row + last_clicked_row = last_click_checked ? $('tr.odd:not(.noclick), tr.even:not(.noclick)').index(this) : -1; + last_shift_clicked_row = -1; } else { - // normaln data table, just toggle class - $tr.toggleClass('marked'); + // handle the shift click + var start, end; + + // clear last shift click result + if (last_shift_clicked_row >= 0) { + if (last_shift_clicked_row >= last_clicked_row) { + start = last_clicked_row; + end = last_shift_clicked_row; + } else { + start = last_shift_clicked_row; + end = last_clicked_row; + } + $tr.parent().find('tr.odd:not(.noclick), tr.even:not(.noclick)') + .slice(start, end + 1) + .removeClass('marked') + .find(':checkbox') + .attr('checked', false); + } + + // handle new shift click + var curr_row = $('tr.odd:not(.noclick), tr.even:not(.noclick)').index(this); + if (curr_row >= last_clicked_row) { + start = last_clicked_row; + end = curr_row; + } else { + start = curr_row; + end = last_clicked_row; + } + $tr.parent().find('tr.odd:not(.noclick), tr.even:not(.noclick)') + .slice(start, end + 1) + .addClass('marked') + .find(':checkbox') + .attr('checked', true); + + // remember the last shift clicked row + last_shift_clicked_row = curr_row; } });
@@ -653,6 +704,22 @@ $(document).ready(function() { })
/** + * True if last click is to check a row. + */ +var last_click_checked = false; + +/** + * Zero-based index of last clicked row. + * Used to handle the shift + click event in the code above. + */ +var last_clicked_row = -1; + +/** + * Zero-based index of last shift clicked row. + */ +var last_shift_clicked_row = -1; + +/** * Row highlighting in horizontal mode (use "live" * so that it works also for pages reached via AJAX) */ @@ -2037,9 +2104,9 @@ function displayMoreTableOpts() { // Optimize DOM querying var $this_dropdown = $(this); // The top offset must be set for IE even if it didn't change - var cell_right_edge_offset = $this_dropdown.parent().offset().left + $this_dropdown.parent().innerWidth(); + var cell_right_edge_offset = $this_dropdown.parent().position().left + $this_dropdown.parent().innerWidth(); var left_offset = cell_right_edge_offset - $this_dropdown.innerWidth(); - var top_offset = $this_dropdown.parent().offset().top + $this_dropdown.parent().innerHeight(); + var top_offset = $this_dropdown.parent().position().top + $this_dropdown.parent().innerHeight(); $this_dropdown.offset({ top: top_offset, left: left_offset }); });
@@ -2213,62 +2280,6 @@ $(function() { });
/** - * For the checkboxes in browse mode, handles the shift/click (only works - * in horizontal mode) and propagates the click to the "companion" checkbox - * (in both horizontal and vertical). Works also for pages reached via AJAX. - */ -$(document).ready(function() { - $('.multi_checkbox').live('click',function(e) { - var current_checkbox_id = this.id; - var left_checkbox_id = current_checkbox_id.replace('_right', '_left'); - var right_checkbox_id = current_checkbox_id.replace('_left', '_right'); - var other_checkbox_id = ''; - if (current_checkbox_id == left_checkbox_id) { - other_checkbox_id = right_checkbox_id; - } else { - other_checkbox_id = left_checkbox_id; - } - - var $current_checkbox = $('#' + current_checkbox_id); - var $other_checkbox = $('#' + other_checkbox_id); - - if (e.shiftKey) { - var index_of_current_checkbox = $('.multi_checkbox').index($current_checkbox); - var $last_checkbox = $('.multi_checkbox').filter('.last_clicked'); - var index_of_last_click = $('.multi_checkbox').index($last_checkbox); - $('.multi_checkbox') - .filter(function(index) { - // the first clicked row can be on a row above or below the - // shift-clicked row - return (index_of_current_checkbox > index_of_last_click && index > index_of_last_click && index < index_of_current_checkbox) - || (index_of_last_click > index_of_current_checkbox && index < index_of_last_click && index > index_of_current_checkbox); - }) - .each(function(index) { - var $intermediate_checkbox = $(this); - if ($current_checkbox.is(':checked')) { - $intermediate_checkbox.attr('checked', true); - } else { - $intermediate_checkbox.attr('checked', false); - } - }); - } - - $('.multi_checkbox').removeClass('last_clicked'); - $current_checkbox.addClass('last_clicked'); - - // When there is a checkbox on both ends of the row, propagate the - // click on one of them to the other one. - // (the default action has not been prevented so if we have - // just clicked, this "if" is true) - if ($current_checkbox.is(':checked')) { - $other_checkbox.attr('checked', true); - } else { - $other_checkbox.attr('checked', false); - } - }); -}) // end of $(document).ready() for multi checkbox - -/** * Get the row number from the classlist (for example, row_1) */ function PMA_getRowNumber(classlist) { @@ -2659,4 +2670,35 @@ $(document).ready(function() { if (elm.length > 0) { codemirror_editor = CodeMirror.fromTextArea(elm[0], {lineNumbers: true, matchBrackets: true, indentUnit: 4, mode: "text/x-mysql"}); } -}) +}); + +/** + * jQuery plugin to cancel selection in HTML code. + */ +(function ($) { + $.fn.noSelect = function (p) { //no select plugin by Paulo P.Marinas + var prevent = (p == null) ? true : p; + if (prevent) { + return this.each(function () { + if ($.browser.msie || $.browser.safari) $(this).bind('selectstart', function () { + return false; + }); + else if ($.browser.mozilla) { + $(this).css('MozUserSelect', 'none'); + $('body').trigger('focus'); + } else if ($.browser.opera) $(this).bind('mousedown', function () { + return false; + }); + else $(this).attr('unselectable', 'on'); + }); + } else { + return this.each(function () { + if ($.browser.msie || $.browser.safari) $(this).unbind('selectstart'); + else if ($.browser.mozilla) $(this).css('MozUserSelect', 'inherit'); + else if ($.browser.opera) $(this).unbind('mousedown'); + else $(this).removeAttr('unselectable', 'on'); + }); + } + }; //end noSelect +})(jQuery); + diff --git a/js/makegrid.js b/js/makegrid.js index 6e16db9..8b1bd7c 100644 --- a/js/makegrid.js +++ b/js/makegrid.js @@ -3,21 +3,26 @@ // prepare the grid var g = { // constant - minColWidth: 5, + minColWidth: 15,
// variables, assigned with default value, changed later alignment: 'horizontal', // 3 possibilities: vertical, horizontal, horizontalflipped actionSpan: 5, colOrder: new Array(), // array of column order + colVisib: new Array(), // array of column visibility tableCreateTime: null, // table creation time, only available in "Browse tab" hintShown: false, // true if hint balloon is shown, used by updateHint() method reorderHint: '', // string, hint for column reordering sortHint: '', // string, hint for column sorting markHint: '', // string, hint for column marking - showReorderHint: false, // boolean, used by showHint() method - showSortHint: false, // boolean, used by showHint() method + colVisibHint: '', // string, hint for column visibility drop-down + showAllColText: '', // string, text for "show all" button under column visibility list + showReorderHint: false, + showSortHint: false, showMarkHint: false, - hintIsHiding: false, // true when hint is still shown, but hide() already called + showColVisibHint: false, + hintIsHiding: false, // true when hint is still shown, but hideHint() already called + visibleHeadersCount: 0, // number of visible data headers
// functions dragStartRsz: function(e, obj) { // start column resize @@ -28,7 +33,7 @@ obj: obj, objLeft: $(obj).position().left, objWidth: this.alignment != 'vertical' ? - $(this.t).find('th.draggable:eq(' + n + ') span').outerWidth() : + $(this.t).find('th.draggable:visible:eq(' + n + ') span').outerWidth() : $(this.t).find('tr:first td:eq(' + n + ') span').outerWidth() }; $('body').css('cursor', 'col-resize'); @@ -141,20 +146,11 @@ } var n = this.colRsz.n; // do the resizing - if (this.alignment != 'vertical') { - $(this.t).find('tr').each(function() { - $(this).find('th.draggable:eq(' + n + ') span,' + - 'td:eq(' + (g.actionSpan + n) + ') span') - .css('width', nw); - }); - } else { // vertical alignment - $(this.t).find('tr').each(function() { - $(this).find('td:eq(' + n + ') span') - .css('width', nw); - }); - } + this.resize(n, nw); + $('body').css('cursor', 'default'); this.reposRsz(); + this.reposDrop(); this.colRsz = false; } else if (this.colMov) { // shift columns @@ -167,7 +163,7 @@ this.colMov.n = this.colMov.newn; // send request to server to remember the column order if (this.tableCreateTime) { - this.sendColOrder(); + this.sendColPrefs(); } this.refreshRestoreButton(); } @@ -188,18 +184,35 @@ },
/** + * Resize column n to new width "nw" + */ + resize: function(n, nw) { + if (this.alignment != 'vertical') { + $(this.t).find('tr').each(function() { + $(this).find('th.draggable:visible:eq(' + n + ') span,' + + 'td:visible:eq(' + (g.actionSpan + n) + ') span') + .css('width', nw); + }); + } else { // vertical alignment + $(this.t).find('tr').each(function() { + $(this).find('td:eq(' + n + ') span') + .css('width', nw); + }); + } + }, + + /** * Reposition column resize bars. */ reposRsz: function() { $(this.cRsz).find('div').hide(); $firstRowCols = this.alignment != 'vertical' ? - $(this.t).find('tr:first th.draggable') : + $(this.t).find('tr:first th.draggable:visible') : $(this.t).find('tr:first td'); for (var n = 0; n < $firstRowCols.length; n++) { $this = $($firstRowCols[n]); $cb = $(g.cRsz).find('div:eq(' + n + ')'); // column border - var pad = parseInt($this.css('padding-right')); - $cb.css('left', Math.floor($this.position().left + $this.width() + pad)) + $cb.css('left', $this.position().left + $this.outerWidth(true)) .show(); } }, @@ -229,16 +242,28 @@ // shift rows if (newn < oldn) { $(this.t).find('tr:eq(' + (g.actionSpan + newn) + ')') - .before($(this.t).find('tr:eq(' + (g.actionSpan + oldn) + ')')); + .before($(this.t).find('tr:eq(' + (g.actionSpan + oldn) + ')')); } else { $(this.t).find('tr:eq(' + (g.actionSpan + newn) + ')') - .after($(this.t).find('tr:eq(' + (g.actionSpan + oldn) + ')')); + .after($(this.t).find('tr:eq(' + (g.actionSpan + oldn) + ')')); } } + // adjust the column visibility list + if (newn < oldn) { + $(g.cList).find('tr:eq(' + newn + ')') + .before($(g.cList).find('tr:eq(' + oldn + ')')); + } else { + $(g.cList).find('tr:eq(' + newn + ')') + .after($(g.cList).find('tr:eq(' + oldn + ')')); + } // adjust the colOrder var tmp = this.colOrder[oldn]; this.colOrder.splice(oldn, 1); this.colOrder.splice(newn, 0, tmp); + // adjust the colVisib + var tmp = this.colVisib[oldn]; + this.colVisib.splice(oldn, 1); + this.colVisib.splice(newn, 0, tmp); },
/** @@ -247,10 +272,10 @@ */ getHoveredCol: function(e) { var hoveredCol; - $headers = $(this.t).find('th.draggable'); + $headers = $(this.t).find('th.draggable:visible'); if (this.alignment != 'vertical') { $headers.each(function() { - var left = $(this).position().left; + var left = $(this).offset().left; var right = left + $(this).outerWidth(); if (left <= e.pageX && e.pageX <= right) { hoveredCol = this; @@ -258,7 +283,7 @@ }); } else { // vertical alignment $headers.each(function() { - var top = $(this).position().top; + var top = $(this).offset().top; var bottom = top + $(this).height(); if (top <= e.pageY && e.pageY <= bottom) { hoveredCol = this; @@ -286,7 +311,7 @@ /** * Reposition the table back to normal order. */ - restore: function() { + restoreColOrder: function() { // use insertion sort, since we already have shiftCol function for (var i = 1; i < this.colOrder.length; i++) { var x = this.colOrder[i]; @@ -300,23 +325,24 @@ } if (this.tableCreateTime) { // send request to server to remember the column order - this.sendColOrder(); + this.sendColPrefs(); } this.refreshRestoreButton(); },
/** - * Send column order to the server. + * Send column preferences (column order and visibility) to the server. */ - sendColOrder: function() { + sendColPrefs: function() { $.post('sql.php', { ajax_request: true, db: window.parent.db, table: window.parent.table, token: window.parent.token, server: window.parent.server, - set_col_order: true, + set_col_prefs: true, col_order: this.colOrder.toString(), + col_visib: this.colVisib.toString(), table_create_time: this.tableCreateTime }); }, @@ -334,8 +360,10 @@ break; } } + // check if only one visible column left + var isOneColumn = this.visibleHeadersCount == 1; // enable or disable restore button - if (isInitial) { + if (isInitial || isOneColumn) { $('.restore_column').hide(); } else { $('.restore_column').show(); @@ -361,6 +389,10 @@ text += text.length > 0 ? '<br />' : ''; text += this.markHint; } + if (this.showColVisibHint && this.colVisibHint) { + text += text.length > 0 ? '<br />' : ''; + text += this.colVisibHint; + }
// hide the hint if no text if (!text) { @@ -373,8 +405,8 @@ $(this.dHint) .stop(true, true) .css({ - top: e.pageY, - left: e.pageX + 15 + top: e.clientY, + left: e.clientX + 15 }) .show('fast'); this.hintShown = true; @@ -404,18 +436,142 @@ updateHint: function(e) { if (this.hintShown) { $(this.dHint).css({ - top: e.pageY, - left: e.pageX + 15 + top: e.clientY, + left: e.clientX + 15 }); } + }, + + /** + * Toggle column's visibility. + * After calling this function and it returns true, afterToggleCol() must be called. + * + * @return boolean True if the column is toggled successfully. + */ + toggleCol: function(n) { + if (this.colVisib[n]) { + // can hide if more than one column is visible + if (this.visibleHeadersCount > 1) { + if (this.alignment != 'vertical') { + $(this.t).find('tr').each(function() { + $(this).find('th.draggable:eq(' + n + '),' + + 'td:eq(' + (g.actionSpan + n) + ')') + .hide(); + }); + } else { // vertical alignment + $(this.t).find('tr:eq(' + (g.actionSpan + n) + ')') + .hide(); + } + this.colVisib[n] = 0; + $(this.cList).find('tr:eq(' + n + ') input').removeAttr('checked'); + } else { + // cannot hide, force the checkbox to stay checked + $(this.cList).find('tr:eq(' + n + ') input').attr('checked', 'checked'); + return false; + } + } else { // column n is not visible + if (this.alignment != 'vertical') { + $(this.t).find('tr').each(function() { + $(this).find('th.draggable:eq(' + n + '),' + + 'td:eq(' + (g.actionSpan + n) + ')') + .show(); + }); + } else { // vertical alignment + $(this.t).find('tr:eq(' + (g.actionSpan + n) + ')') + .show(); + } + this.colVisib[n] = 1; + $(this.cList).find('tr:eq(' + n + ') input').attr('checked', 'checked'); + } + return true; + }, + + /** + * This must be called after calling toggleCol() and the return value is true. + * + * This function is separated from toggleCol because, sometimes, we want to toggle + * some columns together at one time and do one adjustment after it, e.g. in showAllColumns(). + */ + afterToggleCol: function() { + // some adjustments after hiding column + this.reposRsz(); + this.reposDrop(); + this.sendColPrefs(); + + // check visible first row headers count + this.visibleHeadersCount = this.alignment != 'vertical' ? + $(this.t).find('tr:first th.draggable:visible').length : + $(this.t).find('th.draggable:nth-child(1):visible').length; + this.refreshRestoreButton(); + }, + + /** + * Show columns' visibility list. + */ + showColList: function(obj) { + // only show when not resizing or reordering + if (!this.colRsz && !this.colMov) { + var pos = $(obj).position(); + // check if the list position is too right + if (pos.left + $(this.cList).outerWidth(true) > $(document).width()) { + pos.left = $(document).width() - $(this.cList).outerWidth(true); + } + $(this.cList).css({ + left: pos.left, + top: pos.top + $(obj).outerHeight(true) + }) + .show(); + $(obj).addClass('coldrop-hover'); + } + }, + + /** + * Hide columns' visibility list. + */ + hideColList: function() { + $(this.cList).hide(); + $(g.cDrop).find('.coldrop-hover').removeClass('coldrop-hover'); + }, + + /** + * Reposition the column visibility drop-down arrow. + */ + reposDrop: function() { + $th = $(t).find('th:not(.draggable)'); + for (var i = 0; i < $th.length; i++) { + var $cd = $(this.cDrop).find('div:eq(' + i + ')'); // column drop-down arrow + var pos = $($th[i]).position(); + $cd.css({ + left: pos.left + $($th[i]).width() - $cd.width(), + top: pos.top + }); + } + }, + + /** + * Show all hidden columns. + */ + showAllColumns: function() { + for (var i = 0; i < this.colVisib.length; i++) { + if (!this.colVisib[i]) { + this.toggleCol(i); + } + } + this.afterToggleCol(); } }
+ // wrap all data cells, except actions cell, with span + $(t).find('th, td:not(:has(span))') + .wrapInner('<span />'); + g.gDiv = document.createElement('div'); // create global div g.cRsz = document.createElement('div'); // column resizer g.cCpy = document.createElement('div'); // column copy, to store copy of dragged column header g.cPointer = document.createElement('div'); // column pointer, used when reordering column g.dHint = document.createElement('div'); // draggable hint + g.cDrop = document.createElement('div'); // column drop-down arrows + g.cList = document.createElement('div'); // column visibility list
// assign the table alignment g.alignment = $("#top_direction_dropdown").val(); @@ -432,6 +588,13 @@ g.dHint.className = 'dHint'; $(g.dHint).hide();
+ // adjust g.cDrop + g.cDrop.className = 'cDrop'; + + // adjust g.cList + g.cList.className = 'cList'; + $(g.cList).hide(); + // chain table and grid together t.grid = g; g.t = t; @@ -441,6 +604,14 @@ $(t).find('tr:first th.draggable') : $(t).find('tr:first td');
+ // get first row of data headers (first column of data headers, in vertical mode) + var $firstRowHeaders = g.alignment != 'vertical' ? + $(t).find('tr:first th.draggable') : + $(t).find('th.draggable:nth-child(1)'); + + // initialize g.visibleHeadersCount + g.visibleHeadersCount = $firstRowHeaders.filter(':visible').length; + // assign first column (actions) span if (! $(t).find('tr:first th:first').hasClass('draggable')) { // action header exist g.actionSpan = g.alignment != 'vertical' ? @@ -458,6 +629,8 @@ g.reorderHint = $('#col_order_hint').val(); g.sortHint = $('#sort_hint').val(); g.markHint = $('#col_mark_hint').val(); + g.colVisibHint = $('#col_visib_hint').val(); + g.showAllColText = $('#show_all_col_text').val();
// initialize column order $col_order = $('#col_order'); @@ -468,37 +641,106 @@ } } else { g.colOrder = new Array(); - for (var i = 0; i < $firstRowCols.length; i++) { + for (var i = 0; i < $firstRowHeaders.length; i++) { g.colOrder.push(i); } }
+ // initialize column visibility + $col_visib = $('#col_visib'); + if ($col_visib.length > 0) { + g.colVisib = $col_visib.val().split(','); + for (var i = 0; i < g.colVisib.length; i++) { + g.colVisib[i] = parseInt(g.colVisib[i]); + } + } else { + g.colVisib = new Array(); + for (var i = 0; i < $firstRowHeaders.length; i++) { + g.colVisib.push(1); + } + } + + if ($firstRowHeaders.length > 1) { + // create column drop-down arrow(s) + $(t).find('th:not(.draggable)').each(function() { + var cd = document.createElement('div'); // column drop-down arrow + var pos = $(this).position(); + $(cd).addClass('coldrop') + .css({ + left: pos.left + $(this).width() - $(cd).width(), + top: pos.top + }) + .click(function() { + if (g.cList.style.display == 'none') { + g.showColList(this); + } else { + g.hideColList(); + } + }); + $(g.cDrop).append(cd); + }); + + // add column visibility control + g.cList.innerHTML = '<table cellpadding="0" cellspacing="0"><tbody></tbody></table>'; + var $tbody = $(g.cList).find('tbody'); + for (var i = 0; i < $firstRowHeaders.length; i++) { + var currHeader = $firstRowHeaders[i]; + var tr = document.createElement('tr'); + $(tr).html('<td><input type="checkbox" ' + (g.colVisib[i] ? 'checked="checked" ' : '') + '/></td>' + + '<td>' + $(currHeader).text() + '</td>'); + $tbody.append(tr); + // add event on click + $(tr).click(function() { + if ( g.toggleCol($(this).index()) ) { + g.afterToggleCol(); + } + }); + } + // add "show all column" button + var showAll = document.createElement('div'); + $(showAll).addClass('showAllColBtn') + .text(g.showAllColText); + $(g.cList).append(showAll); + $(showAll).click(function() { + g.showAllColumns(); + }); + // prepend "show all column" button at top if the list is too long + if ($firstRowHeaders.length > 10) { + var clone = showAll.cloneNode(true); + $(g.cList).prepend(clone); + $(clone).click(function() { + g.showAllColumns(); + }); + } + } + // create column borders $firstRowCols.each(function() { $this = $(this); var cb = document.createElement('div'); // column border - var pad = parseInt($this.css('padding-right')); - $(cb).css('left', Math.floor($this.position().left + $this.width() + pad)); - $(cb).addClass('colborder'); - $(cb).mousedown(function(e) { - g.dragStartRsz(e, this); - }); + $(cb).addClass('colborder') + .mousedown(function(e) { + g.dragStartRsz(e, this); + }); $(g.cRsz).append(cb); }); - - // wrap all data cells, except actions cell, with span - $(t).find('th, td:not(:has(span))') - .wrapInner('<span />'); + g.reposRsz();
// register events - if ($firstRowCols.length > 1 && g.reorderHint) { // make sure columns is reorderable + if (g.reorderHint) { // make sure columns is reorderable $(t).find('th.draggable') - .css('cursor', 'move') .mousedown(function(e) { - g.dragStartMove(e, this); + if (g.visibleHeadersCount > 1) { + g.dragStartMove(e, this); + } }) .mouseenter(function(e) { - g.showReorderHint = true; + if (g.visibleHeadersCount > 1) { + g.showReorderHint = true; + $(this).css('cursor', 'move'); + } else { + $(this).css('cursor', 'inherit'); + } g.showHint(e); }) .mouseleave(function(e) { @@ -506,6 +748,15 @@ g.showHint(e); }); } + $(t).find('th:not(.draggable)') + .mouseenter(function(e) { + g.showColVisibHint = true; + g.showHint(e); + }) + .mouseleave(function(e) { + g.showColVisibHint = false; + g.showHint(e); + }); $(t).find('th.draggable a') .attr('title', '') // hide default tooltip for sorting .mouseenter(function(e) { @@ -533,7 +784,10 @@ g.dragEnd(e); }); $('.restore_column').click(function() { - g.restore(); + g.restoreColOrder(); + }); + $(t).find('td, th.draggable').mouseenter(function() { + g.hideColList(); });
// add table class @@ -543,9 +797,11 @@ $(t).before(g.gDiv); $(g.gDiv).append(t); $(g.gDiv).prepend(g.cRsz); - $(g.gDiv).append(g.cCpy); $(g.gDiv).append(g.cPointer); + $(g.gDiv).append(g.cDrop); + $(g.gDiv).append(g.cList); $(g.gDiv).append(g.dHint); + $(g.gDiv).append(g.cCpy);
// some adjustment g.refreshRestoreButton(); @@ -574,9 +830,11 @@ var t = this; $(document).ready(function() { $.grid(t); + t.grid.reposDrop(); }); } else { $.grid(this); + this.grid.reposDrop(); } }); }; @@ -588,37 +846,19 @@ if (!docready) { var t = this; $(document).ready(function() { - if (t.grid) t.grid.reposRsz(); + if (t.grid) { + t.grid.reposRsz(); + t.grid.reposDrop(); + } }); } else { - if (this.grid) this.grid.reposRsz(); + if (this.grid) { + this.grid.reposRsz(); + this.grid.reposDrop(); + } } }); } - $.fn.noSelect = function (p) { //no select plugin by Paulo P.Marinas - var prevent = (p == null) ? true : p; - if (prevent) { - return this.each(function () { - if ($.browser.msie || $.browser.safari) $(this).bind('selectstart', function () { - return false; - }); - else if ($.browser.mozilla) { - $(this).css('MozUserSelect', 'none'); - $('body').trigger('focus'); - } else if ($.browser.opera) $(this).bind('mousedown', function () { - return false; - }); - else $(this).attr('unselectable', 'on'); - }); - } else { - return this.each(function () { - if ($.browser.msie || $.browser.safari) $(this).unbind('selectstart'); - else if ($.browser.mozilla) $(this).css('MozUserSelect', 'inherit'); - else if ($.browser.opera) $(this).unbind('mousedown'); - else $(this).removeAttr('unselectable', 'on'); - }); - } - }; //end noSelect
})(jQuery);
diff --git a/libraries/Table.class.php b/libraries/Table.class.php index 8e8a8d7..37df829 100644 --- a/libraries/Table.class.php +++ b/libraries/Table.class.php @@ -16,6 +16,7 @@ class PMA_Table */ const PROP_SORTED_COLUMN = 'sorted_col'; const PROP_COLUMN_ORDER = 'col_order'; + const PROP_COLUMN_VISIB = 'col_visib';
static $cache = array();
@@ -1305,6 +1306,7 @@ class PMA_Table * Available property: * - PROP_SORTED_COLUMN * - PROP_COLUMN_ORDER + * - PROP_COLUMN_VISIB * * * @param string $property @@ -1335,7 +1337,8 @@ class PMA_Table } else { return false; } - } else if ($property == self::PROP_COLUMN_ORDER) { + } else if ($property == self::PROP_COLUMN_ORDER || + $property == self::PROP_COLUMN_VISIB) { if (isset($this->uiprefs[$property])) { // check if the table has not been modified if (self::sGetStatusInfo($this->db_name, $this->name, 'Create_time') == @@ -1361,10 +1364,11 @@ class PMA_Table * Available property: * - PROP_SORTED_COLUMN * - PROP_COLUMN_ORDER + * - PROP_COLUMN_VISIB * * @param string $property * @param mixed $value - * @param string $table_create_time Needed for PROP_COLUMN_ORDER + * @param string $table_create_time Needed for PROP_COLUMN_ORDER and PROP_COLUMN_VISIB * @return boolean|PMA_Message */ public function setUiProp($property, $value, $table_create_time = NULL) @@ -1373,8 +1377,10 @@ class PMA_Table $this->loadUiPrefs(); } // we want to save the create time if the property is PROP_COLUMN_ORDER - if ($property == self::PROP_COLUMN_ORDER) { - $curr_create_time = self::sGetStatusInfo($this->db_name, $this->name, 'Create_time'); + if ($property == self::PROP_COLUMN_ORDER || + $property == self::PROP_COLUMN_VISIB) { + + $curr_create_time = self::sGetStatusInfo($this->db_name, $this->name, 'CREATE_TIME'); if (isset($table_create_time) && $table_create_time == $curr_create_time) { $this->uiprefs['CREATE_TIME'] = $curr_create_time; diff --git a/libraries/config.default.php b/libraries/config.default.php index b355c02..809a48d 100644 --- a/libraries/config.default.php +++ b/libraries/config.default.php @@ -2313,6 +2313,11 @@ $cfg['ShowBrowseComments'] = true; $cfg['ShowPropertyComments']= true;
/** + * shows table display direction. + */ +$cfg['ShowDisplayDir'] = false; + +/** * repeat header names every X cells? (0 = deactivate) * * @global integer $cfg['RepeatCells'] diff --git a/libraries/config/messages.inc.php b/libraries/config/messages.inc.php index 5b144e1..0602cae 100644 --- a/libraries/config/messages.inc.php +++ b/libraries/config/messages.inc.php @@ -450,6 +450,8 @@ $strConfigShowAll_name = __('Allow to display all the rows'); $strConfigShowChgPassword_desc = __('Please note that enabling this has no effect with [kbd]config[/kbd] authentication mode because the password is hard coded in the configuration file; this does not limit the ability to execute the same command directly'); $strConfigShowChgPassword_name = __('Show password change form'); $strConfigShowCreateDb_name = __('Show create database form'); +$strConfigShowDisplayDir_desc = __('Defines whether or not type display direction option is shown when browsing a table'); +$strConfigShowDisplayDir_name = __('Show display direction'); $strConfigShowFieldTypesInDataEditView_desc = __('Defines whether or not type fields should be initially displayed in edit/insert mode'); $strConfigShowFieldTypesInDataEditView_name = __('Show field types'); $strConfigShowFunctionFields_desc = __('Display the function fields in edit/insert mode'); diff --git a/libraries/config/setup.forms.php b/libraries/config/setup.forms.php index 8cb473d..e1865fa 100644 --- a/libraries/config/setup.forms.php +++ b/libraries/config/setup.forms.php @@ -198,6 +198,7 @@ $forms['Main_frame']['Browse'] = array( 'Order', 'BrowsePointerEnable', 'BrowseMarkerEnable', + 'ShowDisplayDir', 'RepeatCells', 'LimitChars', 'RowActionLinks', diff --git a/libraries/config/user_preferences.forms.php b/libraries/config/user_preferences.forms.php index 38137ae..f1363b4 100644 --- a/libraries/config/user_preferences.forms.php +++ b/libraries/config/user_preferences.forms.php @@ -108,6 +108,7 @@ $forms['Main_frame']['Browse'] = array( 'DisplayBinaryAsHex', 'BrowsePointerEnable', 'BrowseMarkerEnable', + 'ShowDisplayDir', 'RepeatCells', 'LimitChars', 'RowActionLinks', diff --git a/libraries/display_tbl.lib.php b/libraries/display_tbl.lib.php index 0280d8b..988da42 100644 --- a/libraries/display_tbl.lib.php +++ b/libraries/display_tbl.lib.php @@ -293,8 +293,9 @@ function PMA_displayTableNavigation($pos_next, $pos_prev, $sql_query, $id_for_di ?>
<!-- Navigation bar --> -<table border="0" cellpadding="2" cellspacing="0" class="navigation"> +<table border="0" cellpadding="0" cellspacing="0" class="navigation"> <tr> + <td class="navigation_separator"></td> <?php // Move to the beginning or to the previous page if ($_SESSION['tmp_user_values']['pos'] && $_SESSION['tmp_user_values']['max_rows'] != 'all') { @@ -330,8 +331,7 @@ function PMA_displayTableNavigation($pos_next, $pos_prev, $sql_query, $id_for_di 5, 5, 20, - 10, - __('Page number:') + 10 ); ?> </form> @@ -344,16 +344,16 @@ function PMA_displayTableNavigation($pos_next, $pos_prev, $sql_query, $id_for_di if ($GLOBALS['cfg']['ShowAll'] && ($num_rows < $unlim_num_rows)) { echo "\n"; ?> -<td> - <form action="sql.php" method="post"> - <?php echo PMA_generate_common_hidden_inputs($db, $table); ?> - <input type="hidden" name="sql_query" value="<?php echo $html_sql_query; ?>" /> - <input type="hidden" name="pos" value="0" /> - <input type="hidden" name="session_max_rows" value="all" /> - <input type="hidden" name="goto" value="<?php echo $goto; ?>" /> - <input type="submit" name="navig" value="<?php echo __('Show all'); ?>" /> - </form> -</td> + <td> + <form action="sql.php" method="post"> + <?php echo PMA_generate_common_hidden_inputs($db, $table); ?> + <input type="hidden" name="sql_query" value="<?php echo $html_sql_query; ?>" /> + <input type="hidden" name="pos" value="0" /> + <input type="hidden" name="session_max_rows" value="all" /> + <input type="hidden" name="goto" value="<?php echo $goto; ?>" /> + <input type="submit" name="navig" value="<?php echo __('Show all'); ?>" /> + </form> + </td> <?php } // end show all
@@ -386,9 +386,17 @@ function PMA_displayTableNavigation($pos_next, $pos_prev, $sql_query, $id_for_di $onclick ); } // end move toward + + // show separator if pagination happen + if ($nbTotalPage > 1){ + echo '<td><div class="navigation_separator">|</div></td>'; + } ?> <td> - <input class="restore_column hide" type="submit" value="<?php echo __('Restore column order'); ?>" /> + <div class="restore_column hide"> + <input type="submit" value="<?php echo __('Restore column order'); ?>" /> + <div class="navigation_separator">|</div> + </div> <?php if (PMA_isSelect()) { // generate the column order, if it is set @@ -397,6 +405,10 @@ function PMA_displayTableNavigation($pos_next, $pos_prev, $sql_query, $id_for_di if ($col_order) { echo '<input id="col_order" type="hidden" value="' . implode(',', $col_order) . '" />'; } + $col_visib = $pmatable->getUiProp(PMA_Table::PROP_COLUMN_VISIB); + if ($col_visib) { + echo '<input id="col_visib" type="hidden" value="' . implode(',', $col_visib) . '" />'; + } // generate table create time echo '<input id="table_create_time" type="hidden" value="' . PMA_Table::sGetStatusInfo($GLOBALS['db'], $GLOBALS['table'], 'Create_time') . '" />'; @@ -405,40 +417,48 @@ function PMA_displayTableNavigation($pos_next, $pos_prev, $sql_query, $id_for_di echo '<input id="col_order_hint" type="hidden" value="' . __('Drag to reorder') . '" />'; echo '<input id="sort_hint" type="hidden" value="' . __('Click to sort') . '" />'; echo '<input id="col_mark_hint" type="hidden" value="' . __('Click to mark/unmark') . '" />'; + echo '<input id="col_visib_hint" type="hidden" value="' . __('Click the drop-down arrow<br />to toggle column\'s visibility') . '" />'; + echo '<input id="show_all_col_text" type="hidden" value="' . __('Show all') . '" />'; ?> </td> -</tr> -</table>
<?php // if displaying a VIEW, $unlim_num_rows could be zero because // of $cfg['MaxExactCountViews']; in this case, avoid passing // the 5th parameter to checkFormElementInRange() // (this means we can't validate the upper limit ?> -<div> - <form action="sql.php" method="post" -onsubmit="return (checkFormElementInRange(this, 'session_max_rows', '<?php echo str_replace('\'', '\\\'', __('%d is not valid row number.')); ?>', 1) && checkFormElementInRange(this, 'pos', '<?php echo str_replace('\'', '\\\'', __('%d is not valid row number.')); ?>', 0<?php echo $unlim_num_rows > 0 ? ',' . $unlim_num_rows - 1 : ''; ?>))"> - <?php echo PMA_generate_common_hidden_inputs($db, $table); ?> - <input type="hidden" name="sql_query" value="<?php echo $html_sql_query; ?>" /> - <input type="hidden" name="goto" value="<?php echo $goto; ?>" /> - <input type="submit" name="navig" <?php echo ($GLOBALS['cfg']['AjaxEnable'] ? ' class="ajax"' : ''); ?> value="<?php echo __('Show'); ?> :" /> - <input type="text" name="session_max_rows" size="3" value="<?php echo (($_SESSION['tmp_user_values']['max_rows'] != 'all') ? $_SESSION['tmp_user_values']['max_rows'] : $GLOBALS['cfg']['MaxRows']); ?>" class="textfield" onfocus="this.select()" /> - <?php echo __('row(s) starting from row #') . "\n"; ?> - <input type="text" name="pos" size="6" value="<?php echo (($pos_next >= $unlim_num_rows) ? 0 : $pos_next); ?>" class="textfield" onfocus="this.select()" /> - <?php - // Display mode (horizontal/vertical and repeat headers) - $choices = array( - 'horizontal' => __('horizontal'), - 'horizontalflipped' => __('horizontal (rotated headers)'), - 'vertical' => __('vertical')); - $param1 = PMA_generate_html_dropdown('disp_direction', $choices, $_SESSION['tmp_user_values']['disp_direction'], $id_for_direction_dropdown); - unset($choices); - - $param2 = ' <input type="text" size="3" name="repeat_cells" value="' . $_SESSION['tmp_user_values']['repeat_cells'] . '" class="textfield" />' . "\n" - . ' '; - echo ' ' . sprintf(__('in %s mode and repeat headers after %s cells'), "\n" . $param1, "\n" . $param2) . "\n"; - ?> - </form> -</div> + <td class="navigation_goto"> + <form action="sql.php" method="post" + onsubmit="return (checkFormElementInRange(this, 'session_max_rows', '<?php echo str_replace('\'', '\\\'', __('%d is not valid row number.')); ?>', 1) && checkFormElementInRange(this, 'pos', '<?php echo str_replace('\'', '\\\'', __('%d is not valid row number.')); ?>', 0<?php echo $unlim_num_rows > 0 ? ',' . $unlim_num_rows - 1 : ''; ?>))"> + <?php echo PMA_generate_common_hidden_inputs($db, $table); ?> + <input type="hidden" name="sql_query" value="<?php echo $html_sql_query; ?>" /> + <input type="hidden" name="goto" value="<?php echo $goto; ?>" /> + <input type="submit" name="navig" <?php echo ($GLOBALS['cfg']['AjaxEnable'] ? ' class="ajax"' : ''); ?> value="<?php echo __('Show'); ?> :" /> + <?php echo __('Start row') . ': ' . "\n"; ?> + <input type="text" name="pos" size="3" value="<?php echo (($pos_next >= $unlim_num_rows) ? 0 : $pos_next); ?>" class="textfield" onfocus="this.select()" /> + <?php echo __('Number of rows') . ': ' . "\n"; ?> + <input type="text" name="session_max_rows" size="3" value="<?php echo (($_SESSION['tmp_user_values']['max_rows'] != 'all') ? $_SESSION['tmp_user_values']['max_rows'] : $GLOBALS['cfg']['MaxRows']); ?>" class="textfield" onfocus="this.select()" /> + <?php + if ($GLOBALS['cfg']['ShowDisplayDir']) { + // Display mode (horizontal/vertical and repeat headers) + echo __('Mode') . ': ' . "\n"; + $choices = array( + 'horizontal' => __('horizontal'), + 'horizontalflipped' => __('horizontal (rotated headers)'), + 'vertical' => __('vertical')); + echo PMA_generate_html_dropdown('disp_direction', $choices, $_SESSION['tmp_user_values']['disp_direction'], $id_for_direction_dropdown); + unset($choices); + } + + echo __('Headers every') . ': ' . "\n"; + echo '<input type="text" size="3" name="repeat_cells" value="' . $_SESSION['tmp_user_values']['repeat_cells'] . '" class="textfield" />' . "\n"; + echo __('rows'). "\n"; + ?> + </form> + </td> + <td class="navigation_separator"></td> +</tr> +</table> + <?php } // end of the 'PMA_displayTableNavigation()' function
@@ -779,8 +799,10 @@ function PMA_displayTableHeaders(&$is_display, &$fields_meta, $fields_cnt = 0, $ // prepare to get the column order, if available $pmatable = new PMA_Table($GLOBALS['table'], $GLOBALS['db']); $col_order = $pmatable->getUiProp(PMA_Table::PROP_COLUMN_ORDER); + $col_visib = $pmatable->getUiProp(PMA_Table::PROP_COLUMN_VISIB); } else { $col_order = false; + $col_visib = false; }
for ($j = 0; $j < $fields_cnt; $j++) { @@ -921,6 +943,9 @@ function PMA_displayTableHeaders(&$is_display, &$fields_meta, $fields_cnt = 0, $ echo '<th'; $th_class = array(); $th_class[] = 'draggable'; + if ($col_visib && !$col_visib[$j]) { + $th_class[] = 'hide'; + } if ($condition_field) { $th_class[] = 'condition'; } @@ -939,7 +964,9 @@ function PMA_displayTableHeaders(&$is_display, &$fields_meta, $fields_cnt = 0, $ echo '>' . $order_link . $comments . '</th>'; } $vertical_display['desc'][] = ' <th ' - . 'class="draggable' . ($condition_field ? ' condition' : '') . '">' . "\n" + . 'class="draggable' + . ($condition_field ? ' condition' : '') + . '">' . "\n" . $order_link . $comments . ' </th>' . "\n"; } // end if (2.1)
@@ -950,6 +977,9 @@ function PMA_displayTableHeaders(&$is_display, &$fields_meta, $fields_cnt = 0, $ echo '<th'; $th_class = array(); $th_class[] = 'draggable'; + if ($col_visib && !$col_visib[$j]) { + $th_class[] = 'hide'; + } if ($condition_field) { $th_class[] = 'condition'; } @@ -971,7 +1001,9 @@ function PMA_displayTableHeaders(&$is_display, &$fields_meta, $fields_cnt = 0, $ echo "\n" . $comments . '</th>'; } $vertical_display['desc'][] = ' <th ' - . 'class="draggable' . ($condition_field ? ' condition"' : '') . '">' . "\n" + . 'class="draggable' + . ($condition_field ? ' condition"' : '') + . '">' . "\n" . ' ' . htmlspecialchars($fields_meta[$i]->name) . "\n" . $comments . ' </th>'; } // end else (2.2) @@ -1178,8 +1210,10 @@ function PMA_displayTableBody(&$dt_result, &$is_display, $map, $analyzed_sql) { if (PMA_isSelect()) { $pmatable = new PMA_Table($GLOBALS['table'], $GLOBALS['db']); $col_order = $pmatable->getUiProp(PMA_Table::PROP_COLUMN_ORDER); + $col_visib = $pmatable->getUiProp(PMA_Table::PROP_COLUMN_VISIB); } else { $col_order = false; + $col_visib = false; }
// Correction University of Virginia 19991216 in the while below @@ -1350,11 +1384,14 @@ function PMA_displayTableBody(&$dt_result, &$is_display, $map, $analyzed_sql) { $meta = $fields_meta[$i]; $not_null_class = $meta->not_null ? 'not_null' : ''; $relation_class = isset($map[$meta->name]) ? 'relation' : ''; + $hide_class = ($col_visib && !$col_visib[$j] && + // hide per <td> only if the display direction is not vertical + $_SESSION['tmp_user_values']['disp_direction'] != 'vertical') ? 'hide' : ''; $pointer = $i; $is_field_truncated = false; //If the previous column had blob data, we need to reset the class // to $inline_edit_class - $class = 'data ' . $inline_edit_class . ' ' . $not_null_class . ' ' . $alternating_color_class . ' ' . $relation_class; + $class = 'data ' . $inline_edit_class . ' ' . $not_null_class . ' ' . $alternating_color_class . ' ' . $relation_class . ' ' . $hide_class;
// See if this column should get highlight because it's used in the // where-query. @@ -1702,13 +1739,15 @@ function PMA_displayVerticalTable() echo '<th></th>' . "\n"; } echo $vertical_display['textbtn']; - $foo_counter = 0; + $cell_displayed = 0; foreach ($vertical_display['row_delete'] as $val) { - if (($foo_counter != 0) && ($_SESSION['tmp_user_values']['repeat_cells'] != 0) && !($foo_counter % $_SESSION['tmp_user_values']['repeat_cells'])) { - echo '<th></th>' . "\n"; + if (($cell_displayed != 0) && ($_SESSION['tmp_user_values']['repeat_cells'] != 0) && !($cell_displayed % $_SESSION['tmp_user_values']['repeat_cells'])) { + echo '<th' . + (($is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn') ? ' rowspan="4"' : '') . + '></th>' . "\n"; } echo str_replace('[%_PMA_CHECKBOX_DIR_%]', '_left', $val); - $foo_counter++; + $cell_displayed++; } // end while echo '</tr>' . "\n"; } // end if @@ -1720,14 +1759,8 @@ function PMA_displayVerticalTable() if (! is_array($vertical_display['row_delete'])) { echo $vertical_display['textbtn']; } - $foo_counter = 0; foreach ($vertical_display['edit'] as $val) { - if (($foo_counter != 0) && ($_SESSION['tmp_user_values']['repeat_cells'] != 0) && !($foo_counter % $_SESSION['tmp_user_values']['repeat_cells'])) { - echo ' <th></th>' . "\n"; - } - echo $val; - $foo_counter++; } // end while echo '</tr>' . "\n"; } // end if @@ -1739,14 +1772,8 @@ function PMA_displayVerticalTable() if (! is_array($vertical_display['row_delete'])) { echo $vertical_display['textbtn']; } - $foo_counter = 0; foreach ($vertical_display['copy'] as $val) { - if (($foo_counter != 0) && ($_SESSION['tmp_user_values']['repeat_cells'] != 0) && !($foo_counter % $_SESSION['tmp_user_values']['repeat_cells'])) { - echo ' <th></th>' . "\n"; - } - echo $val; - $foo_counter++; } // end while echo '</tr>' . "\n"; } // end if @@ -1758,14 +1785,8 @@ function PMA_displayVerticalTable() if (! is_array($vertical_display['edit']) && ! is_array($vertical_display['row_delete'])) { echo $vertical_display['textbtn']; } - $foo_counter = 0; foreach ($vertical_display['delete'] as $val) { - if (($foo_counter != 0) && ($_SESSION['tmp_user_values']['repeat_cells'] != 0) && !($foo_counter % $_SESSION['tmp_user_values']['repeat_cells'])) { - echo '<th></th>' . "\n"; - } - echo $val; - $foo_counter++; } // end while echo '</tr>' . "\n"; } // end if @@ -1774,8 +1795,10 @@ function PMA_displayVerticalTable() // prepare to get the column order, if available $pmatable = new PMA_Table($GLOBALS['table'], $GLOBALS['db']); $col_order = $pmatable->getUiProp(PMA_Table::PROP_COLUMN_ORDER); + $col_visib = $pmatable->getUiProp(PMA_Table::PROP_COLUMN_VISIB); } else { $col_order = false; + $col_visib = false; }
// Displays data @@ -1783,17 +1806,17 @@ function PMA_displayVerticalTable() // assign appropriate key with current column order $key = $col_order ? $col_order[$j] : $j;
- echo '<tr>' . "\n"; + echo '<tr' . (($col_visib && !$col_visib[$j]) ? ' class="hide"' : '') . '>' . "\n"; echo $val;
- $foo_counter = 0; + $cell_displayed = 0; foreach ($vertical_display['rowdata'][$key] as $subval) { - if (($foo_counter != 0) && ($_SESSION['tmp_user_values']['repeat_cells'] != 0) and !($foo_counter % $_SESSION['tmp_user_values']['repeat_cells'])) { + if (($cell_displayed != 0) && ($_SESSION['tmp_user_values']['repeat_cells'] != 0) and !($cell_displayed % $_SESSION['tmp_user_values']['repeat_cells'])) { echo $val; }
echo $subval; - $foo_counter++; + $cell_displayed++; } // end while
echo '</tr>' . "\n"; @@ -1804,14 +1827,16 @@ function PMA_displayVerticalTable() && is_array($vertical_display['row_delete']) && (count($vertical_display['row_delete']) > 0 || !empty($vertical_display['textbtn']))) { echo '<tr>' . "\n"; echo $vertical_display['textbtn']; - $foo_counter = 0; + $cell_displayed = 0; foreach ($vertical_display['row_delete'] as $val) { - if (($foo_counter != 0) && ($_SESSION['tmp_user_values']['repeat_cells'] != 0) && !($foo_counter % $_SESSION['tmp_user_values']['repeat_cells'])) { - echo '<th></th>' . "\n"; + if (($cell_displayed != 0) && ($_SESSION['tmp_user_values']['repeat_cells'] != 0) && !($cell_displayed % $_SESSION['tmp_user_values']['repeat_cells'])) { + echo '<th' . + (($is_display['edit_lnk'] != 'nn' && $is_display['del_lnk'] != 'nn') ? ' rowspan="4"' : '') . + '></th>' . "\n"; }
echo str_replace('[%_PMA_CHECKBOX_DIR_%]', '_right', $val); - $foo_counter++; + $cell_displayed++; } // end while echo '</tr>' . "\n"; } // end if @@ -1823,14 +1848,8 @@ function PMA_displayVerticalTable() if (! is_array($vertical_display['row_delete'])) { echo $vertical_display['textbtn']; } - $foo_counter = 0; foreach ($vertical_display['edit'] as $val) { - if (($foo_counter != 0) && ($_SESSION['tmp_user_values']['repeat_cells'] != 0) && !($foo_counter % $_SESSION['tmp_user_values']['repeat_cells'])) { - echo '<th></th>' . "\n"; - } - echo $val; - $foo_counter++; } // end while echo '</tr>' . "\n"; } // end if @@ -1842,14 +1861,8 @@ function PMA_displayVerticalTable() if (! is_array($vertical_display['row_delete'])) { echo $vertical_display['textbtn']; } - $foo_counter = 0; foreach ($vertical_display['copy'] as $val) { - if (($foo_counter != 0) && ($_SESSION['tmp_user_values']['repeat_cells'] != 0) && !($foo_counter % $_SESSION['tmp_user_values']['repeat_cells'])) { - echo '<th></th>' . "\n"; - } - echo $val; - $foo_counter++; } // end while echo '</tr>' . "\n"; } // end if @@ -1861,14 +1874,8 @@ function PMA_displayVerticalTable() if (! is_array($vertical_display['edit']) && ! is_array($vertical_display['row_delete'])) { echo $vertical_display['textbtn']; } - $foo_counter = 0; foreach ($vertical_display['delete'] as $val) { - if (($foo_counter != 0) && ($_SESSION['tmp_user_values']['repeat_cells'] != 0) && !($foo_counter % $_SESSION['tmp_user_values']['repeat_cells'])) { - echo '<th></th>' . "\n"; - } - echo $val; - $foo_counter++; } // end while echo '</tr>' . "\n"; } diff --git a/sql.php b/sql.php index 10985b6..543c115 100644 --- a/sql.php +++ b/sql.php @@ -164,10 +164,17 @@ if(isset($_REQUEST['get_set_values']) && $_REQUEST['get_set_values'] == true) { /** * Check ajax request to set the column order */ -if(isset($_REQUEST['set_col_order']) && $_REQUEST['set_col_order'] == true) { +if(isset($_REQUEST['set_col_prefs']) && $_REQUEST['set_col_prefs'] == true) { $pmatable = new PMA_Table($table, $db); + + // set column order $col_order = explode(',', $_REQUEST['col_order']); $retval = $pmatable->setUiProp(PMA_Table::PROP_COLUMN_ORDER, $col_order, $_REQUEST['table_create_time']); + + // set column visibility + $col_visib = explode(',', $_REQUEST['col_visib']); + $retval &= $pmatable->setUiProp(PMA_Table::PROP_COLUMN_VISIB, $col_visib, $_REQUEST['table_create_time']); + PMA_ajaxResponse(NULL, ($retval == true)); }
diff --git a/themes/original/css/theme_right.css.php b/themes/original/css/theme_right.css.php index 932f6b8..5b92cd5 100644 --- a/themes/original/css/theme_right.css.php +++ b/themes/original/css/theme_right.css.php @@ -2067,11 +2067,15 @@ span.mysql-number { border-right: solid 1px #FFFFFF; cursor: col-resize; height: 100%; - margin-left: -3px; + margin-left: -6px; position: absolute; width: 5px; }
+.pma_table td { + position: static; +} + .pma_table th.draggable span, .pma_table tbody td span { display: block; overflow: hidden; @@ -2121,9 +2125,120 @@ span.mysql-number { margin-top: -1em; opacity: 0.8; padding: 0.5em 1em; - position: absolute; + position: fixed; text-shadow: -1px -1px #000; -moz-border-radius: 0.3em; -webkit-border-radius: 0.3em; border-radius: 0.3em; } + +.data { + position: relative; +} + +.cHide { + background: #D3DCE3 url(<?php echo $_SESSION['PMA_Theme']->getImgPath(); ?>col_hide.png); + color: #CCC; + cursor: pointer; + height: 16px; + margin-left: -5px; + margin-top: 0.3em; + position: absolute; + width: 16px; +} + +.cHide:hover { + background-color: #AAA; +} + +.cDrop { + left: 0; + position: absolute; + top: 0; +} + +.coldrop { + background: url(<?php echo $_SESSION['PMA_Theme']->getImgPath(); ?>col_drop.png); + cursor: pointer; + height: 16px; + margin-left: 0.5em; + margin-top: 0.3em; + position: absolute; + width: 16px; +} + +.coldrop:hover, .coldrop-hover { + background-color: #999; +} + +.cList { + background: #EEE; + border: solid 1px #999; + position: absolute; +} + +.cList table { +} + +.cList table tr:hover { + background: #DDD; + cursor: pointer; +} + +.cList table td input { + cursor: pointer; +} + +.showAllColBtn { + border-bottom: solid 1px #999; + border-top: solid 1px #999; + cursor: pointer; + font-size: 0.9em; + font-weight: bold; + padding: 0.35em 1em; + text-align: center; +} + +.showAllColBtn:hover { + background: #DDD; +} + +.navigation { + background: #E5E5E5; + border: 1px solid black; + margin: 0.8em 0; +} + +.navigation td { + margin: 0; + padding: 0; + vertical-align: middle; + white-space: nowrap; +} + +.navigation_separator { + color: #555; + display: inline-block; + text-align: center; + width: 1.2em; + text-shadow: 1px 0 #FFF; +} + +.navigation input[type=submit] { + background: none; + border: 0; + margin: 0; + padding: 0.3em 0.5em; + min-width: 1.5em; + font-weight: bold; +} + +.navigation input[type=submit]:hover { + background: #333; + color: white; + cursor: pointer; +} + +.navigation select { + margin: 0 0.8em; +} diff --git a/themes/pmahomme/css/theme_right.css.php b/themes/pmahomme/css/theme_right.css.php index 272c17b..f2250a9 100644 --- a/themes/pmahomme/css/theme_right.css.php +++ b/themes/pmahomme/css/theme_right.css.php @@ -65,7 +65,7 @@ h2 a img{display:inline;}
.data{ margin: 0 0 12px 0; - +position: relative; }
h3 { @@ -2422,14 +2422,18 @@ span.mysql-number { }
.colborder { - border-left: 1px solid #FFF; + border-right: 1px solid #FFF; cursor: col-resize; height: 100%; - margin-left: -1px; + margin-left: -6px; position: absolute; width: 5px; }
+.pma_table td { + position: static; +} + .pma_table th.draggable span, .pma_table tbody td span { display: block; overflow: hidden; @@ -2483,9 +2487,140 @@ span.mysql-number { margin-top: -1em; opacity: 0.8; padding: 0.5em 1em; - position: absolute; + position: fixed; text-shadow: -1px -1px #000; -moz-border-radius: 0.3em; -webkit-border-radius: 0.3em; border-radius: 0.3em; } + +.cHide { + background: #EEE url(./themes/pmahomme/img/col_hide.png); + color: #CCC; + cursor: pointer; + height: 16px; + margin-left: -10px; + margin-top: 0.3em; + position: absolute; + width: 16px; +} + +.cHide:hover { + background-color: #AAA; +} + +.cDrop { + left: 0; + position: absolute; + top: 0; +} + +.coldrop { + background: url(./themes/pmahomme/img/col_drop.png); + cursor: pointer; + height: 16px; + margin-left: 0.3em; + margin-top: 0.3em; + position: absolute; + width: 16px; +} + +.coldrop:hover, .coldrop-hover { + background-color: #999; +} + +.cList { + background: #EEE; + border: solid 1px #999; + position: absolute; + -moz-box-shadow: 0 0.2em 0.5em #333; + -webkit-box-shadow: 0 0.2em 0.5em #333; + box-shadow: 0 0.2em 0.5em #333; +} + +.cList table { +} + +.cList table tr:hover { + background: #DDD; + cursor: pointer; +} + +.cList table td input { + cursor: pointer; +} + +.showAllColBtn { + border-bottom: solid 1px #999; + border-top: solid 1px #999; + cursor: pointer; + font-size: 0.9em; + font-weight: bold; + padding: 0.35em 1em; + text-align: center; +} + +.showAllColBtn:hover { + background: #DDD; +} + +.navigation { + margin: 0.8em 0; + + border-radius: 5px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + + background-image: url(./themes/svg_gradient.php?from=eeeeee&to=cccccc); + background-size: 100% 100%; + background: -webkit-gradient(linear, left top, left bottom, from(#eeeeee), to(#cccccc)); + background: -moz-linear-gradient(top, #eeeeee, #cccccc); + background: -o-linear-gradient(top, #eeeeee, #cccccc); + <?php echo PMA_ieFilter('#eeeeee', '#cccccc'); ?> +} + +.navigation td { + margin: 0; + padding: 0; + vertical-align: middle; + white-space: nowrap; +} + +.navigation_separator { + color: #999; + display: inline-block; + font-size: 1.5em; + text-align: center; + height: 1.4em; + width: 1.2em; + text-shadow: 1px 0 #FFF; +} + +.navigation input[type=submit] { + background: none; + border: 0; + filter: none; + margin: 0; + padding: 0.8em 0.5em; + + border-radius: 0; + -webkit-border-radius: 0; + -moz-border-radius: 0; +} + +.navigation input[type=submit]:hover { + color: white; + cursor: pointer; + text-shadow: none; + + background-image: url(./themes/svg_gradient.php?from=333333&to=555555); + background-size: 100% 100%; + background: -webkit-gradient(linear, left top, left bottom, from(#333333), to(#555555)); + background: -moz-linear-gradient(top, #333333, #555555); + background: -o-linear-gradient(top, #333333, #555555); + <?php echo PMA_ieFilter('#333333', '#555555'); ?> +} + +.navigation select { + margin: 0 0.8em; +}
hooks/post-receive