Skip to content

Commit

Permalink
feat: add pageUp/pageDown/home/end to SlickCellSelection, fixes #794
Browse files Browse the repository at this point in the history
- fixes #794
- adding "pageUp/pageDown/home/end" to SlickCellSelection when using selection with "Shift+{key}"
- add `hasDataView()` and `getViewportRowCount()` methods to SlickGrid and also make `getViewportHeight()` and `getViewportWidth()` as publish methods
- add new `example-spreadsheet-dataview.html` demo to manually test updated Cell Selection feature
  • Loading branch information
ghiscoding committed Oct 1, 2023
1 parent 953ec65 commit 0682eed
Show file tree
Hide file tree
Showing 7 changed files with 406 additions and 49 deletions.
43 changes: 34 additions & 9 deletions examples/example-frozen-columns-and-rows-spreadsheet.html
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ <h2>
<li>Use Ctrl-C and Ctrl-V keyboard shortcuts to cut and paste cells</li>
<li>Use Esc to cancel a copy and paste operation</li>
<li>Edit the cell and select a cell range to paste the range</li>
<li>Cell Selection using "Shift+{key}" where "key" can be any of:</li>
<ul>
<li>Arrow Up/Down/Left/Right</li>
<li>Page Up/Down</li>
<li>Home</li>
<li>End</li>
</ul>
</ul>
</div>
</div>
Expand Down Expand Up @@ -90,7 +97,7 @@ <h2>
/***
* A proof-of-concept cell editor with Excel-like range selection and insertion.
*/
function FormulaEditor(args) {
function FormulaEditor(args) {
var _self = this;
var _editor = new Slick.Editors.Text(args);
var _selector;
Expand All @@ -113,23 +120,41 @@ <h2>
_editor.destroy();
};

this.isValueChanged = function() {
return _editor.isValueChanged();
};

this.loadValue = function (item) {
_editor.loadValue(item);
};

this.applyValue = function(item, state) {
return _editor.applyValue(item, state);
};

this.serializeValue = function() {
return _editor.serializeValue();
};

this.validate = function() {
return _editor.validate();
};

this.handleCellRangeSelected = function (e, args) {
_editor.setValue(
_editor.getValue() +
grid.getColumns()[args.range.fromCell].name +
args.range.fromRow +
":" +
grid.getColumns()[args.range.toCell].name +
args.range.toRow
grid.getColumns()[args.range.fromCell].name +
args.range.fromRow +
":" +
grid.getColumns()[args.range.toCell].name +
args.range.toRow
);
};


init();
}


document.addEventListener("DOMContentLoaded", function() {
document.addEventListener("DOMContentLoaded", () => {
for (var i = 0; i < 100; i++) {
var d = (data[i] = {});
d["num"] = i;
Expand Down
246 changes: 246 additions & 0 deletions examples/example-spreadsheet-dataview.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="shortcut icon" type="image/ico" href="favicon.ico" />
<title>SlickGrid example 3: Editing</title>
<link rel="stylesheet" href="../dist/styles/css/slick-icons.css" type="text/css"/>
<link rel="stylesheet" href="../dist/styles/css/example-demo.css" type="text/css"/>
<link rel="stylesheet" href="../dist/styles/css/slick-alpine-theme.css" type="text/css"/>
<style>
.slick-cell.copied {
background: blue;
background: rgba(0, 0, 255, 0.2);
transition: 0.5s background;
}
/** override slick-cell to make it look like Excel sheet */
.slick-container {
--alpine-header-column-height: 20px;
--alpine-header-font-weight: 500;
--alpine-cell-border-width: 0 1px 1px 0;
--alpine-cell-border-color: #d4d4d4;
}
</style>
</head>
<body>
<div style="position:relative">
<div style="width:600px;">
<div id="myGrid" class="slick-container" style="width:100%;height:500px;"></div>
<div id="pager" style="width:100%;height:20px;"></div>
</div>

<div class="options-panel">
<h2>
<a href="/examples/index.html" style="text-decoration: none; font-size: 22px">&#x2302;</a>
Demonstrates:
</h2>
<ul>
<li>Virtual scrolling on both rows and columns.</li>
<li>Select a range of cells with a mouse</li>
<li>Use Ctrl-C and Ctrl-V keyboard shortcuts to cut and paste cells</li>
<li>Use Esc to cancel a copy and paste operation</li>
<li>Edit the cell and select a cell range to paste the range</li>
<li>Cell Selection using "Shift+{key}" where "key" can be any of:</li>
<ul>
<li>Arrow Up/Down/Left/Right</li>
<li>Page Up/Down</li>
<li>Home</li>
<li>End</li>
</ul>
</ul>
<h2>View Source:</h2>
<ul>
<li>
<a href="https://github.com/6pac/SlickGrid/blob/master/examples/example-spreadsheet-dataview.html" target="_sourcewindow">
View the source for this example on Github
</a>
</li>
</ul>
</div>
</div>

<script src="https://cdn.jsdelivr.net/npm/sortablejs/Sortable.min.js"></script>
<script src="sortable-cdn-fallback.js"></script>

<script src="../dist/browser/slick.core.js"></script>
<script src="../dist/browser/slick.interactions.js"></script>
<script src="../dist/browser/slick.grid.js"></script>
<script src="../dist/browser/slick.editors.js"></script>
<script src="../dist/browser/plugins/slick.cellrangedecorator.js"></script>
<script src="../dist/browser/plugins/slick.cellrangeselector.js"></script>
<script src="../dist/browser/plugins/slick.cellcopymanager.js"></script>
<script src="../dist/browser/plugins/slick.cellselectionmodel.js"></script>
<script src="../dist/browser/slick.dataview.js"></script>
<script src="../dist/browser/controls/slick.pager.js"></script>

<script>
var grid;
var data = [];
var dataView;
var options = {
editable: true,
enableAddRow: true,
enableCellNavigation: true,
asyncEditorLoading: false,
autoEdit: false
};

var columns = [
{
id: "selector",
name: "",
field: "num",
width: 30
}
];

for (var i = 0; i < 100; i++) {
columns.push({
id: i,
name: String.fromCharCode("A".charCodeAt(0) + (i / 26) | 0) +
String.fromCharCode("A".charCodeAt(0) + (i % 26)),
field: i,
width: 60,
editor: FormulaEditor
});
}

/***
* A proof-of-concept cell editor with Excel-like range selection and insertion.
*/
function FormulaEditor(args) {
var _self = this;
var _editor = new Slick.Editors.Text(args);
var _selector;

Slick.Utils.extend(this, _editor);

function init() {
// register a plugin to select a range and append it to the textbox
// since events are fired in reverse order (most recently added are executed first),
// this will override other plugins like moverows or selection model and will
// not require the grid to not be in the edit mode
_selector = new Slick.CellRangeSelector();
_selector.onCellRangeSelected.subscribe(_self.handleCellRangeSelected);
args.grid.registerPlugin(_selector);
}

this.destroy = function () {
_selector.onCellRangeSelected.unsubscribe(_self.handleCellRangeSelected);
grid.unregisterPlugin(_selector);
_editor.destroy();
};

this.isValueChanged = function() {
return _editor.isValueChanged();
};

this.loadValue = function (item) {
_editor.loadValue(item);
};

this.applyValue = function(item, state) {
return _editor.applyValue(item, state);
};

this.serializeValue = function() {
return _editor.serializeValue();
};

this.validate = function() {
return _editor.validate();
};

this.handleCellRangeSelected = function (e, args) {
_editor.setValue(
_editor.getValue() +
grid.getColumns()[args.range.fromCell].name +
args.range.fromRow +
":" +
grid.getColumns()[args.range.toCell].name +
args.range.toRow
);
};

init();
}

document.addEventListener("DOMContentLoaded", function() {
for (var i = 0; i < 100; i++) {
var d = (data[i] = {});
d["id"] = i;
d["num"] = i;
}

dataView = new Slick.Data.DataView();
grid = new Slick.Grid("#myGrid", dataView, columns, options);

var pager = new Slick.Controls.Pager(dataView, grid, "#pager");

grid.setSelectionModel(new Slick.CellSelectionModel());

// set keyboard focus on the grid
grid.getCanvasNode().focus();

var copyManager = new Slick.CellCopyManager();
grid.registerPlugin(copyManager);

copyManager.onPasteCells.subscribe(function (e, args) {
if (args.from.length !== 1 || args.to.length !== 1) {
throw "This implementation only supports single range copy and paste operations";
}

var from = args.from[0];
var to = args.to[0];
var val;
for (var i = 0; i <= from.toRow - from.fromRow; i++) {
for (var j = 0; j <= from.toCell - from.fromCell; j++) {
if (i <= to.toRow - to.fromRow && j <= to.toCell - to.fromCell) {
val = data[from.fromRow + i][columns[from.fromCell + j].field];
data[to.fromRow + i][columns[to.fromCell + j].field] = val;
grid.invalidateRow(to.fromRow + i);
}
}
}
grid.render();
});

dataView.onRowCountChanged.subscribe(function (e, args) {
grid.updateRowCount();
grid.render();
});

dataView.onRowsChanged.subscribe(function (e, args) {
grid.invalidateRows(args.rows);
grid.render();
});

dataView.onPagingInfoChanged.subscribe(function (e, pagingInfo) {
grid.updatePagingStatusFromView( pagingInfo );

// show the pagingInfo but remove the dataView from the object, just for the Cypress E2E test
delete pagingInfo.dataView;
console.log('on After Paging Info Changed - New Paging:: ', pagingInfo);
});

dataView.onBeforePagingInfoChanged.subscribe(function (e, previousPagingInfo) {
// show the previous pagingInfo but remove the dataView from the object, just for the Cypress E2E test
delete previousPagingInfo.dataView;
console.log('on Before Paging Info Changed - Previous Paging:: ', previousPagingInfo);
});

grid.onAddNewRow.subscribe(function (e, args) {
var item = args.item;
Slick.Utils.extend(item, args.item);
dataView.addItem(item);
});

// initialize the model after all the events have been hooked up
dataView.beginUpdate();
dataView.setItems(data);
dataView.endUpdate();
grid.render();
})
</script>
</body>
</html>
31 changes: 28 additions & 3 deletions examples/example-spreadsheet.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ <h2>
<li>Use Ctrl-C and Ctrl-V keyboard shortcuts to cut and paste cells</li>
<li>Use Esc to cancel a copy and paste operation</li>
<li>Edit the cell and select a cell range to paste the range</li>
<li>Cell Selection using "Shift+{key}" where "key" can be any of:</li>
<ul>
<li>Arrow Up/Down/Left/Right</li>
<li>Page Up/Down</li>
<li>Home</li>
<li>End</li>
</ul>
</ul>
<h2>View Source:</h2>
<ul>
Expand Down Expand Up @@ -97,7 +104,7 @@ <h2>View Source:</h2>
/***
* A proof-of-concept cell editor with Excel-like range selection and insertion.
*/
function FormulaEditor(args) {
function FormulaEditor(args) {
var _self = this;
var _editor = new Slick.Editors.Text(args);
var _selector;
Expand All @@ -120,6 +127,26 @@ <h2>View Source:</h2>
_editor.destroy();
};

this.isValueChanged = function() {
return _editor.isValueChanged();
};

this.loadValue = function (item) {
_editor.loadValue(item);
};

this.applyValue = function(item, state) {
return _editor.applyValue(item, state);
};

this.serializeValue = function() {
return _editor.serializeValue();
};

this.validate = function() {
return _editor.validate();
};

this.handleCellRangeSelected = function (e, args) {
_editor.setValue(
_editor.getValue() +
Expand All @@ -131,11 +158,9 @@ <h2>View Source:</h2>
);
};


init();
}


document.addEventListener("DOMContentLoaded", function() {
for (var i = 0; i < 100; i++) {
var d = (data[i] = {});
Expand Down
1 change: 1 addition & 0 deletions examples/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ <h2>Layout</h2>
<ul>
<li><a href="./example8-alternative-display.html">Using pre-compiled micro-templates to render cells</a></li>
<li><a href="./example-spreadsheet.html">Spreadsheet: cell range selection, copy’n’paste and Excel-style formula editor</a></li>
<li><a href="./example-spreadsheet-dataview.html">Spreadsheet using a DataView: cell range selection</a></li>
<li><a href="./example-excel-compatible-spreadsheet.html">Spreadsheet: features of the previous example plus Excel compatible copy and paste</a></li>
<li><a href="./example-excel-compatible-spreadsheet-dataview.html">Spreadsheet: features of the previous example but using a DataView</a></li>
<li><a href="./example11-autoheight.html" title="autoHeight">No vertical scrolling</a></li>
Expand Down
Loading

0 comments on commit 0682eed

Please sign in to comment.