canvas-datagrid 0.3.10 → 0.3.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/dist/canvas-datagrid.debug.js +328 -129
- package/dist/canvas-datagrid.debug.map +1 -1
- package/dist/canvas-datagrid.js +1 -1
- package/dist/canvas-datagrid.module.js +1 -1
- package/dist/canvas-datagrid.module.js.map +1 -1
- package/dist/types.d.ts +6 -0
- package/lib/defaults.js +3 -0
- package/lib/docs.js +5 -0
- package/lib/draw.js +3 -1
- package/lib/{events.js → events/index.js} +39 -57
- package/lib/events/util.js +96 -0
- package/lib/intf.js +69 -5
- package/lib/publicMethods.js +4 -0
- package/lib/touch.js +2 -39
- package/package.json +1 -1
package/dist/types.d.ts
CHANGED
|
@@ -66,6 +66,8 @@
|
|
|
66
66
|
* @param [args.autoScrollMargin = 5] - Number of pixels of mouse movement to trigger auto scroll.
|
|
67
67
|
* @param [args.allowFreezingRows = false] - When true, the UI provides a drag-able cutter to freeze rows.
|
|
68
68
|
* @param [args.allowFreezingColumns = false] - When true, the UI provides a drag-able cutter to freeze columns.
|
|
69
|
+
* @param [args.filterFrozenRows = true] - When false, rows on and above {@link canvasDatagrid#property:frozenRow}` will be ignored by filters when {@link canvasDatagrid#param:allowFreezingRows} is true.
|
|
70
|
+
* @param [args.sortFrozenRows = true] - When false, rows on and above {@link canvasDatagrid#property:frozenRow}` will be ignored by sorters when {@link canvasDatagrid#param:allowSorting} is true.
|
|
69
71
|
* @param [args.allowColumnReordering = true] - When true columns can be reordered.
|
|
70
72
|
* @param [args.allowMovingSelection = false] - When true selected data can be moved by clicking and dragging on the border of the selection.
|
|
71
73
|
* @param [args.allowRowReordering = false] - When true rows can be reordered.
|
|
@@ -76,6 +78,7 @@
|
|
|
76
78
|
* @param [args.pageUpDownOverlap = 1] - Amount of rows to overlap when pageup/pagedown is used.
|
|
77
79
|
* @param [args.persistantSelectionMode = false] - When true, selections will behave as if the command/control key is held down at all times. Conflicts with singleSelectionMode.
|
|
78
80
|
* @param [args.singleSelectionMode = false] - When true, selections will ignore the command/control key. Conflicts with persistantSelectionMode.
|
|
81
|
+
* @param [args.keepFocusOnMouseOut = false] - When true, grid will continue to handle keydown events when mouse is outside of the grid.
|
|
79
82
|
* @param [args.selectionMode = 'cell'] - Can be 'cell', or 'row'. This setting dictates what will be selected when the user clicks a cell. The cell, or the entire row respectively.
|
|
80
83
|
* @param [args.hoverMode = 'cell'] - Can be 'cell', or 'row'. This setting dictates whether to highlight either the individual cell, or the entire row when hovering over a cell.
|
|
81
84
|
* @param [args.autoResizeColumns = false] - When true, all columns will be automatically resized to fit the data in them. Warning! Expensive for large (>100k ~2 seconds) datasets.
|
|
@@ -152,6 +155,8 @@ declare class canvasDatagrid {
|
|
|
152
155
|
autoScrollMargin?: number;
|
|
153
156
|
allowFreezingRows?: boolean;
|
|
154
157
|
allowFreezingColumns?: boolean;
|
|
158
|
+
filterFrozenRows?: boolean;
|
|
159
|
+
sortFrozenRows?: boolean;
|
|
155
160
|
allowColumnReordering?: boolean;
|
|
156
161
|
allowMovingSelection?: boolean;
|
|
157
162
|
allowRowReordering?: boolean;
|
|
@@ -162,6 +167,7 @@ declare class canvasDatagrid {
|
|
|
162
167
|
pageUpDownOverlap?: number;
|
|
163
168
|
persistantSelectionMode?: boolean;
|
|
164
169
|
singleSelectionMode?: boolean;
|
|
170
|
+
keepFocusOnMouseOut?: boolean;
|
|
165
171
|
selectionMode?: string;
|
|
166
172
|
hoverMode?: string;
|
|
167
173
|
autoResizeColumns?: boolean;
|
package/lib/defaults.js
CHANGED
|
@@ -38,9 +38,11 @@ export default function (self) {
|
|
|
38
38
|
['ellipsisText', '...'],
|
|
39
39
|
['filterOptionText', 'Filter %s'],
|
|
40
40
|
['filterTextPrefix', '(filtered) '],
|
|
41
|
+
['filterFrozenRows', true],
|
|
41
42
|
['globalRowResize', false],
|
|
42
43
|
['hideColumnText', 'Hide %s'],
|
|
43
44
|
['hoverMode', 'cell'],
|
|
45
|
+
['keepFocusOnMouseOut', false],
|
|
44
46
|
['maxAutoCompleteItems', 200],
|
|
45
47
|
['multiLine', false],
|
|
46
48
|
['name', ''],
|
|
@@ -76,6 +78,7 @@ export default function (self) {
|
|
|
76
78
|
['showRowNumberGaps', true],
|
|
77
79
|
['singleSelectionMode', false],
|
|
78
80
|
['snapToRow', false],
|
|
81
|
+
['sortFrozenRows', true],
|
|
79
82
|
['touchContextMenuTimeMs', 800],
|
|
80
83
|
['touchDeadZone', 3],
|
|
81
84
|
['touchEasingMethod', 'easeOutQuad'],
|
package/lib/docs.js
CHANGED
|
@@ -29,6 +29,8 @@
|
|
|
29
29
|
* @param {number} [args.autoScrollMargin=5] - Number of pixels of mouse movement to trigger auto scroll.
|
|
30
30
|
* @param {boolean} [args.allowFreezingRows=false] - When true, the UI provides a drag-able cutter to freeze rows.
|
|
31
31
|
* @param {boolean} [args.allowFreezingColumns=false] - When true, the UI provides a drag-able cutter to freeze columns.
|
|
32
|
+
* @param {boolean} [args.filterFrozenRows=true] - When false, rows on and above {@link canvasDatagrid#property:frozenRow}` will be ignored by filters when {@link canvasDatagrid#param:allowFreezingRows} is true.
|
|
33
|
+
* @param {boolean} [args.sortFrozenRows=true] - When false, rows on and above {@link canvasDatagrid#property:frozenRow}` will be ignored by sorters when {@link canvasDatagrid#param:allowSorting} is true.
|
|
32
34
|
* @param {boolean} [args.allowColumnReordering=true] - When true columns can be reordered.
|
|
33
35
|
* @param {boolean} [args.allowMovingSelection=false] - When true selected data can be moved by clicking and dragging on the border of the selection.
|
|
34
36
|
* @param {boolean} [args.allowRowReordering=false] - When true rows can be reordered.
|
|
@@ -39,6 +41,7 @@
|
|
|
39
41
|
* @param {number} [args.pageUpDownOverlap=1] - Amount of rows to overlap when pageup/pagedown is used.
|
|
40
42
|
* @param {boolean} [args.persistantSelectionMode=false] - When true, selections will behave as if the command/control key is held down at all times. Conflicts with singleSelectionMode.
|
|
41
43
|
* @param {boolean} [args.singleSelectionMode=false] - When true, selections will ignore the command/control key. Conflicts with persistantSelectionMode.
|
|
44
|
+
* @param {boolean} [args.keepFocusOnMouseOut=false] - When true, grid will continue to handle keydown events when mouse is outside of the grid.
|
|
42
45
|
* @param {string} [args.selectionMode='cell'] - Can be 'cell', or 'row'. This setting dictates what will be selected when the user clicks a cell. The cell, or the entire row respectively.
|
|
43
46
|
* @param {string} [args.hoverMode='cell'] - Can be 'cell', or 'row'. This setting dictates whether to highlight either the individual cell, or the entire row when hovering over a cell.
|
|
44
47
|
* @param {boolean} [args.autoResizeColumns=false] - When true, all columns will be automatically resized to fit the data in them. Warning! Expensive for large (>100k ~2 seconds) datasets.
|
|
@@ -454,6 +457,8 @@
|
|
|
454
457
|
* @param {object} e.selectedData Selected data.
|
|
455
458
|
* @param {array} e.selections Selections object. 2D matrix of selections.
|
|
456
459
|
* @param {rectangle} e.selectionBounds rectangle object describing the selection bounds.
|
|
460
|
+
* @param {object} e.boundRowIndexMap Mapping of view data row to bound data row index.
|
|
461
|
+
* @param {object} e.boundColumnIndexMap Mapping of view column order to bound column order.
|
|
457
462
|
*/
|
|
458
463
|
/**
|
|
459
464
|
* Fires when the user clicks on the "drill in" arrow. When the arrow is clicked a new
|
package/lib/draw.js
CHANGED
|
@@ -911,7 +911,9 @@ export default function (self) {
|
|
|
911
911
|
viewColumnIndex: columnOrderIndex,
|
|
912
912
|
|
|
913
913
|
boundRowIndex: self.getBoundRowIndexFromViewRowIndex(rowOrderIndex),
|
|
914
|
-
boundColumnIndex:
|
|
914
|
+
boundColumnIndex: self.getBoundColumnIndexFromViewColumnIndex(
|
|
915
|
+
columnOrderIndex,
|
|
916
|
+
),
|
|
915
917
|
|
|
916
918
|
sortColumnIndex: headerIndex,
|
|
917
919
|
sortRowIndex: rowIndex,
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
'use strict';
|
|
4
4
|
|
|
5
5
|
import isPrintableKeyEvent from 'is-printable-key-event';
|
|
6
|
+
import { isSupportedHtml, parseData } from './util';
|
|
6
7
|
|
|
7
8
|
export default function (self) {
|
|
8
9
|
var wheeling;
|
|
@@ -518,13 +519,12 @@ export default function (self) {
|
|
|
518
519
|
self.selections[cell.rowIndex].indexOf(cell.columnIndex) === -1
|
|
519
520
|
) {
|
|
520
521
|
self.selections[cell.rowIndex].push(cell.columnIndex);
|
|
521
|
-
|
|
522
522
|
const event = {
|
|
523
523
|
selections: self.selections,
|
|
524
524
|
selectedData: self.getSelectedData(),
|
|
525
|
+
selectedCells: self.getSelectedCells(),
|
|
525
526
|
selectionBounds: self.getSelectionBounds(),
|
|
526
527
|
};
|
|
527
|
-
|
|
528
528
|
self.dispatchEvent('selectionchanged', event);
|
|
529
529
|
}
|
|
530
530
|
}
|
|
@@ -583,12 +583,14 @@ export default function (self) {
|
|
|
583
583
|
function checkSelectionChange() {
|
|
584
584
|
var ev,
|
|
585
585
|
sb = self.getSelectionBounds();
|
|
586
|
+
|
|
586
587
|
if (startingBounds === JSON.stringify(sb)) {
|
|
587
588
|
return;
|
|
588
589
|
}
|
|
589
590
|
ev = {
|
|
590
591
|
selections: self.selections,
|
|
591
592
|
selectionBounds: self.getSelectionBounds(),
|
|
593
|
+
selectedCells: self.getSelectedCells(),
|
|
592
594
|
};
|
|
593
595
|
Object.defineProperty(ev, 'selectedData', {
|
|
594
596
|
get: function () {
|
|
@@ -1246,7 +1248,7 @@ export default function (self) {
|
|
|
1246
1248
|
return;
|
|
1247
1249
|
}
|
|
1248
1250
|
|
|
1249
|
-
if (!self.hasFocus) {
|
|
1251
|
+
if (!self.attributes.keepFocusOnMouseOut && !self.hasFocus) {
|
|
1250
1252
|
return;
|
|
1251
1253
|
}
|
|
1252
1254
|
|
|
@@ -1401,6 +1403,7 @@ export default function (self) {
|
|
|
1401
1403
|
selectedData: self.getSelectedData(),
|
|
1402
1404
|
selections: self.selections,
|
|
1403
1405
|
selectionBounds: self.getSelectionBounds(),
|
|
1406
|
+
selectedCells: self.getSelectedCells(),
|
|
1404
1407
|
};
|
|
1405
1408
|
Object.defineProperty(ev, 'selectedData', {
|
|
1406
1409
|
get: function () {
|
|
@@ -1497,24 +1500,13 @@ export default function (self) {
|
|
|
1497
1500
|
}, 1);
|
|
1498
1501
|
}
|
|
1499
1502
|
};
|
|
1500
|
-
|
|
1501
1503
|
self.pasteData = function (
|
|
1502
1504
|
pasteValue,
|
|
1503
1505
|
mimeType,
|
|
1504
1506
|
startRowIndex,
|
|
1505
1507
|
startColIndex,
|
|
1506
1508
|
) {
|
|
1507
|
-
|
|
1508
|
-
const isSupportedHtmlTable = (htmlString) =>
|
|
1509
|
-
/(?:^(<meta[^>]+>)?<table.*?>)|(?:<!--StartFragment-->\s*<table.*?>)/.test(
|
|
1510
|
-
htmlString,
|
|
1511
|
-
);
|
|
1512
|
-
|
|
1513
|
-
// TODO: support pasting tables from Excel
|
|
1514
|
-
if (
|
|
1515
|
-
mimeType === 'text/html' &&
|
|
1516
|
-
isSupportedHtmlTable(pasteValue) === false
|
|
1517
|
-
) {
|
|
1509
|
+
if (mimeType === 'text/html' && !isSupportedHtml(pasteValue)) {
|
|
1518
1510
|
console.warn(
|
|
1519
1511
|
'Unrecognized HTML format. HTML must be a simple table, e.g.: <table><tr><td>data</td></tr></table>.',
|
|
1520
1512
|
);
|
|
@@ -1524,48 +1516,12 @@ export default function (self) {
|
|
|
1524
1516
|
|
|
1525
1517
|
return;
|
|
1526
1518
|
}
|
|
1527
|
-
|
|
1528
|
-
function parseData(data, mimeType) {
|
|
1529
|
-
// TODO: use DOMParser
|
|
1530
|
-
if (mimeType === 'text/html') {
|
|
1531
|
-
const doc = new DOMParser().parseFromString(data, 'text/html');
|
|
1532
|
-
const trs = doc.querySelectorAll('table tr');
|
|
1533
|
-
const rows = [];
|
|
1534
|
-
trs.forEach((tr) => {
|
|
1535
|
-
const row = [];
|
|
1536
|
-
tr.childNodes.forEach((td) => {
|
|
1537
|
-
if (td.nodeName === '#text') return;
|
|
1538
|
-
const col = {
|
|
1539
|
-
// style: {}, // keep style if need
|
|
1540
|
-
value: [],
|
|
1541
|
-
};
|
|
1542
|
-
td.childNodes.forEach((ele) => {
|
|
1543
|
-
col.value.push({
|
|
1544
|
-
// style: {}, // keep style if need
|
|
1545
|
-
value: ele.nodeType === 1 ? ele.innerText : ele.data,
|
|
1546
|
-
});
|
|
1547
|
-
});
|
|
1548
|
-
row.push(col);
|
|
1549
|
-
});
|
|
1550
|
-
rows.push(row);
|
|
1551
|
-
});
|
|
1552
|
-
return rows;
|
|
1553
|
-
}
|
|
1554
|
-
|
|
1555
|
-
// Default data format is string, so split on new line,
|
|
1556
|
-
// and then enclose in an array (a row with one cell):
|
|
1557
|
-
return data
|
|
1558
|
-
.split('\n')
|
|
1559
|
-
.map((item) =>
|
|
1560
|
-
item.split('\t').map((value) => ({ value: [{ value }] })),
|
|
1561
|
-
);
|
|
1562
|
-
}
|
|
1563
|
-
|
|
1519
|
+
var schema = self.getSchema();
|
|
1564
1520
|
var rows = parseData(pasteValue, mimeType);
|
|
1565
1521
|
|
|
1566
1522
|
// selected cell. This mimics Excel's paste functionality, and works
|
|
1567
1523
|
// as a poor-man's fill-down.
|
|
1568
|
-
if (rows.length === 1) {
|
|
1524
|
+
if (rows.length === 1 && rows[0].length === 1) {
|
|
1569
1525
|
var cellData = rows[0][0].value.map((item) => item.value).join();
|
|
1570
1526
|
|
|
1571
1527
|
self.forEachSelectedCell(function (data, rowIndex, colName) {
|
|
@@ -1627,7 +1583,8 @@ export default function (self) {
|
|
|
1627
1583
|
affectedCells.push([
|
|
1628
1584
|
rowIndex,
|
|
1629
1585
|
columnIndex,
|
|
1630
|
-
self.
|
|
1586
|
+
self.getBoundRowIndexFromViewRowIndex(rowIndex),
|
|
1587
|
+
self.getBoundColumnIndexFromViewColumnIndex(columnIndex),
|
|
1631
1588
|
]);
|
|
1632
1589
|
});
|
|
1633
1590
|
});
|
|
@@ -1722,9 +1679,34 @@ export default function (self) {
|
|
|
1722
1679
|
};
|
|
1723
1680
|
self.cut = function (e) {
|
|
1724
1681
|
self.copy(e);
|
|
1725
|
-
self.
|
|
1726
|
-
|
|
1727
|
-
|
|
1682
|
+
const schema = self.getSchema();
|
|
1683
|
+
|
|
1684
|
+
var affectedCells = [];
|
|
1685
|
+
for (const [rowIndex, row] of self.selections.entries()) {
|
|
1686
|
+
if (!row) continue;
|
|
1687
|
+
|
|
1688
|
+
const boundRowIndex = self.getBoundRowIndexFromViewRowIndex(rowIndex);
|
|
1689
|
+
|
|
1690
|
+
for (const columnIndex of row) {
|
|
1691
|
+
const boundColumnIndex = self.getBoundColumnIndexFromViewColumnIndex(
|
|
1692
|
+
columnIndex,
|
|
1693
|
+
);
|
|
1694
|
+
const colName = schema[boundColumnIndex].name;
|
|
1695
|
+
|
|
1696
|
+
self.viewData[rowIndex][colName] = '';
|
|
1697
|
+
|
|
1698
|
+
affectedCells.push([
|
|
1699
|
+
rowIndex,
|
|
1700
|
+
columnIndex,
|
|
1701
|
+
boundRowIndex,
|
|
1702
|
+
boundColumnIndex,
|
|
1703
|
+
]);
|
|
1704
|
+
}
|
|
1705
|
+
}
|
|
1706
|
+
|
|
1707
|
+
if (self.dispatchEvent('cut', { NativeEvent: e, cells: affectedCells })) {
|
|
1708
|
+
return;
|
|
1709
|
+
}
|
|
1728
1710
|
};
|
|
1729
1711
|
self.copy = function (e) {
|
|
1730
1712
|
if (self.dispatchEvent('copy', { NativeEvent: e })) {
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const isSupportedHtml = function (pasteValue) {
|
|
4
|
+
// We need to match new lines in the HTML, .* won't match new line characters.
|
|
5
|
+
// `s` regex modifier can't be used with `ecmaVersion === 2017`.
|
|
6
|
+
// As a workaround using [\s\S]*. Fix when we upgrade `ecmaVersion`.
|
|
7
|
+
const genericDiv = /(?:^(<meta[^>]*>)?[\s\S]*<div[^>]*>)/;
|
|
8
|
+
const genericSpan = /(?:^(<meta[^>]*>)?[\s\S]*<span[^>]*>)/;
|
|
9
|
+
const genericTable = /(?:^(<meta[^>]*>)?[\s\S]*<table[^>]*>)/; // Matches Google Sheets format clipboard data format too.
|
|
10
|
+
const excelTable = /(?:<!--StartFragment-->[\s\S]*<tr[^>]*>)/;
|
|
11
|
+
const excelTableRow = /(?:<!--StartFragment-->[\s\S]*<td[^>]*>)/;
|
|
12
|
+
|
|
13
|
+
return [
|
|
14
|
+
genericDiv,
|
|
15
|
+
genericTable,
|
|
16
|
+
genericSpan,
|
|
17
|
+
excelTable,
|
|
18
|
+
excelTableRow,
|
|
19
|
+
].some((expression) => expression.test(pasteValue));
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// Explanation of nodeType here: https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType
|
|
23
|
+
const IGNORE_NODETYPES = [8, 3]; // '#text' and '#comment'
|
|
24
|
+
|
|
25
|
+
const isHtmlTable = function (pasteValue) {
|
|
26
|
+
return /(?:<table[^>]*>)|(?:<tr[^]*>)/.test(pasteValue);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const sanitizeElementData = function (element) {
|
|
30
|
+
// It is not entirely clear if this check on nodeType is required.
|
|
31
|
+
let elementData = element.nodeType === 1 ? element.innerText : element.data;
|
|
32
|
+
|
|
33
|
+
return String(elementData).replace(/\s+/g, ' ').trim();
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const parseHtmlText = function (data) {
|
|
37
|
+
const doc = new DOMParser().parseFromString(data, 'text/html');
|
|
38
|
+
const element = doc.querySelector('div') || doc.querySelector('span');
|
|
39
|
+
const elementData = sanitizeElementData(element);
|
|
40
|
+
|
|
41
|
+
return elementData
|
|
42
|
+
.split('\n')
|
|
43
|
+
.map((item) => item.split('\t').map((value) => ({ value: [{ value }] })));
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const parseHtmlTable = function (data) {
|
|
47
|
+
const doc = new DOMParser().parseFromString(data, 'text/html');
|
|
48
|
+
const trs = doc.querySelectorAll('table tr');
|
|
49
|
+
const rows = [];
|
|
50
|
+
|
|
51
|
+
for (const tr of trs) {
|
|
52
|
+
const row = [];
|
|
53
|
+
|
|
54
|
+
for (const childNode of tr.childNodes) {
|
|
55
|
+
if (IGNORE_NODETYPES.includes(childNode.nodeType)) continue;
|
|
56
|
+
|
|
57
|
+
const col = { value: [] };
|
|
58
|
+
const value = sanitizeElementData(childNode);
|
|
59
|
+
|
|
60
|
+
if (value) col.value.push({ value });
|
|
61
|
+
|
|
62
|
+
row.push(col);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
rows.push(row);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return rows;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const parseText = function (data) {
|
|
72
|
+
return data
|
|
73
|
+
.split('\n')
|
|
74
|
+
.map((item) => item.split('\t').map((value) => ({ value: [{ value }] })));
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const parseData = function (data, mimeType) {
|
|
78
|
+
if (mimeType === 'text/html' && isHtmlTable(data)) {
|
|
79
|
+
return parseHtmlTable(data);
|
|
80
|
+
} else if (mimeType === 'text/html') {
|
|
81
|
+
return parseHtmlText(data);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Default data format is string, so split on new line,
|
|
85
|
+
// and then enclose in an array (a row with one cell):
|
|
86
|
+
return parseText(data);
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
export {
|
|
90
|
+
isSupportedHtml,
|
|
91
|
+
sanitizeElementData,
|
|
92
|
+
parseData,
|
|
93
|
+
parseHtmlTable,
|
|
94
|
+
parseHtmlText,
|
|
95
|
+
parseText,
|
|
96
|
+
};
|
package/lib/intf.js
CHANGED
|
@@ -184,6 +184,54 @@ export default function (self, ctor) {
|
|
|
184
184
|
|
|
185
185
|
return selectedData;
|
|
186
186
|
};
|
|
187
|
+
self.getSelectedCells = function (expandToRow) {
|
|
188
|
+
const selectedCells = [];
|
|
189
|
+
const schema = self.getSchema();
|
|
190
|
+
const viewDataLength = self.viewData.length;
|
|
191
|
+
|
|
192
|
+
if (viewDataLength === 0) {
|
|
193
|
+
return [];
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
for (const [viewRowIndex, row] of self.selections.entries()) {
|
|
197
|
+
if (!row || row.length === 0) continue;
|
|
198
|
+
|
|
199
|
+
for (const [, viewColumnIndex] of row.entries()) {
|
|
200
|
+
if (viewColumnIndex === -1 || !schema[viewColumnIndex]) {
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const boundColumnIndex = self.getBoundColumnIndexFromViewColumnIndex(
|
|
205
|
+
viewColumnIndex,
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
if (!expandToRow && schema[boundColumnIndex].hidden) {
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (self.viewData[viewRowIndex]) {
|
|
213
|
+
const header = schema[boundColumnIndex];
|
|
214
|
+
const value = self.viewData[viewRowIndex][header.name];
|
|
215
|
+
const boundRowIndex = self.getBoundRowIndexFromViewRowIndex(
|
|
216
|
+
viewRowIndex,
|
|
217
|
+
);
|
|
218
|
+
|
|
219
|
+
const cell = {
|
|
220
|
+
value,
|
|
221
|
+
header,
|
|
222
|
+
boundRowIndex,
|
|
223
|
+
boundColumnIndex,
|
|
224
|
+
viewRowIndex,
|
|
225
|
+
viewColumnIndex,
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
selectedCells.push(cell);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return selectedCells;
|
|
234
|
+
};
|
|
187
235
|
self.getBoundRowIndexFromViewRowIndex = function (viewRowIndex) {
|
|
188
236
|
if (self.boundRowIndexMap && self.boundRowIndexMap.has(viewRowIndex)) {
|
|
189
237
|
return self.boundRowIndexMap.get(viewRowIndex);
|
|
@@ -191,6 +239,9 @@ export default function (self, ctor) {
|
|
|
191
239
|
|
|
192
240
|
return undefined;
|
|
193
241
|
};
|
|
242
|
+
self.getBoundColumnIndexFromViewColumnIndex = function (viewColumnIndex) {
|
|
243
|
+
return self.orders.columns[viewColumnIndex];
|
|
244
|
+
};
|
|
194
245
|
self.getColumnHeaderCellHeight = function () {
|
|
195
246
|
if (!self.attributes.showColumnHeaders) {
|
|
196
247
|
return 0;
|
|
@@ -320,11 +371,15 @@ export default function (self, ctor) {
|
|
|
320
371
|
const currentFilterFunction =
|
|
321
372
|
header.filter || self.filter(header.type || 'string');
|
|
322
373
|
|
|
323
|
-
newViewData = newViewData.filter(function ([row]) {
|
|
324
|
-
|
|
325
|
-
|
|
374
|
+
newViewData = newViewData.filter(function ([row, originalRowIndex]) {
|
|
375
|
+
if (
|
|
376
|
+
self.attributes.allowFreezingRows &&
|
|
377
|
+
!self.attributes.filterFrozenRows &&
|
|
378
|
+
originalRowIndex < self.frozenRow
|
|
379
|
+
)
|
|
380
|
+
return true;
|
|
326
381
|
|
|
327
|
-
return
|
|
382
|
+
return currentFilterFunction(row[headerName], filterText);
|
|
328
383
|
});
|
|
329
384
|
}
|
|
330
385
|
|
|
@@ -332,7 +387,15 @@ export default function (self, ctor) {
|
|
|
332
387
|
for (const column of self.orderings.columns) {
|
|
333
388
|
const sortFn = column.sortFunction(column.orderBy, column.orderDirection);
|
|
334
389
|
|
|
335
|
-
newViewData.sort(([rowA], [rowB]) =>
|
|
390
|
+
newViewData.sort(([rowA], [rowB, rowIndexB]) => {
|
|
391
|
+
if (
|
|
392
|
+
self.attributes.allowFreezingRows &&
|
|
393
|
+
!self.attributes.sortFrozenRows &&
|
|
394
|
+
rowIndexB < self.frozenRow
|
|
395
|
+
)
|
|
396
|
+
return 0;
|
|
397
|
+
return sortFn(rowA, rowB);
|
|
398
|
+
});
|
|
336
399
|
}
|
|
337
400
|
|
|
338
401
|
return {
|
|
@@ -738,6 +801,7 @@ export default function (self, ctor) {
|
|
|
738
801
|
self.intf.clearPxColorAssertions = self.clearPxColorAssertions;
|
|
739
802
|
self.intf.integerToAlpha = self.integerToAlpha;
|
|
740
803
|
self.intf.copy = self.copy;
|
|
804
|
+
self.intf.cut = self.cut;
|
|
741
805
|
self.intf.paste = self.paste;
|
|
742
806
|
self.intf.setStyleProperty = self.setStyleProperty;
|
|
743
807
|
Object.defineProperty(self.intf, 'defaults', {
|
package/lib/publicMethods.js
CHANGED
|
@@ -353,6 +353,7 @@ export default function (self) {
|
|
|
353
353
|
selectedData: self.getSelectedData(),
|
|
354
354
|
selections: self.selections,
|
|
355
355
|
selectionBounds: self.selectionBounds,
|
|
356
|
+
selectedCells: self.getSelectedCells(),
|
|
356
357
|
});
|
|
357
358
|
if (dontDraw) {
|
|
358
359
|
return;
|
|
@@ -485,6 +486,7 @@ export default function (self) {
|
|
|
485
486
|
selectedData: self.getSelectedData(),
|
|
486
487
|
selections: self.selections,
|
|
487
488
|
selectionBounds: self.getSelectionBounds(),
|
|
489
|
+
selectedCells: self.getSelectedCells(),
|
|
488
490
|
});
|
|
489
491
|
};
|
|
490
492
|
/**
|
|
@@ -510,6 +512,7 @@ export default function (self) {
|
|
|
510
512
|
selectedData: self.getSelectedData(),
|
|
511
513
|
selections: self.selections,
|
|
512
514
|
selectionBounds: self.selectionBounds,
|
|
515
|
+
selectedCells: self.getSelectedCells(),
|
|
513
516
|
});
|
|
514
517
|
}
|
|
515
518
|
function addRow(ri) {
|
|
@@ -1252,6 +1255,7 @@ export default function (self) {
|
|
|
1252
1255
|
ev = {
|
|
1253
1256
|
selections: self.selections,
|
|
1254
1257
|
selectionBounds: self.selectionBounds,
|
|
1258
|
+
selectedCells: self.getSelectedCells(),
|
|
1255
1259
|
};
|
|
1256
1260
|
Object.defineProperty(ev, 'selectedData', {
|
|
1257
1261
|
get: function () {
|
package/lib/touch.js
CHANGED
|
@@ -144,41 +144,6 @@ export default function (self) {
|
|
|
144
144
|
self.touchEditCell = function (cell) {
|
|
145
145
|
self.beginEditAt(cell.columnIndex, cell.rowIndex);
|
|
146
146
|
};
|
|
147
|
-
self.touchCell = function (e) {
|
|
148
|
-
return function () {
|
|
149
|
-
clearInterval(self.calculatePPSTimer);
|
|
150
|
-
var i,
|
|
151
|
-
pos = self.getTouchPos(e);
|
|
152
|
-
if (
|
|
153
|
-
Math.abs(self.touchDelta.x) + Math.abs(self.touchDelta.y) <
|
|
154
|
-
self.attributes.touchDeadZone
|
|
155
|
-
) {
|
|
156
|
-
i = self.getCellAt(pos.x, pos.y);
|
|
157
|
-
if (!i) {
|
|
158
|
-
return;
|
|
159
|
-
}
|
|
160
|
-
if (
|
|
161
|
-
self.touchingCell &&
|
|
162
|
-
self.touchingCell.rowIndex === i.rowIndex &&
|
|
163
|
-
self.touchingCell.columnIndex === i.columnIndex
|
|
164
|
-
) {
|
|
165
|
-
self.touchEditCell(i);
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
if (self.input && self.input.editCell) {
|
|
169
|
-
self.endEdit();
|
|
170
|
-
}
|
|
171
|
-
self.touchingCell = i;
|
|
172
|
-
self.selectArea({
|
|
173
|
-
top: i.rowIndex,
|
|
174
|
-
bottom: i.rowIndex,
|
|
175
|
-
left: i.columnIndex,
|
|
176
|
-
right: i.columnIndex,
|
|
177
|
-
});
|
|
178
|
-
self.draw(true);
|
|
179
|
-
}
|
|
180
|
-
};
|
|
181
|
-
};
|
|
182
147
|
self.touchstart = function (e) {
|
|
183
148
|
if (e.changedTouches[0]) {
|
|
184
149
|
self.touchStart = self.getTouchPos(e);
|
|
@@ -203,7 +168,6 @@ export default function (self) {
|
|
|
203
168
|
self.stopAnimation = true;
|
|
204
169
|
self.animationFrames = 0;
|
|
205
170
|
self.stopPropagation(e);
|
|
206
|
-
e.preventDefault();
|
|
207
171
|
if (e.touches.length === 1 && e.changedTouches[0] && !self.zoomAltered) {
|
|
208
172
|
self.touchLength = 1;
|
|
209
173
|
self.touchStart = self.touchStart || self.touchStart1;
|
|
@@ -509,9 +473,8 @@ export default function (self) {
|
|
|
509
473
|
self.touchAnimateTo.y =
|
|
510
474
|
self.yPPS * self.attributes.touchReleaseAcceleration;
|
|
511
475
|
self.calculatePPSTimed();
|
|
512
|
-
if (
|
|
513
|
-
|
|
514
|
-
} else if (
|
|
476
|
+
if (
|
|
477
|
+
!dz &&
|
|
515
478
|
self.animationFrames === 0 &&
|
|
516
479
|
(Math.abs(self.xPPST) > self.attributes.scrollAnimationPPSThreshold ||
|
|
517
480
|
Math.abs(self.yPPST) > self.attributes.scrollAnimationPPSThreshold) &&
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "canvas-datagrid",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.14",
|
|
4
4
|
"description": "Canvas based data grid web component. Capable of displaying millions of contiguous hierarchical rows and columns without paging or loading, on a single canvas element.",
|
|
5
5
|
"main": "./dist/canvas-datagrid.js",
|
|
6
6
|
"module": "./dist/canvas-datagrid.module.js",
|