Fixed issue 38: [Wishlist] Fix the table header so that it's always visible when scrolling a long page
git-svn-id: http://google-refine.googlecode.com/svn/trunk@2229 7d457c2a-affb-35e4-300a-418c747d4874
This commit is contained in:
parent
a88ccd2c32
commit
98c268d9f7
@ -532,6 +532,7 @@ DataTableCellUI.prototype._startEdit = function(elmt) {
|
||||
self._cell = o.cell;
|
||||
self._dataTableView._updateCell(self._rowIndex, self._cellIndex, self._cell);
|
||||
self._render();
|
||||
self._dataTableView._adjustDataTables();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
@ -67,9 +67,13 @@ DataTableView.prototype.getSorting = function() {
|
||||
};
|
||||
|
||||
DataTableView.prototype.resize = function() {
|
||||
var topHeight = this._div.find(".viewpanel-header").outerHeight(true);
|
||||
this._adjustDataTables();
|
||||
|
||||
var topHeight =
|
||||
this._div.find(".viewpanel-header").outerHeight(true) +
|
||||
this._div.find(".data-header-table-container").outerHeight(true);
|
||||
var tableContainerIntendedHeight = this._div.innerHeight() - topHeight;
|
||||
|
||||
|
||||
var tableContainer = this._div.find(".data-table-container").css("display", "block");
|
||||
var tableContainerVPadding = tableContainer.outerHeight(true) - tableContainer.height();
|
||||
tableContainer.height((tableContainerIntendedHeight - tableContainerVPadding) + "px");
|
||||
@ -87,15 +91,18 @@ DataTableView.prototype.render = function() {
|
||||
|
||||
var html = $(
|
||||
'<div class="viewpanel-header">' +
|
||||
'<div class="viewpanel-rowrecord" bind="rowRecordControls">Show as: ' +
|
||||
'<span bind="modeSelectors"></span>' +
|
||||
'<div class="viewpanel-rowrecord" bind="rowRecordControls">Show as: ' +
|
||||
'<span bind="modeSelectors"></span>' +
|
||||
'</div>' +
|
||||
'<div class="viewpanel-pagesize" bind="pageSizeControls"></div>' +
|
||||
'<div class="viewpanel-sorting" bind="sortingControls"></div>' +
|
||||
'<div class="viewpanel-paging" bind="pagingControls"></div>' +
|
||||
'</div>' +
|
||||
'<div class="viewpanel-pagesize" bind="pageSizeControls"></div>' +
|
||||
'<div class="viewpanel-sorting" bind="sortingControls"></div>' +
|
||||
'<div class="viewpanel-paging" bind="pagingControls"></div>' +
|
||||
'<div bind="dataHeaderTableContainer" class="data-header-table-container">' +
|
||||
'<table bind="headerTable" class="data-header-table"></table>' +
|
||||
'</div>' +
|
||||
'<div bind="dataTableContainer" class="data-table-container" style="display: none;">' +
|
||||
'<table bind="table" class="data-table" cellspacing="0"></table>' +
|
||||
'<div bind="dataTableContainer" class="data-table-container">' +
|
||||
'<table bind="table" class="data-table"></table>' +
|
||||
'</div>'
|
||||
);
|
||||
var elmts = DOM.bind(html);
|
||||
@ -125,11 +132,11 @@ DataTableView.prototype.render = function() {
|
||||
this._renderSortingControls(elmts.sortingControls);
|
||||
}
|
||||
|
||||
this._renderDataTable(elmts.table[0]);
|
||||
|
||||
this._renderDataTables(elmts.table[0], elmts.headerTable[0]);
|
||||
this._div.empty().append(html);
|
||||
|
||||
this.resize();
|
||||
|
||||
|
||||
elmts.dataTableContainer[0].scrollLeft = scrollLeft;
|
||||
};
|
||||
|
||||
@ -199,7 +206,7 @@ DataTableView.prototype._renderPagingControls = function(pageSizeControls, pagin
|
||||
.appendTo(pageSizeControls);
|
||||
};
|
||||
|
||||
DataTableView.prototype._renderDataTable = function(table) {
|
||||
DataTableView.prototype._renderDataTables = function(table, headerTable) {
|
||||
var self = this;
|
||||
|
||||
var columns = theProject.columnModel.columns;
|
||||
@ -212,18 +219,20 @@ DataTableView.prototype._renderDataTable = function(table) {
|
||||
|
||||
var renderColumnKeys = function(keys) {
|
||||
if (keys.length > 0) {
|
||||
var tr = table.insertRow(table.rows.length);
|
||||
tr.insertCell(0); // star
|
||||
tr.insertCell(1); // flag
|
||||
tr.insertCell(2); // row index
|
||||
var tr = headerTable.insertRow(headerTable.rows.length);
|
||||
$(tr.insertCell(0)).attr('colspan', '3'); // star, flag, row index
|
||||
|
||||
for (var c = 0; c < columns.length; c++) {
|
||||
var column = columns[c];
|
||||
var td = tr.insertCell(tr.cells.length);
|
||||
|
||||
for (var k = 0; k < keys.length; k++) {
|
||||
if (c == keys[k]) {
|
||||
$('<img />').attr("src", "images/down-arrow.png").appendTo(td);
|
||||
break;
|
||||
if (column.name in self._collapsedColumnNames) {
|
||||
$(td).html(' ');
|
||||
} else {
|
||||
for (var k = 0; k < keys.length; k++) {
|
||||
if (c == keys[k]) {
|
||||
$('<img />').attr("src", "images/down-arrow.png").appendTo(td);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -234,10 +243,8 @@ DataTableView.prototype._renderDataTable = function(table) {
|
||||
var nextLayer = [];
|
||||
|
||||
if (groups.length > 0) {
|
||||
var tr = table.insertRow(table.rows.length);
|
||||
tr.insertCell(0); // star
|
||||
tr.insertCell(1); // flag
|
||||
tr.insertCell(2); // row index
|
||||
var tr = headerTable.insertRow(headerTable.rows.length);
|
||||
$(tr.insertCell(0)).attr('colspan', '3'); // star, flag, row index
|
||||
|
||||
for (var c = 0; c < columns.length; c++) {
|
||||
var foundGroup = false;
|
||||
@ -288,21 +295,25 @@ DataTableView.prototype._renderDataTable = function(table) {
|
||||
*------------------------------------------------------------
|
||||
*/
|
||||
|
||||
var trHead = table.insertRow(table.rows.length);
|
||||
var trHead = headerTable.insertRow(headerTable.rows.length);
|
||||
DOM.bind(
|
||||
$(trHead.insertCell(trHead.cells.length))
|
||||
.attr("colspan", "3")
|
||||
.addClass("column-header")
|
||||
.html('<div class="column-header-title"><a class="column-header-menu" bind="dropdownMenu"></a><span class="column-header-name">All</span></div>')
|
||||
.html(
|
||||
'<div class="column-header-title">' +
|
||||
'<a class="column-header-menu" bind="dropdownMenu"></a><span class="column-header-name">All</span>' +
|
||||
'</div>'
|
||||
)
|
||||
).dropdownMenu.click(function() {
|
||||
self._createMenuForAllColumns(this);
|
||||
});
|
||||
this._columnHeaderUIs = [];
|
||||
var createColumnHeader = function(column, index) {
|
||||
var td = trHead.insertCell(trHead.cells.length);
|
||||
$(td).addClass("column-header");
|
||||
$(td).addClass("column-header").attr('title', column.name);
|
||||
if (column.name in self._collapsedColumnNames) {
|
||||
$(td).html(" ").attr("title", column.name).click(function(evt) {
|
||||
$(td).html(" ").click(function(evt) {
|
||||
delete self._collapsedColumnNames[column.name];
|
||||
self.render();
|
||||
});
|
||||
@ -406,6 +417,63 @@ DataTableView.prototype._renderDataTable = function(table) {
|
||||
}
|
||||
renderRow(tr, r, row, even);
|
||||
}
|
||||
|
||||
$(table.parentNode).bind('scroll', function(evt) {
|
||||
self._adjustDataTableScroll();
|
||||
});
|
||||
};
|
||||
|
||||
DataTableView.prototype._adjustDataTables = function() {
|
||||
var dataTable = this._div.find('.data-table');
|
||||
var headerTable = this._div.find('.data-header-table');
|
||||
if (dataTable.length == 0 || headerTable.length == 0) {
|
||||
return;
|
||||
}
|
||||
dataTable = dataTable[0];
|
||||
headerTable = headerTable[0];
|
||||
|
||||
if (dataTable.rows.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var dataTr = dataTable.rows[0];
|
||||
var headerTr = headerTable.rows[headerTable.rows.length - 1];
|
||||
|
||||
var marginColumnWidths =
|
||||
$(dataTr.cells[0]).outerWidth(true) +
|
||||
$(dataTr.cells[1]).outerWidth(true) +
|
||||
$(dataTr.cells[2]).outerWidth(true) -
|
||||
DOM.getHPaddings($(headerTr.cells[0])) + 1;
|
||||
|
||||
$(headerTable)
|
||||
.find('> tbody > tr > td:first-child')
|
||||
.width('1%')
|
||||
.children()
|
||||
.first()
|
||||
.width(marginColumnWidths);
|
||||
|
||||
for (var i = 1; i < headerTr.cells.length; i++) {
|
||||
var headerTd = $(headerTr.cells[i]);
|
||||
var dataTd = $(dataTr.cells[i + 2]);
|
||||
var commonWidth = Math.max(
|
||||
Math.min(headerTd.width(), 100),
|
||||
dataTd.width()
|
||||
);
|
||||
headerTd.width('1%').find('> div').width(commonWidth);
|
||||
dataTd.children().first().width(commonWidth);
|
||||
}
|
||||
|
||||
this._adjustDataTableScroll();
|
||||
};
|
||||
|
||||
DataTableView.prototype._adjustDataTableScroll = function() {
|
||||
var dataTableContainer = this._div.find('.data-table-container');
|
||||
var headerTableContainer = this._div.find('.data-header-table-container');
|
||||
if (dataTableContainer.length > 0 && headerTableContainer.length > 0) {
|
||||
headerTableContainer
|
||||
.find('> .data-header-table')
|
||||
.css('left', '-' + dataTableContainer[0].scrollLeft + 'px');
|
||||
}
|
||||
};
|
||||
|
||||
DataTableView.prototype._showRows = function(start, onDone) {
|
||||
|
@ -35,7 +35,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
.viewpanel-header {
|
||||
position: relative;
|
||||
background: @chrome_secondary;
|
||||
background: @fill_secondary;
|
||||
font-size: 1.3em;
|
||||
padding: @padding_normal;
|
||||
overflow: hidden;
|
||||
@ -45,7 +45,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.viewpanel-rowrecord, .viewpanel-pagesize, .viewpanel-sorting {
|
||||
position: absolute;
|
||||
top: @padding_normal;
|
||||
background: @chrome_secondary;
|
||||
padding: 0 10px 0 0;
|
||||
}
|
||||
|
||||
@ -61,26 +60,46 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
.data-table-container {
|
||||
.data-header-table-container {
|
||||
border-top: 1px solid @chrome_primary;
|
||||
border-bottom: 2px solid @chrome_primary;
|
||||
background: @fill_primary;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.data-header-table {
|
||||
width: 1px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.data-table-container {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.data-table {
|
||||
.data-header-table, .data-table {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 1.1em;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.data-table td {
|
||||
.data-table td, .data-header-table td {
|
||||
padding: 2px 5px;
|
||||
border-bottom: 1px dotted #ddd;
|
||||
}
|
||||
.data-table td {
|
||||
border-bottom: 1px dotted #ddd;
|
||||
border-right: 1px solid #ddd;
|
||||
}
|
||||
.data-header-table td {
|
||||
border-bottom: 1px dotted @chrome_primary;
|
||||
border-right: 1px solid @chrome_primary;
|
||||
}
|
||||
|
||||
table.data-header-table > tbody > tr > td {
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
table.data-table > tbody > tr.even > td {
|
||||
table.data-table > tbody > tr.odd > td {
|
||||
background: @fill_secondary;
|
||||
}
|
||||
|
||||
@ -88,13 +107,12 @@ table.data-table > tbody > tr.contextual > td > div {
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
table.data-table td.column-header {
|
||||
table.data-header-table td.column-header {
|
||||
vertical-align: top;
|
||||
white-space: nowrap;
|
||||
background: #f2f2f2;
|
||||
cursor: pointer;
|
||||
padding: 4px 6px 4px 4px;
|
||||
border-right: 1px solid #ddd;
|
||||
border-bottom: none;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user