canvas-datagrid 0.4.4 → 0.4.6
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 +24 -0
- package/dist/canvas-datagrid.debug.js +3433 -1522
- 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 +295 -70
- package/lib/component.js +1 -2
- package/lib/contextMenu.js +10 -102
- package/lib/defaults.js +7 -0
- package/lib/docs.js +37 -3
- package/lib/dom.js +2 -1
- package/lib/draw.js +169 -69
- package/lib/events/index.js +587 -277
- package/lib/intf.js +33 -219
- package/lib/main.js +3 -0
- package/lib/publicMethods.js +17 -386
- package/lib/selections/index.js +985 -0
- package/lib/selections/type.d.ts +38 -0
- package/lib/selections/util.js +1319 -0
- package/package.json +4 -4
package/lib/events/index.js
CHANGED
|
@@ -493,6 +493,8 @@ export default function (self) {
|
|
|
493
493
|
y = self.mouse.y,
|
|
494
494
|
cell = self.getCellAt(x, y),
|
|
495
495
|
delta,
|
|
496
|
+
disallowVerticalAutoScroll = false,
|
|
497
|
+
disallowHorizontalAutoScroll = false,
|
|
496
498
|
ev = { NativeEvent: e, cell: cell, x: x, y: y },
|
|
497
499
|
previousCell = self.currentCell;
|
|
498
500
|
clearTimeout(self.scrollTimer);
|
|
@@ -700,32 +702,9 @@ export default function (self) {
|
|
|
700
702
|
if (self.hovers.onFilterButton) return;
|
|
701
703
|
if (self.hovers.onCellTreeIcon) return;
|
|
702
704
|
if (!self.dragAddToSelection && cell.rowIndex !== undefined) {
|
|
703
|
-
if (
|
|
704
|
-
self.selections[cell.rowIndex] &&
|
|
705
|
-
self.selections[cell.rowIndex].indexOf(cell.columnIndex) !==
|
|
706
|
-
-1
|
|
707
|
-
) {
|
|
708
|
-
self.selections[cell.rowIndex].splice(
|
|
709
|
-
self.selections[cell.rowIndex].indexOf(cell.columnIndex),
|
|
710
|
-
1,
|
|
711
|
-
);
|
|
712
|
-
}
|
|
705
|
+
if (self.isCellSelected(cell)) self.unselectCell(cell);
|
|
713
706
|
} else {
|
|
714
|
-
self.
|
|
715
|
-
self.selections[cell.rowIndex] || [];
|
|
716
|
-
if (
|
|
717
|
-
self.selections[cell.rowIndex].indexOf(cell.columnIndex) ===
|
|
718
|
-
-1
|
|
719
|
-
) {
|
|
720
|
-
self.selections[cell.rowIndex].push(cell.columnIndex);
|
|
721
|
-
var event = {
|
|
722
|
-
selections: self.selections,
|
|
723
|
-
selectedData: self.getSelectedData(),
|
|
724
|
-
selectedCells: self.getSelectedCells(),
|
|
725
|
-
selectionBounds: self.getSelectionBounds(),
|
|
726
|
-
};
|
|
727
|
-
self.dispatchEvent('selectionchanged', event);
|
|
728
|
-
}
|
|
707
|
+
if (!self.isCellSelected(cell)) self.selectCell(cell);
|
|
729
708
|
}
|
|
730
709
|
}
|
|
731
710
|
}
|
|
@@ -738,11 +717,8 @@ export default function (self) {
|
|
|
738
717
|
dragBounds.right !== self.selectionBounds.right) &&
|
|
739
718
|
!ctrl
|
|
740
719
|
) {
|
|
741
|
-
if (!(cell.hovered && self.hovers.onFilterButton))
|
|
742
|
-
self.
|
|
743
|
-
self.selectedRows = [];
|
|
744
|
-
self.selectedColumns = [];
|
|
745
|
-
}
|
|
720
|
+
if (!(cell.hovered && self.hovers.onFilterButton))
|
|
721
|
+
self.clearSelections();
|
|
746
722
|
if (dragBounds.top === -1) {
|
|
747
723
|
dragBounds.top = 0;
|
|
748
724
|
}
|
|
@@ -762,10 +738,33 @@ export default function (self) {
|
|
|
762
738
|
}
|
|
763
739
|
}
|
|
764
740
|
}
|
|
741
|
+
} else if (self.movingSelectionHandle) {
|
|
742
|
+
delta = {
|
|
743
|
+
x: Math.abs(self.dragStart.x - x),
|
|
744
|
+
y: Math.abs(self.dragStart.y - y),
|
|
745
|
+
};
|
|
765
746
|
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
747
|
+
// Disallow auto-scroll to the direction that overlay is not
|
|
748
|
+
// moving towards.
|
|
749
|
+
if (self.fillOverlay.direction === 'y') {
|
|
750
|
+
disallowHorizontalAutoScroll = true;
|
|
751
|
+
} else if (self.fillOverlay.direction === 'x') {
|
|
752
|
+
disallowVerticalAutoScroll = true;
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
if (delta) {
|
|
757
|
+
if (
|
|
758
|
+
self.attributes.autoScrollOnMousemove ||
|
|
759
|
+
disallowVerticalAutoScroll ||
|
|
760
|
+
disallowHorizontalAutoScroll
|
|
761
|
+
) {
|
|
762
|
+
var movedVertically =
|
|
763
|
+
!disallowVerticalAutoScroll &&
|
|
764
|
+
delta.y > self.attributes.autoScrollMargin;
|
|
765
|
+
var movedHorizontally =
|
|
766
|
+
!disallowHorizontalAutoScroll &&
|
|
767
|
+
delta.x > self.attributes.autoScrollMargin;
|
|
769
768
|
|
|
770
769
|
if (movedVertically && !movedHorizontally)
|
|
771
770
|
self.autoScrollZone(e, -1, y, ctrl);
|
|
@@ -807,17 +806,7 @@ export default function (self) {
|
|
|
807
806
|
if (startingBounds === JSON.stringify(sb)) {
|
|
808
807
|
return;
|
|
809
808
|
}
|
|
810
|
-
|
|
811
|
-
selections: self.selections,
|
|
812
|
-
selectionBounds: self.getSelectionBounds(),
|
|
813
|
-
selectedCells: self.getSelectedCells(),
|
|
814
|
-
};
|
|
815
|
-
Object.defineProperty(ev, 'selectedData', {
|
|
816
|
-
get: function () {
|
|
817
|
-
return self.getSelectedData();
|
|
818
|
-
},
|
|
819
|
-
});
|
|
820
|
-
self.dispatchEvent('selectionchanged', ev);
|
|
809
|
+
self.dispatchEvent('selectionchanged', self.getContextOfSelectionEvent());
|
|
821
810
|
}
|
|
822
811
|
if (self.input) {
|
|
823
812
|
self.endEdit();
|
|
@@ -889,7 +878,6 @@ export default function (self) {
|
|
|
889
878
|
return;
|
|
890
879
|
}
|
|
891
880
|
}
|
|
892
|
-
self.selections[i.rowIndex] = self.selections[i.rowIndex] || [];
|
|
893
881
|
if (
|
|
894
882
|
self.attributes.selectionMode === 'row' ||
|
|
895
883
|
self.currentCell.style === 'rowHeaderCell'
|
|
@@ -922,6 +910,7 @@ export default function (self) {
|
|
|
922
910
|
self.draw(true);
|
|
923
911
|
};
|
|
924
912
|
self.dragResizeColumn = function (e) {
|
|
913
|
+
const resizingColumn = self.dragMode === 'ew-resize';
|
|
925
914
|
var pos, x, y;
|
|
926
915
|
pos = self.getLayerPos(e);
|
|
927
916
|
x = self.resizingStartingWidth + pos.x - self.dragStart.x;
|
|
@@ -933,14 +922,31 @@ export default function (self) {
|
|
|
933
922
|
y = self.style.minRowHeight;
|
|
934
923
|
}
|
|
935
924
|
if (
|
|
936
|
-
self.dispatchEvent('resizecolumn', {
|
|
925
|
+
self.dispatchEvent(resizingColumn ? 'resizecolumn' : 'resizerow', {
|
|
937
926
|
x: x,
|
|
938
927
|
y: y,
|
|
928
|
+
width: x,
|
|
929
|
+
height: y,
|
|
930
|
+
columnIndex: resizingColumn ? self.draggingItem.columnIndex : undefined,
|
|
931
|
+
rowIndex: resizingColumn ? undefined : self.draggingItem.rowIndex,
|
|
939
932
|
draggingItem: self.draggingItem,
|
|
940
933
|
})
|
|
941
934
|
) {
|
|
942
935
|
return false;
|
|
943
936
|
}
|
|
937
|
+
if (self.attributes.resizeAfterDragged) {
|
|
938
|
+
self.pendingDragResize = {
|
|
939
|
+
item: self.draggingItem,
|
|
940
|
+
width: x,
|
|
941
|
+
height: y,
|
|
942
|
+
x: e.clientX,
|
|
943
|
+
y: e.clientY,
|
|
944
|
+
};
|
|
945
|
+
} else {
|
|
946
|
+
self.dragResizeApply(self.draggingItem, x, y);
|
|
947
|
+
}
|
|
948
|
+
};
|
|
949
|
+
self.dragResizeApply = function (draggingItem, width, height) {
|
|
944
950
|
if (
|
|
945
951
|
self.scrollBox.scrollLeft >
|
|
946
952
|
self.scrollBox.scrollWidth - self.attributes.resizeScrollZone &&
|
|
@@ -950,29 +956,27 @@ export default function (self) {
|
|
|
950
956
|
}
|
|
951
957
|
if (self.dragMode === 'ew-resize') {
|
|
952
958
|
self.sizes.columns[
|
|
953
|
-
|
|
959
|
+
draggingItem.header.style === 'rowHeaderCell'
|
|
954
960
|
? 'cornerCell'
|
|
955
|
-
:
|
|
956
|
-
] =
|
|
961
|
+
: draggingItem.sortColumnIndex
|
|
962
|
+
] = width;
|
|
957
963
|
if (
|
|
958
|
-
['rowHeaderCell', 'cornerCell'].indexOf(
|
|
959
|
-
|
|
960
|
-
) !== -1
|
|
964
|
+
['rowHeaderCell', 'cornerCell'].indexOf(draggingItem.header.style) !==
|
|
965
|
+
-1
|
|
961
966
|
) {
|
|
962
967
|
self.resize(true);
|
|
963
968
|
}
|
|
964
969
|
self.resizeChildGrids();
|
|
965
970
|
return;
|
|
966
|
-
}
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
self.sizes.trees[self.draggingItem.rowIndex] = y;
|
|
971
|
+
} else if (self.dragMode === 'ns-resize') {
|
|
972
|
+
if (draggingItem.rowOpen) {
|
|
973
|
+
self.sizes.trees[draggingItem.rowIndex] = height;
|
|
970
974
|
} else if (self.attributes.globalRowResize) {
|
|
971
|
-
self.style.cellHeight =
|
|
975
|
+
self.style.cellHeight = height;
|
|
972
976
|
} else {
|
|
973
|
-
self.sizes.rows[
|
|
977
|
+
self.sizes.rows[draggingItem.rowIndex] = height;
|
|
974
978
|
}
|
|
975
|
-
self.dispatchEvent('resizerow', { row:
|
|
979
|
+
self.dispatchEvent('resizerow', { row: height });
|
|
976
980
|
self.resizeChildGrids();
|
|
977
981
|
return;
|
|
978
982
|
}
|
|
@@ -981,6 +985,15 @@ export default function (self) {
|
|
|
981
985
|
self.stopDragResize = function (event) {
|
|
982
986
|
const pos = self.getLayerPos(event);
|
|
983
987
|
|
|
988
|
+
if (self.attributes.resizeAfterDragged) {
|
|
989
|
+
self.dragResizeApply(
|
|
990
|
+
self.pendingDragResize.item,
|
|
991
|
+
self.pendingDragResize.width,
|
|
992
|
+
self.pendingDragResize.height,
|
|
993
|
+
);
|
|
994
|
+
self.pendingDragResize = undefined;
|
|
995
|
+
}
|
|
996
|
+
|
|
984
997
|
if (self.dragMode === 'ew-resize') {
|
|
985
998
|
const hasMoved = !!(pos.x - self.dragStart.x);
|
|
986
999
|
// Check that dragItem is selected or part of selection.
|
|
@@ -996,6 +1009,18 @@ export default function (self) {
|
|
|
996
1009
|
// If the column is selected, resize it to width plus any other selected columns.
|
|
997
1010
|
self.fitSelectedColumns(width);
|
|
998
1011
|
}
|
|
1012
|
+
} else if (self.dragMode === 'ns-resize') {
|
|
1013
|
+
// Do the above for rows.
|
|
1014
|
+
const hasMoved = !!(pos.y - self.dragStart.y);
|
|
1015
|
+
const dragItemIsSelected = self.isRowSelected(self.dragItem.rowIndex);
|
|
1016
|
+
|
|
1017
|
+
if (hasMoved && dragItemIsSelected) {
|
|
1018
|
+
const height = Math.max(
|
|
1019
|
+
self.resizingStartingHeight + pos.y - self.dragStart.y,
|
|
1020
|
+
self.style.minRowHeight,
|
|
1021
|
+
);
|
|
1022
|
+
self.fitSelectedRows(height);
|
|
1023
|
+
}
|
|
999
1024
|
}
|
|
1000
1025
|
|
|
1001
1026
|
self.resize();
|
|
@@ -1169,17 +1194,16 @@ export default function (self) {
|
|
|
1169
1194
|
}
|
|
1170
1195
|
};
|
|
1171
1196
|
self.stopDragReorder = function (e) {
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
}[self.dragMode];
|
|
1197
|
+
let originalIndex;
|
|
1198
|
+
let targetIndex;
|
|
1199
|
+
const orderLists = {
|
|
1200
|
+
'row-reorder': self.orders.rows,
|
|
1201
|
+
'column-reorder': self.orders.columns,
|
|
1202
|
+
};
|
|
1203
|
+
const indexName = {
|
|
1204
|
+
'row-reorder': 'rowIndex',
|
|
1205
|
+
'column-reorder': 'sortColumnIndex',
|
|
1206
|
+
}[self.dragMode];
|
|
1183
1207
|
window.removeEventListener('mousemove', self.dragReorder, false);
|
|
1184
1208
|
window.removeEventListener('mouseup', self.stopDragReorder, false);
|
|
1185
1209
|
if (
|
|
@@ -1191,7 +1215,7 @@ export default function (self) {
|
|
|
1191
1215
|
(self.dragMode === 'row-reorder' &&
|
|
1192
1216
|
self.reorderTarget.rowIndex > -1 &&
|
|
1193
1217
|
self.reorderTarget.rowIndex < self.viewData.length)) &&
|
|
1194
|
-
self.reorderObject[
|
|
1218
|
+
self.reorderObject[indexName] !== self.reorderTarget[indexName] &&
|
|
1195
1219
|
!self.dispatchEvent('reorder', {
|
|
1196
1220
|
NativeEvent: e,
|
|
1197
1221
|
source: self.reorderObject,
|
|
@@ -1200,61 +1224,64 @@ export default function (self) {
|
|
|
1200
1224
|
})
|
|
1201
1225
|
) {
|
|
1202
1226
|
self.ignoreNextClick = true;
|
|
1203
|
-
|
|
1204
|
-
|
|
1227
|
+
originalIndex = orderLists[self.dragMode].indexOf(
|
|
1228
|
+
self.reorderObject[indexName],
|
|
1229
|
+
);
|
|
1230
|
+
targetIndex = orderLists[self.dragMode].indexOf(
|
|
1231
|
+
self.reorderTarget[indexName],
|
|
1232
|
+
);
|
|
1205
1233
|
if (self.dragMode === 'column-reorder') {
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1234
|
+
/** Select column view indexes in the first row */
|
|
1235
|
+
const selectedIndexes = self.getRowSelectionStates(0);
|
|
1236
|
+
const sortColumnIndices = [];
|
|
1237
|
+
const selectedColumnIndices = [];
|
|
1238
|
+
if (selectedIndexes) {
|
|
1239
|
+
originalIndex = selectedIndexes[0];
|
|
1240
|
+
selectedIndexes.forEach(function (value) {
|
|
1211
1241
|
sortColumnIndices.push(self.orders.columns[value]);
|
|
1212
1242
|
});
|
|
1213
1243
|
}
|
|
1214
|
-
|
|
1244
|
+
const deleteCount = sortColumnIndices.length;
|
|
1215
1245
|
if (
|
|
1216
|
-
|
|
1217
|
-
(
|
|
1246
|
+
targetIndex < originalIndex ||
|
|
1247
|
+
(targetIndex > originalIndex &&
|
|
1248
|
+
Math.abs(targetIndex - originalIndex) >= deleteCount)
|
|
1218
1249
|
) {
|
|
1219
|
-
|
|
1220
|
-
if (
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
for (
|
|
1224
|
-
if (i === 0) self.activeCell.columnIndex =
|
|
1225
|
-
selectedColumnIndices.push(
|
|
1226
|
-
self.
|
|
1227
|
-
|
|
1250
|
+
orderLists[self.dragMode].splice(originalIndex, deleteCount);
|
|
1251
|
+
if (targetIndex > originalIndex)
|
|
1252
|
+
targetIndex = targetIndex - (deleteCount - 1);
|
|
1253
|
+
|
|
1254
|
+
for (let i = 0; i < sortColumnIndices.length; i++) {
|
|
1255
|
+
if (i === 0) self.activeCell.columnIndex = targetIndex;
|
|
1256
|
+
selectedColumnIndices.push(targetIndex + i);
|
|
1257
|
+
orderLists[self.dragMode].splice(
|
|
1258
|
+
targetIndex + i,
|
|
1259
|
+
0,
|
|
1260
|
+
sortColumnIndices[i],
|
|
1261
|
+
);
|
|
1228
1262
|
}
|
|
1229
1263
|
|
|
1230
|
-
self.orders.columns =
|
|
1231
|
-
self.
|
|
1232
|
-
self.selections[rowIndex] = selectedColumnIndices;
|
|
1233
|
-
});
|
|
1264
|
+
self.orders.columns = orderLists[self.dragMode];
|
|
1265
|
+
self.selectColumnViewIndexes(selectedColumnIndices);
|
|
1234
1266
|
}
|
|
1235
1267
|
} else {
|
|
1236
|
-
|
|
1237
|
-
self.
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
}
|
|
1242
|
-
});
|
|
1268
|
+
/** The original name of this variable is `odata` */
|
|
1269
|
+
const rowIndexes = self.getRowViewIndexesFromSelection();
|
|
1270
|
+
const originalData = rowIndexes.map(
|
|
1271
|
+
(rowIndex) => self.viewData[rowIndex],
|
|
1272
|
+
);
|
|
1243
1273
|
if (
|
|
1244
|
-
|
|
1245
|
-
(
|
|
1274
|
+
targetIndex < originalIndex ||
|
|
1275
|
+
(targetIndex > originalIndex &&
|
|
1276
|
+
Math.abs(targetIndex - originalIndex) >= originalData.length)
|
|
1246
1277
|
) {
|
|
1247
|
-
self.viewData.splice(
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
self.viewData.splice(tIndex + i, 0, odata[i]);
|
|
1255
|
-
self.selections[tIndex + i] = selectedRows[i];
|
|
1256
|
-
self.selectedRows.push(tIndex + i);
|
|
1257
|
-
}
|
|
1278
|
+
self.viewData.splice(originalIndex, originalData.length);
|
|
1279
|
+
if (targetIndex > originalIndex)
|
|
1280
|
+
targetIndex = targetIndex - (originalData.length - 1);
|
|
1281
|
+
self.activeCell.rowIndex = targetIndex;
|
|
1282
|
+
for (let i = 0; i < originalData.length; i++)
|
|
1283
|
+
self.viewData.splice(targetIndex + i, 0, originalData[i]);
|
|
1284
|
+
self.moveSelection(0, targetIndex);
|
|
1258
1285
|
}
|
|
1259
1286
|
}
|
|
1260
1287
|
self.resize();
|
|
@@ -1445,7 +1472,8 @@ export default function (self) {
|
|
|
1445
1472
|
var ctrl = e.ctrlKey || e.metaKey,
|
|
1446
1473
|
move = /-move/.test(self.dragMode),
|
|
1447
1474
|
freeze = /frozen-row-marker|frozen-column-marker/.test(self.dragMode),
|
|
1448
|
-
resize = /-resize/.test(self.dragMode)
|
|
1475
|
+
resize = /-resize/.test(self.dragMode),
|
|
1476
|
+
selectionHandleMove = /selection-handle-br/.test(self.dragMode);
|
|
1449
1477
|
const onUnhideIndicator = self.hovers && self.hovers.unhideIndicator;
|
|
1450
1478
|
self.dragStart = overridePos || self.getLayerPos(e);
|
|
1451
1479
|
self.scrollStart = {
|
|
@@ -1464,15 +1492,14 @@ export default function (self) {
|
|
|
1464
1492
|
!self.currentCell.isColumnHeader &&
|
|
1465
1493
|
!move &&
|
|
1466
1494
|
!freeze &&
|
|
1467
|
-
!resize
|
|
1495
|
+
!resize &&
|
|
1496
|
+
!selectionHandleMove
|
|
1468
1497
|
) {
|
|
1469
1498
|
if (
|
|
1470
1499
|
!(self.dragMode == 'row-reorder' && self.isMultiRowsSelected) &&
|
|
1471
1500
|
!(self.currentCell.hovered && self.hovers.onFilterButton)
|
|
1472
1501
|
) {
|
|
1473
|
-
self.
|
|
1474
|
-
self.selectedRows = [];
|
|
1475
|
-
self.selectedColumns = [];
|
|
1502
|
+
self.clearSelections();
|
|
1476
1503
|
}
|
|
1477
1504
|
}
|
|
1478
1505
|
if (self.dragStartObject.isGrid) {
|
|
@@ -1523,9 +1550,26 @@ export default function (self) {
|
|
|
1523
1550
|
}
|
|
1524
1551
|
return;
|
|
1525
1552
|
}
|
|
1553
|
+
if (selectionHandleMove) {
|
|
1554
|
+
self.movingSelectionHandle = true;
|
|
1555
|
+
self.fillOverlay = {
|
|
1556
|
+
handle: {
|
|
1557
|
+
x: self.dragStartObject.x + self.dragStartObject.width / 2,
|
|
1558
|
+
y: self.dragStartObject.y + self.dragStartObject.height / 2,
|
|
1559
|
+
},
|
|
1560
|
+
snapTo: { x: -1, y: -1 },
|
|
1561
|
+
selection: self.getSelectionBounds(),
|
|
1562
|
+
};
|
|
1563
|
+
if (self.dispatchEvent('beginselectionhandlemove', { NativeEvent: e })) {
|
|
1564
|
+
return;
|
|
1565
|
+
}
|
|
1566
|
+
window.addEventListener('mousemove', self.selectionHandleMove, false);
|
|
1567
|
+
window.addEventListener('mouseup', self.stopSelectionHandleMove, false);
|
|
1568
|
+
return self.selectionHandleMove(e);
|
|
1569
|
+
}
|
|
1526
1570
|
if (move) {
|
|
1527
1571
|
self.draggingItem = self.dragItem;
|
|
1528
|
-
self.movingSelection = self.
|
|
1572
|
+
self.movingSelection = self.cloneSelections();
|
|
1529
1573
|
self.dragging = self.dragStartObject;
|
|
1530
1574
|
if (
|
|
1531
1575
|
self.dispatchEvent('beginmove', {
|
|
@@ -1733,7 +1777,7 @@ export default function (self) {
|
|
|
1733
1777
|
|
|
1734
1778
|
// TODO - most likely some column order related bugs in key based selection
|
|
1735
1779
|
// Arrows
|
|
1736
|
-
|
|
1780
|
+
const isArrowKey = [
|
|
1737
1781
|
'ArrowLeft',
|
|
1738
1782
|
'ArrowUp',
|
|
1739
1783
|
'ArrowRight',
|
|
@@ -1742,63 +1786,12 @@ export default function (self) {
|
|
|
1742
1786
|
|
|
1743
1787
|
// Shrinking and expanding selection using shift and arrow keys
|
|
1744
1788
|
if (e.shiftKey && isArrowKey) {
|
|
1745
|
-
const
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
const xAtLeft = x === 0;
|
|
1752
|
-
const xAtRight = x === cols;
|
|
1753
|
-
|
|
1754
|
-
if (e.key === 'ArrowUp') {
|
|
1755
|
-
if (y + 1 > firstSelectedRowIndex && !yAtTop) {
|
|
1756
|
-
self.selections.pop();
|
|
1757
|
-
} else if (y < firstSelectedRowIndex) {
|
|
1758
|
-
self.selections[y] = self.selections[y] || [];
|
|
1759
|
-
self.selections[y].push(x);
|
|
1760
|
-
} else if (yAtTop && self.activeCell.rowIndex !== 0) {
|
|
1761
|
-
self.selections.pop();
|
|
1762
|
-
}
|
|
1763
|
-
}
|
|
1764
|
-
|
|
1765
|
-
if (e.key === 'ArrowDown') {
|
|
1766
|
-
if (y > firstSelectedRowIndex && y === self.selections.length) {
|
|
1767
|
-
self.selections[y] = self.selections[y] || [];
|
|
1768
|
-
self.selections[y].push(x);
|
|
1769
|
-
} else if (y >= firstSelectedRowIndex && !yAtBottom) {
|
|
1770
|
-
delete self.selections[y - 1];
|
|
1771
|
-
} else if (yAtBottom && self.activeCell.rowIndex !== last) {
|
|
1772
|
-
delete self.selections[y - 1];
|
|
1773
|
-
}
|
|
1774
|
-
}
|
|
1775
|
-
|
|
1776
|
-
for (const selection of self.selections) {
|
|
1777
|
-
if (e.key === 'ArrowRight' && selection) {
|
|
1778
|
-
if (x > lastSelectedColumn) {
|
|
1779
|
-
selection.push(x);
|
|
1780
|
-
} else if (x <= lastSelectedColumn && !xAtRight) {
|
|
1781
|
-
selection.shift();
|
|
1782
|
-
} else if (xAtRight && self.activeCell.columnIndex !== cols) {
|
|
1783
|
-
selection.shift();
|
|
1784
|
-
}
|
|
1785
|
-
}
|
|
1786
|
-
|
|
1787
|
-
if (e.key === 'ArrowLeft' && selection) {
|
|
1788
|
-
if (x < firstSelectedColumnIndex) {
|
|
1789
|
-
selection.unshift(x);
|
|
1790
|
-
} else if (x >= firstSelectedColumnIndex && !xAtLeft) {
|
|
1791
|
-
selection.pop();
|
|
1792
|
-
} else if (xAtLeft && self.activeCell.columnIndex !== 0) {
|
|
1793
|
-
selection.pop();
|
|
1794
|
-
}
|
|
1795
|
-
}
|
|
1796
|
-
}
|
|
1797
|
-
|
|
1798
|
-
self.selectionBounds = self.getSelectionBounds();
|
|
1799
|
-
self.selectArea(undefined, ctrl);
|
|
1800
|
-
|
|
1801
|
-
self.draw(true);
|
|
1789
|
+
const changed = self.shrinkOrExpandSelections(
|
|
1790
|
+
{ rowIndex: y, columnIndex: x },
|
|
1791
|
+
e,
|
|
1792
|
+
true,
|
|
1793
|
+
);
|
|
1794
|
+
if (changed) self.draw(true);
|
|
1802
1795
|
}
|
|
1803
1796
|
|
|
1804
1797
|
if (x !== self.activeCell.columnIndex || y !== self.activeCell.rowIndex) {
|
|
@@ -1809,25 +1802,8 @@ export default function (self) {
|
|
|
1809
1802
|
|
|
1810
1803
|
self.setActiveCell(x, y);
|
|
1811
1804
|
if (!e.shiftKey && self.attributes.selectionFollowsActiveCell) {
|
|
1812
|
-
if (!ctrl)
|
|
1813
|
-
|
|
1814
|
-
self.selectedRows = [];
|
|
1815
|
-
self.selectedColumns = [];
|
|
1816
|
-
}
|
|
1817
|
-
self.selections[y] = self.selections[y] || [];
|
|
1818
|
-
self.selections[y].push(x);
|
|
1819
|
-
ev = {
|
|
1820
|
-
selectedData: self.getSelectedData(),
|
|
1821
|
-
selections: self.selections,
|
|
1822
|
-
selectionBounds: self.getSelectionBounds(),
|
|
1823
|
-
selectedCells: self.getSelectedCells(),
|
|
1824
|
-
};
|
|
1825
|
-
Object.defineProperty(ev, 'selectedData', {
|
|
1826
|
-
get: function () {
|
|
1827
|
-
return self.getSelectedData();
|
|
1828
|
-
},
|
|
1829
|
-
});
|
|
1830
|
-
self.dispatchEvent('selectionchanged', ev);
|
|
1805
|
+
if (!ctrl) self.clearSelections();
|
|
1806
|
+
self.selectCell({ rowIndex: y, viewColumnIndex: x });
|
|
1831
1807
|
}
|
|
1832
1808
|
self.draw(true);
|
|
1833
1809
|
}
|
|
@@ -1908,7 +1884,7 @@ export default function (self) {
|
|
|
1908
1884
|
deltaY = e.deltaY === undefined ? e.NativeEvent.deltaY : e.deltaY,
|
|
1909
1885
|
deltaMode =
|
|
1910
1886
|
e.deltaMode === undefined ? e.NativeEvent.deltaMode : e.deltaMode;
|
|
1911
|
-
|
|
1887
|
+
if (e.NativeEvent) e = e.NativeEvent;
|
|
1912
1888
|
if (wheeling) {
|
|
1913
1889
|
ev.preventDefault(e);
|
|
1914
1890
|
return;
|
|
@@ -1947,6 +1923,8 @@ export default function (self) {
|
|
|
1947
1923
|
mimeType,
|
|
1948
1924
|
startRowIndex,
|
|
1949
1925
|
startColIndex,
|
|
1926
|
+
minRowsLength = 0,
|
|
1927
|
+
minColumnsLength = 0,
|
|
1950
1928
|
) {
|
|
1951
1929
|
if (mimeType === 'text/html' && !isSupportedHtml(pasteValue)) {
|
|
1952
1930
|
console.warn(
|
|
@@ -1958,82 +1936,57 @@ export default function (self) {
|
|
|
1958
1936
|
|
|
1959
1937
|
return;
|
|
1960
1938
|
}
|
|
1961
|
-
|
|
1962
|
-
|
|
1939
|
+
|
|
1940
|
+
const rows = parseData(pasteValue, mimeType);
|
|
1941
|
+
const columnsLength = rows[0].length;
|
|
1963
1942
|
|
|
1964
1943
|
// selected cell. This mimics Excel's paste functionality, and works
|
|
1965
1944
|
// as a poor-man's fill-down.
|
|
1966
|
-
if (
|
|
1945
|
+
if (
|
|
1946
|
+
rows.length === 1 &&
|
|
1947
|
+
columnsLength === 1 &&
|
|
1948
|
+
minRowsLength <= 1 &&
|
|
1949
|
+
minColumnsLength <= 1
|
|
1950
|
+
) {
|
|
1967
1951
|
var cellData = rows[0][0].value.map((item) => item.value).join();
|
|
1968
1952
|
|
|
1969
1953
|
self.forEachSelectedCell(function (data, rowIndex, colName) {
|
|
1970
1954
|
data[rowIndex][colName] = cellData;
|
|
1971
1955
|
});
|
|
1972
1956
|
} else {
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
var existingRowData = self.viewData[realRowIndex];
|
|
1983
|
-
var newRowData = Object.assign({}, existingRowData);
|
|
1984
|
-
|
|
1985
|
-
selections[realRowIndex] = [];
|
|
1986
|
-
self.selectedRows.push(realRowIndex);
|
|
1987
|
-
|
|
1988
|
-
for (var colIndex = 0; colIndex < cells.length; colIndex++) {
|
|
1989
|
-
var column = schema[startColIndex + colIndex];
|
|
1990
|
-
|
|
1991
|
-
if (!column) {
|
|
1992
|
-
console.warn('Paste data exceeded grid bounds. Skipping.');
|
|
1993
|
-
continue;
|
|
1994
|
-
}
|
|
1995
|
-
|
|
1996
|
-
var columnName = column.name;
|
|
1997
|
-
var cellData = cells[colIndex].value
|
|
1998
|
-
.map((item) => item.value)
|
|
1999
|
-
.join('');
|
|
2000
|
-
|
|
2001
|
-
if (cellData === undefined || cellData === null) {
|
|
2002
|
-
newRowData[columnName] = existingRowData[columnName];
|
|
2003
|
-
continue;
|
|
2004
|
-
}
|
|
2005
|
-
|
|
2006
|
-
selections[realRowIndex].push(startColIndex + colIndex);
|
|
2007
|
-
|
|
2008
|
-
newRowData[columnName] = cellData;
|
|
2009
|
-
if (self.selectedColumns.indexOf(startColIndex + colIndex) === -1)
|
|
2010
|
-
self.selectedColumns.push(startColIndex + colIndex);
|
|
2011
|
-
}
|
|
2012
|
-
|
|
2013
|
-
self.originalData[self.boundRowIndexMap.get(realRowIndex)] = newRowData;
|
|
2014
|
-
// Update view date here to avoid a full refresh of `viewData`.
|
|
2015
|
-
// To stay in line with Excel and Google Sheet behaviour,
|
|
2016
|
-
// don't perform a full refresh (and filter/sort results)
|
|
2017
|
-
// as this would make any pasted values disappear and/or suddenly change position.
|
|
2018
|
-
self.viewData[realRowIndex] = newRowData;
|
|
1957
|
+
let direction = null;
|
|
1958
|
+
|
|
1959
|
+
if (minRowsLength > rows.length && minColumnsLength > columnsLength) {
|
|
1960
|
+
direction = 'both';
|
|
1961
|
+
} else if (minRowsLength > rows.length) {
|
|
1962
|
+
direction = 'vertical';
|
|
1963
|
+
} else if (minColumnsLength > columnsLength) {
|
|
1964
|
+
direction = 'horizontal';
|
|
2019
1965
|
}
|
|
2020
|
-
|
|
1966
|
+
|
|
1967
|
+
self.insert({
|
|
1968
|
+
rows: rows,
|
|
1969
|
+
startRowIndex: startRowIndex,
|
|
1970
|
+
startColumnIndex: startColIndex,
|
|
1971
|
+
minRowsLength: minRowsLength,
|
|
1972
|
+
minColumnsLength: minColumnsLength,
|
|
1973
|
+
reverseRows: false,
|
|
1974
|
+
reverseColumns: false,
|
|
1975
|
+
clearSelections: true,
|
|
1976
|
+
alwaysFilling: false,
|
|
1977
|
+
direction: direction,
|
|
1978
|
+
});
|
|
2021
1979
|
}
|
|
2022
1980
|
|
|
2023
1981
|
// selections is a sparse array, so we condense:
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
columnIndex,
|
|
2033
|
-
self.getBoundRowIndexFromViewRowIndex(rowIndex),
|
|
2034
|
-
self.getBoundColumnIndexFromViewColumnIndex(columnIndex),
|
|
2035
|
-
]);
|
|
2036
|
-
});
|
|
1982
|
+
const affectedCells = [];
|
|
1983
|
+
self.forEachSelectedCell((viewData, viewRowIndex, columnName, cell) => {
|
|
1984
|
+
affectedCells.push([
|
|
1985
|
+
viewRowIndex,
|
|
1986
|
+
cell.viewColumnIndex,
|
|
1987
|
+
cell.boundRowIndex,
|
|
1988
|
+
cell.boundColumnIndex,
|
|
1989
|
+
]);
|
|
2037
1990
|
});
|
|
2038
1991
|
|
|
2039
1992
|
self.dispatchEvent('afterpaste', {
|
|
@@ -2042,6 +1995,158 @@ export default function (self) {
|
|
|
2042
1995
|
|
|
2043
1996
|
return rows.length;
|
|
2044
1997
|
};
|
|
1998
|
+
self.insert = function ({
|
|
1999
|
+
rows = [],
|
|
2000
|
+
startRowIndex = 0,
|
|
2001
|
+
startColumnIndex = 0,
|
|
2002
|
+
minRowsLength = 0,
|
|
2003
|
+
minColumnsLength = 0,
|
|
2004
|
+
reverseRows = false,
|
|
2005
|
+
reverseColumns = false,
|
|
2006
|
+
clearSelections = false,
|
|
2007
|
+
alwaysFilling = false,
|
|
2008
|
+
direction = 'both',
|
|
2009
|
+
}) {
|
|
2010
|
+
var schema = self.getSchema();
|
|
2011
|
+
const rowsLength = Math.max(rows.length, minRowsLength);
|
|
2012
|
+
const fillCellCallback = self.fillCellCallback;
|
|
2013
|
+
const filledCells = [];
|
|
2014
|
+
|
|
2015
|
+
if (clearSelections) self.selections = [];
|
|
2016
|
+
|
|
2017
|
+
for (
|
|
2018
|
+
let rowPosReal = 0, rowDataPos = 0;
|
|
2019
|
+
rowPosReal < rowsLength;
|
|
2020
|
+
rowPosReal++, rowDataPos++
|
|
2021
|
+
) {
|
|
2022
|
+
if (rowDataPos >= rows.length) {
|
|
2023
|
+
rowDataPos = 0;
|
|
2024
|
+
}
|
|
2025
|
+
|
|
2026
|
+
const fillingRow = rowPosReal >= rows.length;
|
|
2027
|
+
const rowPosition = reverseRows
|
|
2028
|
+
? rowsLength - rowPosReal - 1
|
|
2029
|
+
: rowPosReal;
|
|
2030
|
+
// Rows may have been moved by user, so get the actual row index
|
|
2031
|
+
// (instead of the row index at which the row is rendered):
|
|
2032
|
+
var realRowIndex = self.orders.rows[startRowIndex + rowPosition];
|
|
2033
|
+
var cells = rows[rowDataPos];
|
|
2034
|
+
const cellsLength = Math.max(cells.length, minColumnsLength);
|
|
2035
|
+
|
|
2036
|
+
var existingRowData = self.viewData[realRowIndex];
|
|
2037
|
+
var newRowData = Object.assign({}, existingRowData);
|
|
2038
|
+
const fillArgs = fillCellCallback
|
|
2039
|
+
? {
|
|
2040
|
+
rows: rows,
|
|
2041
|
+
direction: direction,
|
|
2042
|
+
rowData: newRowData,
|
|
2043
|
+
existingRowData: existingRowData,
|
|
2044
|
+
rowIndex: realRowIndex,
|
|
2045
|
+
rowOffset: rowDataPos,
|
|
2046
|
+
cells: cells,
|
|
2047
|
+
reversed: direction === 'horizontal' ? reverseColumns : reverseRows,
|
|
2048
|
+
isFillingRow: fillingRow || alwaysFilling,
|
|
2049
|
+
fillingRowPosition: alwaysFilling
|
|
2050
|
+
? rowPosReal
|
|
2051
|
+
: fillingRow
|
|
2052
|
+
? rowPosReal - rows.length
|
|
2053
|
+
: -1,
|
|
2054
|
+
fillingRowLength: alwaysFilling
|
|
2055
|
+
? rowsLength
|
|
2056
|
+
: fillingRow
|
|
2057
|
+
? rowsLength - rows.length
|
|
2058
|
+
: -1,
|
|
2059
|
+
}
|
|
2060
|
+
: undefined;
|
|
2061
|
+
|
|
2062
|
+
for (
|
|
2063
|
+
var colPosReal = 0, cellDataPos = 0;
|
|
2064
|
+
colPosReal < cellsLength;
|
|
2065
|
+
colPosReal++, cellDataPos++
|
|
2066
|
+
) {
|
|
2067
|
+
if (cellDataPos >= cells.length) {
|
|
2068
|
+
cellDataPos = 0;
|
|
2069
|
+
}
|
|
2070
|
+
|
|
2071
|
+
const fillingColumn = colPosReal >= cells.length;
|
|
2072
|
+
const colPosition = reverseColumns
|
|
2073
|
+
? cellsLength - colPosReal - 1
|
|
2074
|
+
: colPosReal;
|
|
2075
|
+
const columnIndex = startColumnIndex + colPosition;
|
|
2076
|
+
var column = schema[columnIndex];
|
|
2077
|
+
|
|
2078
|
+
if (!column) {
|
|
2079
|
+
console.warn('Paste data exceeded grid bounds. Skipping.');
|
|
2080
|
+
continue;
|
|
2081
|
+
}
|
|
2082
|
+
|
|
2083
|
+
var columnName = column.name;
|
|
2084
|
+
var cellData = cells[cellDataPos];
|
|
2085
|
+
if (cellData && cellData.value) {
|
|
2086
|
+
cellData = cellData.value.map((item) => item.value).join('');
|
|
2087
|
+
}
|
|
2088
|
+
|
|
2089
|
+
const existingCellData = existingRowData[columnName];
|
|
2090
|
+
|
|
2091
|
+
if (
|
|
2092
|
+
fillCellCallback &&
|
|
2093
|
+
(fillingColumn || fillingRow || alwaysFilling)
|
|
2094
|
+
) {
|
|
2095
|
+
newRowData[columnName] = fillCellCallback({
|
|
2096
|
+
...fillArgs,
|
|
2097
|
+
column: column,
|
|
2098
|
+
columnIndex: columnIndex,
|
|
2099
|
+
columnOffset: cellDataPos,
|
|
2100
|
+
newCellData: cellData,
|
|
2101
|
+
existingCellData: existingCellData,
|
|
2102
|
+
isFillingColumn: fillingColumn || alwaysFilling,
|
|
2103
|
+
fillingColumnPosition: alwaysFilling
|
|
2104
|
+
? colPosReal
|
|
2105
|
+
: fillingColumn
|
|
2106
|
+
? colPosReal - cells.length
|
|
2107
|
+
: -1,
|
|
2108
|
+
fillingColumnLength: alwaysFilling
|
|
2109
|
+
? cellsLength
|
|
2110
|
+
: fillingColumn
|
|
2111
|
+
? cellsLength - cells.length
|
|
2112
|
+
: -1,
|
|
2113
|
+
});
|
|
2114
|
+
} else {
|
|
2115
|
+
newRowData[columnName] =
|
|
2116
|
+
cellData === undefined || cellData === null
|
|
2117
|
+
? existingCellData
|
|
2118
|
+
: cellData;
|
|
2119
|
+
}
|
|
2120
|
+
|
|
2121
|
+
self.selectCell(
|
|
2122
|
+
{ rowIndex: realRowIndex, viewColumnIndex: columnIndex },
|
|
2123
|
+
true,
|
|
2124
|
+
);
|
|
2125
|
+
|
|
2126
|
+
if (alwaysFilling || fillingRow || fillingColumn) {
|
|
2127
|
+
filledCells.push([
|
|
2128
|
+
realRowIndex,
|
|
2129
|
+
columnIndex,
|
|
2130
|
+
self.getBoundRowIndexFromViewRowIndex(realRowIndex),
|
|
2131
|
+
self.getBoundColumnIndexFromViewColumnIndex(columnIndex),
|
|
2132
|
+
]);
|
|
2133
|
+
}
|
|
2134
|
+
}
|
|
2135
|
+
|
|
2136
|
+
self.originalData[self.boundRowIndexMap.get(realRowIndex)] = newRowData;
|
|
2137
|
+
// Update view date here to avoid a full refresh of `viewData`.
|
|
2138
|
+
// To stay in line with Excel and Google Sheet behaviour,
|
|
2139
|
+
// don't perform a full refresh (and filter/sort results)
|
|
2140
|
+
// as this would make any pasted values disappear and/or suddenly change position.
|
|
2141
|
+
self.viewData[realRowIndex] = newRowData;
|
|
2142
|
+
}
|
|
2143
|
+
|
|
2144
|
+
if (filledCells.length > 0 || alwaysFilling) {
|
|
2145
|
+
self.dispatchEvent('afterfill', {
|
|
2146
|
+
filledCells: filledCells,
|
|
2147
|
+
});
|
|
2148
|
+
}
|
|
2149
|
+
};
|
|
2045
2150
|
self.getNextVisibleColumnIndex = function (visibleColumnIndex) {
|
|
2046
2151
|
var x,
|
|
2047
2152
|
s = self.getVisibleSchema();
|
|
@@ -2062,6 +2167,26 @@ export default function (self) {
|
|
|
2062
2167
|
}
|
|
2063
2168
|
return -1;
|
|
2064
2169
|
};
|
|
2170
|
+
self.getSelectionIndex = function () {
|
|
2171
|
+
const bounds = self.getSelectionBounds(true);
|
|
2172
|
+
if (!bounds) return;
|
|
2173
|
+
const { top, bottom } = bounds;
|
|
2174
|
+
for (let rowIndex = top; rowIndex <= bottom; rowIndex++) {
|
|
2175
|
+
const row = self.getRowSelectionStates(rowIndex);
|
|
2176
|
+
if (row) {
|
|
2177
|
+
if (row[0] === undefined) break;
|
|
2178
|
+
|
|
2179
|
+
return {
|
|
2180
|
+
row: rowIndex,
|
|
2181
|
+
column: row[0] < 0 ? row[1] : row[0],
|
|
2182
|
+
rowLength: bottom - rowIndex + 1,
|
|
2183
|
+
columnLength: row.length - (row[0] < 0 ? 1 : 0),
|
|
2184
|
+
};
|
|
2185
|
+
}
|
|
2186
|
+
}
|
|
2187
|
+
|
|
2188
|
+
return null;
|
|
2189
|
+
};
|
|
2065
2190
|
self.paste = function (event) {
|
|
2066
2191
|
if (!self.attributes.editable) {
|
|
2067
2192
|
return;
|
|
@@ -2098,28 +2223,24 @@ export default function (self) {
|
|
|
2098
2223
|
return;
|
|
2099
2224
|
}
|
|
2100
2225
|
|
|
2101
|
-
|
|
2226
|
+
const selectionIndex = self.getSelectionIndex();
|
|
2227
|
+
if (!selectionIndex) return;
|
|
2102
2228
|
|
|
2103
|
-
|
|
2104
|
-
for (
|
|
2105
|
-
let rowIndex = 0, len = self.selections.length;
|
|
2106
|
-
rowIndex < len;
|
|
2107
|
-
rowIndex++
|
|
2108
|
-
) {
|
|
2109
|
-
const row = self.selections[rowIndex];
|
|
2110
|
-
if (row) {
|
|
2111
|
-
if (row[0] === undefined) return;
|
|
2112
|
-
startCell = [rowIndex, row[0] < 0 ? row[1] : row[0]];
|
|
2113
|
-
break;
|
|
2114
|
-
}
|
|
2115
|
-
}
|
|
2229
|
+
var itemToPaste = pasteableItems[0];
|
|
2116
2230
|
|
|
2117
2231
|
// itemToPaste is cleared once accessed (getData or getAsString),
|
|
2118
2232
|
// so we need to store the type here, before reading its value:
|
|
2119
2233
|
var pasteType = itemToPaste.type;
|
|
2120
2234
|
|
|
2121
2235
|
itemToPaste.getAsString(function (pasteValue) {
|
|
2122
|
-
self.pasteData(
|
|
2236
|
+
self.pasteData(
|
|
2237
|
+
pasteValue,
|
|
2238
|
+
pasteType,
|
|
2239
|
+
selectionIndex.row,
|
|
2240
|
+
selectionIndex.column,
|
|
2241
|
+
selectionIndex.rowLength,
|
|
2242
|
+
selectionIndex.columnLength,
|
|
2243
|
+
);
|
|
2123
2244
|
|
|
2124
2245
|
self.draw();
|
|
2125
2246
|
});
|
|
@@ -2137,9 +2258,17 @@ export default function (self) {
|
|
|
2137
2258
|
self.copySelectedCellsToClipboard(event.clipboardData);
|
|
2138
2259
|
|
|
2139
2260
|
const affectedCells = self.clearSelectedCells();
|
|
2261
|
+
const apiCompatibleCells = affectedCells.map((cell) => {
|
|
2262
|
+
return [
|
|
2263
|
+
cell.viewRowIndex,
|
|
2264
|
+
cell.viewColumnIndex,
|
|
2265
|
+
cell.boundRowIndex,
|
|
2266
|
+
cell.boundColumnIndex,
|
|
2267
|
+
];
|
|
2268
|
+
});
|
|
2140
2269
|
|
|
2141
2270
|
self.dispatchEvent('aftercut', {
|
|
2142
|
-
cells:
|
|
2271
|
+
cells: apiCompatibleCells,
|
|
2143
2272
|
});
|
|
2144
2273
|
|
|
2145
2274
|
requestAnimationFrame(() => self.draw());
|
|
@@ -2159,5 +2288,186 @@ export default function (self) {
|
|
|
2159
2288
|
|
|
2160
2289
|
event.preventDefault();
|
|
2161
2290
|
};
|
|
2291
|
+
self.selectionHandleMove = function (e) {
|
|
2292
|
+
if (!self.movingSelectionHandle) {
|
|
2293
|
+
return;
|
|
2294
|
+
}
|
|
2295
|
+
|
|
2296
|
+
const clippingRect = self.getClippingRect(e);
|
|
2297
|
+
const rowIndex = self.currentCell.rowIndex;
|
|
2298
|
+
const columnIndex = self.currentCell.columnIndex;
|
|
2299
|
+
const isInSelectionBounds =
|
|
2300
|
+
rowIndex >= -1 &&
|
|
2301
|
+
columnIndex >= -1 &&
|
|
2302
|
+
self.fillOverlay.selection.left <= columnIndex &&
|
|
2303
|
+
self.fillOverlay.selection.right >= columnIndex &&
|
|
2304
|
+
self.fillOverlay.selection.top <= rowIndex &&
|
|
2305
|
+
self.fillOverlay.selection.bottom >= rowIndex;
|
|
2306
|
+
|
|
2307
|
+
self.fillOverlay.minX = clippingRect.x;
|
|
2308
|
+
self.fillOverlay.minY = clippingRect.y;
|
|
2309
|
+
self.fillOverlay.x = Math.max(clippingRect.x, e.clientX);
|
|
2310
|
+
self.fillOverlay.y = Math.max(clippingRect.y, e.clientY);
|
|
2311
|
+
|
|
2312
|
+
// If we are in the selection bounds, allow user to change directions.
|
|
2313
|
+
if (isInSelectionBounds) {
|
|
2314
|
+
self.fillOverlay.lastInBoundsLocation = {
|
|
2315
|
+
x: e.clientX,
|
|
2316
|
+
y: e.clientY,
|
|
2317
|
+
};
|
|
2318
|
+
} else if (
|
|
2319
|
+
self.fillOverlay.lastInBoundsLocation ||
|
|
2320
|
+
!self.fillOverlay.direction
|
|
2321
|
+
) {
|
|
2322
|
+
const lastInBoundsLocation = self.fillOverlay.lastInBoundsLocation;
|
|
2323
|
+
self.fillOverlay.lastInBoundsLocation = undefined;
|
|
2324
|
+
|
|
2325
|
+
const x = lastInBoundsLocation
|
|
2326
|
+
? lastInBoundsLocation.x
|
|
2327
|
+
: self.fillOverlay.handle.x;
|
|
2328
|
+
const y = lastInBoundsLocation
|
|
2329
|
+
? lastInBoundsLocation.y
|
|
2330
|
+
: self.fillOverlay.handle.y;
|
|
2331
|
+
const dx = Math.abs(e.clientX - x);
|
|
2332
|
+
const dy = Math.abs(e.clientY - y);
|
|
2333
|
+
|
|
2334
|
+
if (dx > 5 || dy > 5) {
|
|
2335
|
+
self.fillOverlay.direction = dx > dy ? 'x' : 'y';
|
|
2336
|
+
}
|
|
2337
|
+
}
|
|
2338
|
+
|
|
2339
|
+
if (rowIndex >= 0) {
|
|
2340
|
+
self.fillOverlay.rowIndex = rowIndex;
|
|
2341
|
+
}
|
|
2342
|
+
if (columnIndex >= 0) {
|
|
2343
|
+
self.fillOverlay.columnIndex = columnIndex;
|
|
2344
|
+
if (rowIndex === -1 && self.visibleRows.length) {
|
|
2345
|
+
self.fillOverlay.rowIndex = self.visibleRows[0];
|
|
2346
|
+
}
|
|
2347
|
+
}
|
|
2348
|
+
|
|
2349
|
+
if (rowIndex >= -1 && columnIndex >= -1) {
|
|
2350
|
+
self.fillOverlay.snap = self.currentCell;
|
|
2351
|
+
} else {
|
|
2352
|
+
self.fillOverlay.snap = undefined;
|
|
2353
|
+
}
|
|
2354
|
+
};
|
|
2355
|
+
self.stopSelectionHandleMove = function (e) {
|
|
2356
|
+
if (!self.fillOverlay.handle) {
|
|
2357
|
+
return false;
|
|
2358
|
+
}
|
|
2359
|
+
|
|
2360
|
+
self.ignoreNextClick = true;
|
|
2361
|
+
|
|
2362
|
+
window.removeEventListener('mousemove', self.selectionHandleMove, false);
|
|
2363
|
+
window.removeEventListener('mouseup', self.stopSelectionHandleMove, false);
|
|
2364
|
+
|
|
2365
|
+
const overlay = self.fillOverlay;
|
|
2366
|
+
const selectionIndex = self.getSelectionIndex();
|
|
2367
|
+
const bounds = overlay.selection;
|
|
2368
|
+
if (!selectionIndex) return;
|
|
2369
|
+
|
|
2370
|
+
self.movingSelectionHandle = undefined;
|
|
2371
|
+
self.fillOverlay = {};
|
|
2372
|
+
|
|
2373
|
+
if (overlay.rowIndex >= 0 && overlay.columnIndex >= 0) {
|
|
2374
|
+
const boundsOld = { ...bounds };
|
|
2375
|
+
const isVertical = overlay.direction === 'y';
|
|
2376
|
+
const isHorizontal = overlay.direction === 'x';
|
|
2377
|
+
|
|
2378
|
+
let startRow,
|
|
2379
|
+
rowLength,
|
|
2380
|
+
startColumn,
|
|
2381
|
+
columnLength,
|
|
2382
|
+
reverseVertically = false,
|
|
2383
|
+
reverseHorizontally = false;
|
|
2384
|
+
|
|
2385
|
+
if (isVertical) {
|
|
2386
|
+
if (overlay.rowIndex < bounds.top) {
|
|
2387
|
+
bounds.top = overlay.rowIndex;
|
|
2388
|
+
reverseVertically = true;
|
|
2389
|
+
} else if (overlay.rowIndex > bounds.bottom) {
|
|
2390
|
+
bounds.bottom = overlay.rowIndex;
|
|
2391
|
+
}
|
|
2392
|
+
|
|
2393
|
+
startRow =
|
|
2394
|
+
bounds.top < boundsOld.top ? bounds.top : boundsOld.bottom + 1;
|
|
2395
|
+
rowLength =
|
|
2396
|
+
bounds.top < boundsOld.top
|
|
2397
|
+
? boundsOld.top - bounds.top
|
|
2398
|
+
: bounds.bottom - boundsOld.bottom;
|
|
2399
|
+
startColumn = selectionIndex.column;
|
|
2400
|
+
columnLength = selectionIndex.columnLength;
|
|
2401
|
+
} else if (isHorizontal) {
|
|
2402
|
+
if (overlay.columnIndex < bounds.left) {
|
|
2403
|
+
bounds.left = overlay.columnIndex;
|
|
2404
|
+
reverseHorizontally = true;
|
|
2405
|
+
} else if (overlay.columnIndex > bounds.right) {
|
|
2406
|
+
bounds.right = overlay.columnIndex;
|
|
2407
|
+
}
|
|
2408
|
+
|
|
2409
|
+
startColumn =
|
|
2410
|
+
bounds.left < boundsOld.left ? bounds.left : boundsOld.right + 1;
|
|
2411
|
+
columnLength =
|
|
2412
|
+
bounds.left < boundsOld.left
|
|
2413
|
+
? boundsOld.left - bounds.left
|
|
2414
|
+
: bounds.right - boundsOld.right;
|
|
2415
|
+
startRow = selectionIndex.row;
|
|
2416
|
+
rowLength = selectionIndex.rowLength;
|
|
2417
|
+
}
|
|
2418
|
+
|
|
2419
|
+
if (
|
|
2420
|
+
bounds.left <= bounds.right &&
|
|
2421
|
+
bounds.top <= bounds.bottom &&
|
|
2422
|
+
(bounds.left < boundsOld.left ||
|
|
2423
|
+
bounds.top < boundsOld.top ||
|
|
2424
|
+
bounds.right > boundsOld.right ||
|
|
2425
|
+
bounds.bottom > boundsOld.bottom)
|
|
2426
|
+
) {
|
|
2427
|
+
const schema = self.getSchema();
|
|
2428
|
+
const rows = [];
|
|
2429
|
+
|
|
2430
|
+
for (
|
|
2431
|
+
let rowIndex = 0;
|
|
2432
|
+
rowIndex < Math.min(rowLength, selectionIndex.rowLength);
|
|
2433
|
+
rowIndex++
|
|
2434
|
+
) {
|
|
2435
|
+
const rowData = self.viewData[selectionIndex.row + rowIndex];
|
|
2436
|
+
|
|
2437
|
+
rows[rowIndex] = [];
|
|
2438
|
+
|
|
2439
|
+
for (
|
|
2440
|
+
let columnIndex = 0;
|
|
2441
|
+
columnIndex < Math.min(columnLength, selectionIndex.columnLength);
|
|
2442
|
+
columnIndex++
|
|
2443
|
+
) {
|
|
2444
|
+
const column = schema[selectionIndex.column + columnIndex];
|
|
2445
|
+
if (!column) continue;
|
|
2446
|
+
|
|
2447
|
+
const cellData = rowData[column.name];
|
|
2448
|
+
|
|
2449
|
+
rows[rowIndex][columnIndex] = cellData;
|
|
2450
|
+
}
|
|
2451
|
+
}
|
|
2452
|
+
|
|
2453
|
+
self.insert({
|
|
2454
|
+
rows: rows,
|
|
2455
|
+
startRowIndex: startRow,
|
|
2456
|
+
startColumnIndex: startColumn,
|
|
2457
|
+
minRowsLength: rowLength,
|
|
2458
|
+
minColumnsLength: columnLength,
|
|
2459
|
+
reverseRows: reverseVertically,
|
|
2460
|
+
reverseColumns: reverseHorizontally,
|
|
2461
|
+
clearSelections: false,
|
|
2462
|
+
alwaysFilling: true,
|
|
2463
|
+
direction: isHorizontal ? 'horizontal' : 'vertical',
|
|
2464
|
+
});
|
|
2465
|
+
|
|
2466
|
+
self.draw();
|
|
2467
|
+
}
|
|
2468
|
+
}
|
|
2469
|
+
|
|
2470
|
+
return true;
|
|
2471
|
+
};
|
|
2162
2472
|
return;
|
|
2163
2473
|
}
|