summaryrefslogtreecommitdiffstats
path: root/slick.grid.js
diff options
context:
space:
mode:
Diffstat (limited to 'slick.grid.js')
-rw-r--r--slick.grid.js180
1 files changed, 144 insertions, 36 deletions
diff --git a/slick.grid.js b/slick.grid.js
index a20cf39..42ac051 100644
--- a/slick.grid.js
+++ b/slick.grid.js
@@ -429,6 +429,7 @@ if (!jQuery.fn.drag) {
resizeAndRender();
+ bindAncestorScrollEvents();
$viewport.bind("scroll", handleScroll);
$container.bind("resize", resizeAndRender);
$canvas.bind("keydown", handleKeyDown);
@@ -439,6 +440,20 @@ if (!jQuery.fn.drag) {
$headerScroller.bind("contextmenu", handleHeaderContextMenu);
}
+ // TODO: this is static. need to handle page mutation.
+ function bindAncestorScrollEvents() {
+ var elem = $canvas[0];
+ while ((elem = elem.parentNode) != document.body) {
+ // bind to scroll containers only
+ if (elem == $viewport[0] || elem.scrollWidth != elem.clientWidth || elem.scrollHeight != elem.clientHeight)
+ $(elem).bind("scroll.slickgrid", repositionCurrentCellEditor);
+ }
+ }
+
+ function unbindAncestorScrollEvents() {
+ $canvas.parents().unbind("scroll.slickgrid");
+ }
+
function createColumnHeaders() {
var i;
@@ -837,6 +852,7 @@ if (!jQuery.fn.drag) {
if (self.onBeforeDestroy) { self.onBeforeDestroy(); }
if ($headers.sortable) { $headers.sortable("destroy"); }
+ unbindAncestorScrollEvents();
$container.unbind("resize", resizeCanvas);
removeCssRules();
@@ -1087,6 +1103,9 @@ if (!jQuery.fn.drag) {
}
function removeAllRows() {
+ if (currentEditor) {
+ makeSelectedCellNormal();
+ }
$canvas[0].innerHTML = "";
rowsCache= {};
postProcessedRows = {};
@@ -1111,7 +1130,7 @@ if (!jQuery.fn.drag) {
var nodes = [];
for (i=0, rl=rows.length; i<rl; i++) {
if (currentEditor && currentRow === i) {
- throw "Grid : removeRow : Cannot remove a row that is currently in edit mode";
+ makeSelectedCellNormal();
}
if (rowsCache[rows[i]]) {
@@ -1391,55 +1410,47 @@ if (!jQuery.fn.drag) {
if (!options.editorLock.isActive()) {
return; // no editing mode to cancel, allow bubbling and default processing (exit without cancelling the event)
}
- options.editorLock.cancelCurrentEdit();
- if (currentCellNode) {
- currentCellNode.focus();
- }
+ cancelEditAndSetFocus();
break;
case 9: // tab
- gotoDir(0, (e.shiftKey) ? -1 : 1, true);
+ if (e.shiftKey)
+ navigatePrev();
+ else
+ navigateNext();
break;
case 37: // left
- gotoDir(0, -1, false);
+ navigatePrev();
break;
case 39: // right
- gotoDir(0, 1, false);
+ navigateRight();
break;
case 38: // up
- gotoDir(-1, 0, false);
+ navigateUp();
break;
case 40: // down
- gotoDir(1, 0, false);
+ navigateDown();
break;
case 13: // enter
- if (options.autoEdit) {
- gotoDir(1, 0, false);
- }
- else if (options.editable) {
+ if (options.editable) {
if (currentEditor) {
// adding new row
if (currentRow === data.length) {
- gotoDir(1, 0, false);
+ navigateDown();
}
else {
- // if the commit fails, it would do so due to a validation error
- // if so, do not steal the focus from the editor
- if (options.editorLock.commitCurrentEdit()) {
- currentCellNode.focus();
- }
+ commitEditAndSetFocus();
}
} else {
if (options.editorLock.commitCurrentEdit()) {
makeSelectedCellEditable();
}
}
-
}
break;
@@ -1593,7 +1604,6 @@ if (!jQuery.fn.drag) {
}
}
- // TODO: PERF: throttle event
function handleHover(e) {
if (!options.enableAutoTooltips) return;
var $cell = $(e.target).closest(".slick-cell",$canvas);
@@ -1623,6 +1633,7 @@ if (!jQuery.fn.drag) {
//////////////////////////////////////////////////////////////////////////////////////////////
// Cell switching
+
function resetCurrentCell() {
setSelectedCell(null,false,false);
}
@@ -1716,14 +1727,16 @@ if (!jQuery.fn.drag) {
self.onBeforeCellEditorDestroy(currentEditor);
}
currentEditor.destroy();
- $(currentCellNode).removeClass("editable invalid");
+ currentEditor = null;
- if (gridDataGetItem(currentRow)) {
- currentCellNode.innerHTML = columns[currentCell].formatter(currentRow, currentCell, gridDataGetItem(currentRow)[columns[currentCell].field], columns[currentCell], gridDataGetItem(currentRow));
- invalidatePostProcessingResults(currentRow);
- }
+ if (currentCellNode) {
+ $(currentCellNode).removeClass("editable invalid");
- currentEditor = null;
+ if (gridDataGetItem(currentRow)) {
+ currentCellNode.innerHTML = columns[currentCell].formatter(currentRow, currentCell, gridDataGetItem(currentRow)[columns[currentCell].field], columns[currentCell], gridDataGetItem(currentRow));
+ invalidatePostProcessingResults(currentRow);
+ }
+ }
// if there previously was text selected on a page (such as selected text in the edit cell just removed),
// IE can't set focus to anything else correctly
@@ -1745,8 +1758,6 @@ if (!jQuery.fn.drag) {
return;
}
-
-
if (self.onBeforeEditCell && self.onBeforeEditCell(currentRow,currentCell,gridDataGetItem(currentRow)) === false) {
currentCellNode.focus();
return;
@@ -1764,13 +1775,81 @@ if (!jQuery.fn.drag) {
currentCellNode.innerHTML = "";
- currentEditor = new columns[currentCell].editor($(currentCellNode), columns[currentCell], value, gridDataGetItem(currentRow), function() {
- // if the commit fails, it would do so due to a validation error
- // if so, do not steal the focus from the editor
- if (options.editorLock.commitCurrentEdit()) {
- currentCellNode.focus();
- }
+ var columnDef = columns[currentCell];
+
+ currentEditor = new columnDef.editor({
+ grid: self,
+ gridPosition: absBox($container[0]),
+ position: absBox(currentCellNode),
+ container: currentCellNode,
+ column: columnDef,
+ value: value,
+ item: gridDataGetItem(currentRow),
+ commitChanges: commitEditAndSetFocus,
+ cancelChanges: cancelEditAndSetFocus
});
+
+ if (currentEditor.position)
+ repositionCurrentCellEditor();
+ }
+
+ function commitEditAndSetFocus() {
+ // if the commit fails, it would do so due to a validation error
+ // if so, do not steal the focus from the editor
+ if (options.editorLock.commitCurrentEdit()) {
+ currentCellNode.focus();
+ }
+
+ if (options.autoEdit) {
+ navigateDown();
+ }
+ }
+
+ function cancelEditAndSetFocus() {
+ if (options.editorLock.cancelCurrentEdit()) {
+ currentCellNode.focus();
+ }
+ }
+
+ // TODO: may be some issues with floats. investigate.
+ function absBox(elem) {
+ var box = {top:elem.offsetTop, left:elem.offsetLeft, bottom:0, right:0, width:$(elem).outerWidth(), height:$(elem).outerHeight(), visible:true};
+ box.bottom = box.top + box.height;
+ box.right = box.left + box.width;
+
+ // walk up the tree
+ var offsetParent = elem.offsetParent;
+ while ((elem = elem.parentNode) != document.body) {
+ box.visible = box.visible
+ && !(box.bottom <= elem.scrollTop || box.top >= elem.offsetTop + elem.scrollTop + elem.clientHeight)
+ && !(box.right <= elem.scrollLeft || box.left >= elem.offsetLeft + elem.scrollLeft + elem.clientWidth);
+
+ box.left -= elem.scrollLeft;
+ box.top -= elem.scrollTop;
+
+ if (elem === offsetParent) {
+ box.left += elem.offsetLeft;
+ box.top += elem.offsetTop;
+ offsetParent = elem.offsetParent;
+ }
+
+ box.bottom = box.top + box.height;
+ box.right = box.left + box.width;
+ }
+
+ return box;
+ }
+
+ function repositionCurrentCellEditor() {
+ if (!currentEditor || !currentCellNode || !currentEditor.position) return;
+ var cellBox = absBox(currentCellNode);
+ if (currentEditor.show && currentEditor.hide) {
+ if (!cellBox.visible)
+ currentEditor.hide();
+ else
+ currentEditor.show();
+ }
+ currentEditor.position(cellBox);
}
function getCellEditor() {
@@ -1875,6 +1954,29 @@ if (!jQuery.fn.drag) {
}
}
+ function navigateUp() {
+ gotoDir(-1, 0, false);
+ }
+
+ function navigateDown() {
+ gotoDir(1, 0, false);
+ }
+
+ function navigateLeft() {
+ gotoDir(0, -1, false);
+ }
+
+ function navigateRight() {
+ gotoDir(0, 1, false);
+ }
+
+ function navigatePrev() {
+ gotoDir(0, -1, true);
+ }
+
+ function navigateNext() {
+ gotoDir(0, 1, true);
+ }
//////////////////////////////////////////////////////////////////////////////////////////////
// IEditor implementation for the editor lock
@@ -2038,6 +2140,12 @@ if (!jQuery.fn.drag) {
"getCurrentCell": getCurrentCell,
"getCurrentCellNode": getCurrentCellNode,
"resetCurrentCell": resetCurrentCell,
+ "navigatePrev": navigatePrev,
+ "navigateNext": navigateNext,
+ "navigateUp": navigateUp,
+ "navigateDown": navigateDown,
+ "navigateLeft": navigateLeft,
+ "navigateRight": navigateRight,
"gotoCell": gotoCell,
"editCurrentCell": makeSelectedCellEditable,
"getCellEditor": getCellEditor,