Permalink
Browse files

Added "fullWidthRows" option (issue 47), made autosizeColumns() detec…

…t whether a vertical scrollbar is present and handle the transition (scrollbar visible-hidden) if "forceFitColumns" option is set. Also, cached cell CSS rules instead of looping over and looking for them each time.
mleibman committed Jan 20, 2012
1 parent 5b6e673 commit 98a503f3048591dbd6ae3ff8565e5319b97cf37c
Showing with 63 additions and 61 deletions.
  1. +1 −0 slick.grid.css
  2. +62 −61 slick.grid.js
View
@@ -81,6 +81,7 @@ classes should alter those!
.slick-row.ui-widget-content, .slick-row.ui-state-active {
position: absolute;
border: 0px;
+ width: 100%;
}
.slick-cell, .slick-headerrow-column {
View
@@ -81,7 +81,8 @@ if (typeof Slick === "undefined") {
selectedCellCssClass: "selected",
multiSelect: true,
enableTextSelectionOnCells: false,
- dataItemColumnValueExtractor: null
+ dataItemColumnValueExtractor: null,
+ fullWidthRows: false
};
var columnDefaults = {
@@ -116,11 +117,13 @@ if (typeof Slick === "undefined") {
var $viewport;
var $canvas;
var $style;
- var stylesheet;
+ var stylesheet, columnCssRulesL = [], columnCssRulesR = [];
var viewportH, viewportW;
- var viewportHasHScroll;
+ var canvasWidth;
+ var viewportHasHScroll, viewportHasVScroll;
var headerColumnWidthDiff, headerColumnHeightDiff, cellWidthDiff, cellHeightDiff; // padding+border
var absoluteColumnMinWidth;
+ var numberOfRows = 0;
var activePosX;
var activeRow, activeCell;
@@ -318,19 +321,29 @@ if (typeof Slick === "undefined") {
return dim;
}
- function getRowWidth() {
+ function getCanvasWidth() {
+ var availableWidth = viewportHasVScroll ? viewportW - scrollbarDimensions.width : viewportW;
var rowWidth = 0;
var i = columns.length;
while (i--) {
rowWidth += (columns[i].width || columnDefaults.width);
}
- return rowWidth;
+ return options.fullWidthRows ? Math.max(rowWidth, availableWidth) : rowWidth;
}
- function setCanvasWidth(width) {
- $canvas.width(width);
- $headerRow.width(width);
- viewportHasHScroll = (width > viewportW - scrollbarDimensions.width);
+ function updateCanvasWidth(forceColumnWidthsUpdate) {
+ var oldCanvasWidth = canvasWidth;
+ canvasWidth = getCanvasWidth();
+
+ if (canvasWidth != oldCanvasWidth) {
+ $canvas.width(canvasWidth);
+ $headerRow.width(canvasWidth);
+ viewportHasHScroll = (canvasWidth > viewportW - scrollbarDimensions.width);
+ }
+
+ if (canvasWidth != oldCanvasWidth || forceColumnWidthsUpdate) {
+ applyColumnWidths();
+ }
}
function disableSelection($target) {
@@ -468,8 +481,7 @@ if (typeof Slick === "undefined") {
if (column.id === sortColumnId) {
sortAsc = !sortAsc;
- }
- else {
+ } else {
sortColumnId = column.id;
sortAsc = true;
}
@@ -516,7 +528,7 @@ if (typeof Slick === "undefined") {
}
function setupColumnResize() {
- var $col, j, c, pageX, columnElements, minPageX, maxPageX, firstResizable, lastResizable, originalCanvasWidth;
+ var $col, j, c, pageX, columnElements, minPageX, maxPageX, firstResizable, lastResizable;
columnElements = $headers.children();
columnElements.find(".slick-resizable-handle").remove();
columnElements.each(function (i, e) {
@@ -558,8 +570,7 @@ if (typeof Slick === "undefined") {
if (stretchLeewayOnRight !== null) {
if (c.maxWidth) {
stretchLeewayOnRight += c.maxWidth - c.previousWidth;
- }
- else {
+ } else {
stretchLeewayOnRight = null;
}
}
@@ -575,8 +586,7 @@ if (typeof Slick === "undefined") {
if (stretchLeewayOnLeft !== null) {
if (c.maxWidth) {
stretchLeewayOnLeft += c.maxWidth - c.previousWidth;
- }
- else {
+ } else {
stretchLeewayOnLeft = null;
}
}
@@ -597,7 +607,6 @@ if (typeof Slick === "undefined") {
}
maxPageX = pageX + Math.min(shrinkLeewayOnRight, stretchLeewayOnLeft);
minPageX = pageX - Math.min(shrinkLeewayOnLeft, stretchLeewayOnRight);
- originalCanvasWidth = $canvas.width();
})
.bind("drag", function (e, dd) {
var actualMinWidth, d = Math.min(maxPageX, Math.max(minPageX, e.pageX)) - pageX, x;
@@ -631,8 +640,6 @@ if (typeof Slick === "undefined") {
}
}
}
- } else if (options.syncColumnCellResize) {
- setCanvasWidth(originalCanvasWidth + d);
}
} else { // stretch column
x = d;
@@ -664,8 +671,6 @@ if (typeof Slick === "undefined") {
}
}
}
- } else if (options.syncColumnCellResize) {
- setCanvasWidth(originalCanvasWidth + d);
}
}
applyColumnHeaderWidths();
@@ -684,8 +689,7 @@ if (typeof Slick === "undefined") {
invalidateAllRows();
}
}
- applyColumnWidths();
- resizeCanvas();
+ updateCanvasWidth(true);
trigger(self.onColumnsResized, {});
});
});
@@ -732,27 +736,22 @@ if (typeof Slick === "undefined") {
function createCssRules() {
$style = $("<style type='text/css' rel='stylesheet' />").appendTo($("head"));
var rowHeight = (options.rowHeight - cellHeightDiff);
- var rowWidth = getRowWidth();
var rules = [
"." + uid + " .slick-header-column { left: 1000px; }",
"." + uid + " .slick-top-panel { height:" + options.topPanelHeight + "px; }",
"." + uid + " .slick-headerrow-columns { height:" + options.headerRowHeight + "px; }",
"." + uid + " .slick-cell { height:" + rowHeight + "px; }",
- "." + uid + " .slick-row { width:" + getRowWidth() + "px; height:" + options.rowHeight + "px; }"
+ "." + uid + " .slick-row { height:" + options.rowHeight + "px; }"
];
- var x = 0, w;
for (var i = 0; i < columns.length; i++) {
- w = columns[i].width;
- rules.push("." + uid + " .l" + i + " { left: " + x + "px; }");
- rules.push("." + uid + " .r" + i + " { right: " + (rowWidth - x - w) + "px; }");
- x += columns[i].width;
+ rules.push("." + uid + " .l" + i + " { }");
+ rules.push("." + uid + " .r" + i + " { }");
}
if ($style[0].styleSheet) { // IE
$style[0].styleSheet.cssText = rules.join(" ");
- }
- else {
+ } else {
$style[0].appendChild(document.createTextNode(rules.join(" ")));
}
@@ -763,16 +762,20 @@ if (typeof Slick === "undefined") {
break;
}
}
- }
- function findCssRule(selector) {
- var rules = (stylesheet.cssRules || stylesheet.rules);
- for (var i = 0; i < rules.length; i++) {
- if (rules[i].selectorText == selector) {
- return rules[i];
+ // find and cache column CSS rules
+ columnCssRulesL = [], columnCssRulesR = [];
+ var cssRules = (stylesheet.cssRules || stylesheet.rules);
+ var matches, columnIdx;
+ for (var i = 0; i < cssRules.length; i++) {
+ if (matches = /\.l\d+/.exec(cssRules[i].selectorText)) {
+ columnIdx = parseInt(matches[0].substr(2, matches[0].length - 2), 10);
+ columnCssRulesL[columnIdx] = cssRules[i];
+ } else if (matches = /\.r\d+/.exec(cssRules[i].selectorText)) {
+ columnIdx = parseInt(matches[0].substr(2, matches[0].length - 2), 10);
+ columnCssRulesR[columnIdx] = cssRules[i];
}
}
- return null;
}
function removeCssRules() {
@@ -827,10 +830,9 @@ if (typeof Slick === "undefined") {
var i, c,
widths = [],
shrinkLeeway = 0,
- // with AutoHeight, we do not need to accommodate the vertical scroll bar
- availWidth = (options.autoHeight ? viewportW : viewportW - scrollbarDimensions.width),
total = 0,
- existingTotal = 0;
+ existingTotal = 0,
+ availWidth = viewportHasVScroll ? viewportW - scrollbarDimensions.width : viewportW;
for (i = 0; i < columns.length; i++) {
c = columns[i];
@@ -841,8 +843,6 @@ if (typeof Slick === "undefined") {
total = existingTotal;
- invalidateAllRows();
-
// shrink
while (total > availWidth) {
if (!shrinkLeeway) {
@@ -884,8 +884,7 @@ if (typeof Slick === "undefined") {
}
applyColumnHeaderWidths();
- applyColumnWidths();
- resizeCanvas();
+ updateCanvasWidth(true);
}
function applyColumnHeaderWidths() {
@@ -899,22 +898,18 @@ if (typeof Slick === "undefined") {
}
function applyColumnWidths() {
- var rowWidth = getRowWidth();
var x = 0, w, rule;
for (var i = 0; i < columns.length; i++) {
w = columns[i].width;
- rule = findCssRule("." + uid + " .l" + i);
+ rule = columnCssRulesL[i];
rule.style.left = x + "px";
- rule = findCssRule("." + uid + " .r" + i);
- rule.style.right = (rowWidth - x - w) + "px";
+ rule = columnCssRulesR[i];
+ rule.style.right = (canvasWidth - x - w) + "px";
x += columns[i].width;
}
-
- rule = findCssRule("." + uid + " .slick-row");
- rule.style.width = rowWidth + "px";
}
function setSortColumn(columnId, ascending) {
@@ -1263,11 +1258,6 @@ if (typeof Slick === "undefined") {
viewportW = parseFloat($.css($container[0], "width", true));
$viewport.height(viewportH);
- var w = 0, i = columns.length;
- while (i--) {
- w += columns[i].width;
- }
- setCanvasWidth(w);
updateRowCount();
render();
}
@@ -1281,9 +1271,13 @@ if (typeof Slick === "undefined") {
}
function updateRowCount() {
- var newRowCount = getDataLength() + (options.enableAddRow ? 1 : 0) +
+ numberOfRows = getDataLength() +
+ (options.enableAddRow ? 1 : 0) +
(options.leaveSpaceForNewRows ? numVisibleRows - 1 : 0);
- var oldH = h;
+
+ var oldViewportHasVScroll = viewportHasVScroll;
+ // with autoHeight, we do not need to accommodate the vertical scroll bar
+ viewportHasVScroll = !options.autoHeight && (numberOfRows * options.rowHeight > viewportH);
// remove the rows that are now outside of the data range
// this helps avoid redundant calls to .removeRow() when the size of the data decreased by thousands of rows
@@ -1293,7 +1287,9 @@ if (typeof Slick === "undefined") {
removeRowFromCache(i);
}
}
- th = Math.max(options.rowHeight * newRowCount, viewportH - scrollbarDimensions.height);
+
+ var oldH = h;
+ th = Math.max(options.rowHeight * numberOfRows, viewportH - scrollbarDimensions.height);
if (th < maxSupportedCssHeight) {
// just one page
h = ph = th;
@@ -1327,6 +1323,11 @@ if (typeof Slick === "undefined") {
if (h != oldH && options.autoHeight) {
resizeCanvas();
}
+
+ if (options.forceFitColumns && oldViewportHasVScroll != viewportHasVScroll) {
+ autosizeColumns();
+ }
+ updateCanvasWidth(false);
}
function getVisibleRange(viewportTop) {

0 comments on commit 98a503f

Please sign in to comment.