diff --git a/css/grid.css b/css/grid.css index c0439459..3d7d9b1a 100644 --- a/css/grid.css +++ b/css/grid.css @@ -2,20 +2,22 @@ * (Data) Grid *********************************************************/ +table.recline-grid { + table-layout: fixed; + width: 100%; +} + .recline-grid .btn-group .dropdown-toggle { padding: 1px 3px; line-height: auto; } -.recline-grid { - border: 1px solid #ccc; - width: 100%; -} - .recline-grid td, .recline-grid th { border-left: 1px solid #ccc; padding: 3px 4px; text-align: left; + word-wrap: break-word; + white-space: normal; } .recline-grid td { @@ -26,6 +28,14 @@ width: 20px; } +.recline-grid tbody tr:last-child { + border-bottom: 1px solid #ccc; +} + +.recline-grid tbody td:last-child { + border-right: 1px solid #ccc; +} + /* direct borrowing from twitter buttons */ .recline-grid th, .transform-column-view .expression-preview-table-wrapper th @@ -53,6 +63,42 @@ transition: 0.1s linear all; } +/********************************************************** + * Fixed Header - http://www.imaputz.com/cssStuff/bigFourVersion.html + *********************************************************/ + +div.table-container { + overflow: auto; +} + +/* Reset overflow value to hidden for all non-IE browsers. */ +html>body div.table-container { + overflow: hidden; +} + +/* set table header to a fixed position. WinIE 6.x only */ +/* In WinIE 6.x, any element with a position property set to relative and is a child of */ +/* an element that has an overflow property set, the relative value translates into fixed. */ +/* Ex: parent element DIV with a class of table-container has an overflow property set to auto */ +thead.fixed-header tr { + position: relative +} + +/* set THEAD element to have block level attributes. All other non-IE browsers */ +/* this enables overflow to work on TBODY element. All other non-IE, non-Mozilla browsers */ +html>body thead.fixed-header tr { + display: block +} + +/* define the table content to be scrollable */ +/* set TBODY element to have block level attributes. All other non-IE browsers */ +/* this enables overflow to work on TBODY element. All other non-IE, non-Mozilla browsers */ +/* induced side effect is that child TDs no longer accept width: auto */ +tbody.scrollContent { + display: block; + max-height: 500px; + overflow: auto; +} /********************************************************** * Data Table Menus diff --git a/src/view-grid.js b/src/view-grid.js index fc158723..eff00da6 100644 --- a/src/view-grid.js +++ b/src/view-grid.js @@ -130,8 +130,9 @@ my.Grid = Backbone.View.extend({ // ====================================================== // #### Templating template: ' \ +
\ \ - \ + \ \ {{#notEmpty}} \ \ {{/notEmpty}} \ {{#fields}} \ - \ {{/fields}} \ + \ \ \ - \ + \
\ @@ -144,7 +145,7 @@ my.Grid = Backbone.View.extend({ \ + \
\ \
\ +
\ ', toTemplateJSON: function() { + var self = this; var modelData = this.model.toJSON(); modelData.notEmpty = ( this.fields.length > 0 ); // TODO: move this sort of thing into a toTemplateJSON method on Dataset? - modelData.fields = _.map(this.fields, function(field) { return field.toJSON(); }); + modelData.fields = _.map(this.fields, function(field) { + return field.toJSON(); + }); + // last header width = scroll bar - border (2px) */ + modelData.lastHeaderWidth = this.scrollbarDimensions.width - 2; return modelData; }, render: function() { @@ -181,6 +189,20 @@ my.Grid = Backbone.View.extend({ this.fields = this.model.fields.filter(function(field) { return _.indexOf(self.state.get('hiddenFields'), field.id) == -1; }); + this.scrollbarDimensions = this.scrollbarDimensions || this._scrollbarSize(); // skip measurement if already have dimensions + var numFields = this.fields.length; + // compute field widths (-20 for first menu col + 10px for padding on each col and finally 16px for the scrollbar) + var fullWidth = self.el.width() - 20 - 10 * numFields - this.scrollbarDimensions.width; + var width = parseInt(Math.max(50, fullWidth / numFields)); + var remainder = fullWidth - numFields * width; + _.each(this.fields, function(field, idx) { + // add the remainder to the first field width so we make up full col + if (idx == 0) { + field.set({width: width+remainder}); + } else { + field.set({width: width}); + } + }); var htmls = $.mustache(this.template, this.toTemplateJSON()); this.el.html(htmls); this.model.currentDocuments.forEach(function(doc) { @@ -195,6 +217,18 @@ my.Grid = Backbone.View.extend({ }); this.el.find('.recline-grid').toggleClass('no-hidden', (self.state.get('hiddenFields').length === 0)); return this; + }, + + // ### _scrollbarSize + // + // Measure width of a vertical scrollbar and height of a horizontal scrollbar. + // + // @return: { width: pixelWidth, height: pixelHeight } + _scrollbarSize: function() { + var $c = $("
").appendTo("body"); + var dim = { width: $c.width() - $c[0].clientWidth + 1, height: $c.height() - $c[0].clientHeight }; + $c.remove(); + return dim; } }); @@ -231,7 +265,7 @@ my.GridRow = Backbone.View.extend({ \ \ {{#cells}} \ - \ + \
\   \
{{{value}}}
\ @@ -251,6 +285,7 @@ my.GridRow = Backbone.View.extend({ var cellData = this._fields.map(function(field) { return { field: field.id, + width: field.get('width'), value: doc.getFieldValue(field) }; });