canvas-datagrid 0.4.2 → 0.4.5
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 +29 -0
- package/dist/canvas-datagrid.debug.js +1567 -326
- 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 +59 -6
- package/lib/contextMenu.js +178 -49
- package/lib/defaults.js +21 -7
- package/lib/docs.js +48 -1
- package/lib/dom.js +29 -2
- package/lib/draw.js +497 -84
- package/lib/events/index.js +650 -161
- package/lib/groups/util.js +42 -0
- package/lib/intf.js +43 -3
- package/lib/main.js +1 -0
- package/lib/publicMethods.js +199 -41
- package/package.json +2 -2
package/lib/events/index.js
CHANGED
|
@@ -74,6 +74,43 @@ export default function (self) {
|
|
|
74
74
|
1),
|
|
75
75
|
);
|
|
76
76
|
};
|
|
77
|
+
/**
|
|
78
|
+
* @returns {number} dataWidth
|
|
79
|
+
*/
|
|
80
|
+
self.refreshScrollCacheX = function () {
|
|
81
|
+
const s = self.getSchema();
|
|
82
|
+
self.scrollCache.x = [];
|
|
83
|
+
|
|
84
|
+
/** @type {number} it will be used in `reduceSchema` only */
|
|
85
|
+
let frozenWidth = 0;
|
|
86
|
+
|
|
87
|
+
const collapsedColumnGroups = self.getCollapsedColumnGroups();
|
|
88
|
+
const isColumnCollapsed = (columnIndex) =>
|
|
89
|
+
collapsedColumnGroups.findIndex(
|
|
90
|
+
(group) => columnIndex >= group.from && columnIndex <= group.to,
|
|
91
|
+
) >= 0;
|
|
92
|
+
|
|
93
|
+
const dataWidth =
|
|
94
|
+
s.reduce(function reduceSchema(accumulator, column, columnIndex) {
|
|
95
|
+
// intentional redefintion of column. This causes scrollCache to be in the correct order
|
|
96
|
+
const schemaIndex = self.orders.columns[columnIndex];
|
|
97
|
+
const columnWidth = self.getColumnWidth(schemaIndex);
|
|
98
|
+
column = s[schemaIndex];
|
|
99
|
+
if (!column.hidden && !isColumnCollapsed(columnIndex))
|
|
100
|
+
accumulator += columnWidth;
|
|
101
|
+
if (columnIndex < self.frozenColumn) {
|
|
102
|
+
self.scrollCache.x[columnIndex] = accumulator;
|
|
103
|
+
frozenWidth = accumulator;
|
|
104
|
+
} else {
|
|
105
|
+
self.scrollCache.x[columnIndex] = Math.max(
|
|
106
|
+
frozenWidth + columnWidth,
|
|
107
|
+
accumulator,
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
return accumulator;
|
|
111
|
+
}, 0) || 0;
|
|
112
|
+
return dataWidth;
|
|
113
|
+
};
|
|
77
114
|
self.resize = function (drawAfterResize) {
|
|
78
115
|
if (!self.canvas) {
|
|
79
116
|
return;
|
|
@@ -132,8 +169,7 @@ export default function (self) {
|
|
|
132
169
|
rowHeaderCellWidth = self.getRowHeaderCellWidth(),
|
|
133
170
|
topGroupAreaHeight = self.getColumnGroupAreaHeight(),
|
|
134
171
|
leftGroupAreaWidth = self.getRowGroupAreaWidth(),
|
|
135
|
-
ch = self.style.cellHeight
|
|
136
|
-
s = self.getSchema();
|
|
172
|
+
ch = self.style.cellHeight;
|
|
137
173
|
// sets actual DOM canvas element
|
|
138
174
|
function checkScrollBoxVisibility() {
|
|
139
175
|
self.scrollBox.horizontalBarVisible =
|
|
@@ -187,7 +223,7 @@ export default function (self) {
|
|
|
187
223
|
}
|
|
188
224
|
});
|
|
189
225
|
}
|
|
190
|
-
|
|
226
|
+
dataWidth = self.refreshScrollCacheX();
|
|
191
227
|
self.scrollCache.y = [];
|
|
192
228
|
for (x = 0; x < l; x += 1) {
|
|
193
229
|
self.scrollCache.y[x] = dataHeight;
|
|
@@ -199,32 +235,6 @@ export default function (self) {
|
|
|
199
235
|
if (l > 1) {
|
|
200
236
|
self.scrollCache.y[x] = dataHeight;
|
|
201
237
|
}
|
|
202
|
-
const collapsedColumnGroups = self.getCollapsedColumnGroups();
|
|
203
|
-
const isColumnCollapsed = (columnIndex) =>
|
|
204
|
-
collapsedColumnGroups.findIndex(
|
|
205
|
-
(group) => columnIndex >= group.from && columnIndex <= group.to,
|
|
206
|
-
) >= 0;
|
|
207
|
-
/** @type {number} it will be used in `reduceSchema` only */
|
|
208
|
-
let frozenWidth = 0;
|
|
209
|
-
dataWidth =
|
|
210
|
-
s.reduce(function reduceSchema(accumulator, column, columnIndex) {
|
|
211
|
-
// intentional redefintion of column. This causes scrollCache to be in the correct order
|
|
212
|
-
const schemaIndex = self.orders.columns[columnIndex];
|
|
213
|
-
const columnWidth = self.getColumnWidth(schemaIndex);
|
|
214
|
-
column = s[schemaIndex];
|
|
215
|
-
if (!column.hidden && !isColumnCollapsed(columnIndex))
|
|
216
|
-
accumulator += columnWidth;
|
|
217
|
-
if (columnIndex < self.frozenColumn) {
|
|
218
|
-
self.scrollCache.x[columnIndex] = accumulator;
|
|
219
|
-
frozenWidth = accumulator;
|
|
220
|
-
} else {
|
|
221
|
-
self.scrollCache.x[columnIndex] = Math.max(
|
|
222
|
-
frozenWidth + columnWidth,
|
|
223
|
-
accumulator,
|
|
224
|
-
);
|
|
225
|
-
}
|
|
226
|
-
return accumulator;
|
|
227
|
-
}, 0) || 0;
|
|
228
238
|
if (self.attributes.showNewRow) {
|
|
229
239
|
dataHeight += ch;
|
|
230
240
|
}
|
|
@@ -376,9 +386,17 @@ export default function (self) {
|
|
|
376
386
|
);
|
|
377
387
|
// set canvas drawing related items
|
|
378
388
|
if (!self.isChildGrid) {
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
389
|
+
const newWidth = self.width * ratio;
|
|
390
|
+
const newHeight = self.height * ratio;
|
|
391
|
+
// We need to check is settings size to canvas necessary,
|
|
392
|
+
// because settings the canvas'size will cause the canvas and its state be cleared
|
|
393
|
+
// even if the size is the same.
|
|
394
|
+
// Notes: Please don't call `self.resize()` without a subsequent call to `self.draw()`
|
|
395
|
+
if (self.canvas.width !== newWidth || self.canvas.height !== newHeight) {
|
|
396
|
+
self.canvas.width = newWidth;
|
|
397
|
+
self.canvas.height = newHeight;
|
|
398
|
+
self.ctx.scale(ratio, ratio);
|
|
399
|
+
}
|
|
382
400
|
}
|
|
383
401
|
// resize any open dom elements (input/textarea)
|
|
384
402
|
self.resizeEditInput();
|
|
@@ -475,6 +493,8 @@ export default function (self) {
|
|
|
475
493
|
y = self.mouse.y,
|
|
476
494
|
cell = self.getCellAt(x, y),
|
|
477
495
|
delta,
|
|
496
|
+
disallowVerticalAutoScroll = false,
|
|
497
|
+
disallowHorizontalAutoScroll = false,
|
|
478
498
|
ev = { NativeEvent: e, cell: cell, x: x, y: y },
|
|
479
499
|
previousCell = self.currentCell;
|
|
480
500
|
clearTimeout(self.scrollTimer);
|
|
@@ -501,6 +521,20 @@ export default function (self) {
|
|
|
501
521
|
}
|
|
502
522
|
self.currentCell = cell;
|
|
503
523
|
|
|
524
|
+
if (
|
|
525
|
+
!self.draggingItem && // It is not in dragging mode (avoid changing hovers frequent)
|
|
526
|
+
cell &&
|
|
527
|
+
(cell.context === 'cell' || cell.context === self.cursorGrab)
|
|
528
|
+
) {
|
|
529
|
+
const indicator = self.getUnhideIndicator(self.mouse.x, self.mouse.y);
|
|
530
|
+
if (indicator) {
|
|
531
|
+
self.cursor = 'pointer';
|
|
532
|
+
self.hovers = { unhideIndicator: indicator };
|
|
533
|
+
self.draw();
|
|
534
|
+
return;
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
|
|
504
538
|
self.hovers = {};
|
|
505
539
|
if (!self.draggingItem && cell) {
|
|
506
540
|
self.dragItem = cell;
|
|
@@ -592,6 +626,9 @@ export default function (self) {
|
|
|
592
626
|
dragBounds.top = -1;
|
|
593
627
|
dragBounds.bottom = self.viewData.length - 1;
|
|
594
628
|
if (dragBounds.left < 0) dragBounds.left = 0;
|
|
629
|
+
if (dragBounds.left != dragBounds.right)
|
|
630
|
+
self.isMultiColumnsSelected = true;
|
|
631
|
+
else self.isMultiRowsSelected = false;
|
|
595
632
|
}
|
|
596
633
|
|
|
597
634
|
if (
|
|
@@ -705,6 +742,8 @@ export default function (self) {
|
|
|
705
742
|
) {
|
|
706
743
|
if (!(cell.hovered && self.hovers.onFilterButton)) {
|
|
707
744
|
self.selections = [];
|
|
745
|
+
self.selectedRows = [];
|
|
746
|
+
self.selectedColumns = [];
|
|
708
747
|
}
|
|
709
748
|
if (dragBounds.top === -1) {
|
|
710
749
|
dragBounds.top = 0;
|
|
@@ -716,14 +755,42 @@ export default function (self) {
|
|
|
716
755
|
}
|
|
717
756
|
} else {
|
|
718
757
|
self.selectArea(sBounds, true);
|
|
719
|
-
|
|
758
|
+
self.activeCell.rowIndex = sBounds.top;
|
|
759
|
+
self.activeCell.columnIndex = sBounds.left;
|
|
760
|
+
if (sBounds.left == -1 && sBounds.top !== sBounds.bottom) {
|
|
761
|
+
self.activeCell.columnIndex = 0;
|
|
720
762
|
self.isMultiRowsSelected = true;
|
|
763
|
+
self.isMultiColumnsSelected = false;
|
|
764
|
+
}
|
|
721
765
|
}
|
|
722
766
|
}
|
|
767
|
+
} else if (self.movingSelectionHandle) {
|
|
768
|
+
delta = {
|
|
769
|
+
x: Math.abs(self.dragStart.x - x),
|
|
770
|
+
y: Math.abs(self.dragStart.y - y),
|
|
771
|
+
};
|
|
723
772
|
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
773
|
+
// Disallow auto-scroll to the direction that overlay is not
|
|
774
|
+
// moving towards.
|
|
775
|
+
if (self.fillOverlay.direction === 'y') {
|
|
776
|
+
disallowHorizontalAutoScroll = true;
|
|
777
|
+
} else if (self.fillOverlay.direction === 'x') {
|
|
778
|
+
disallowVerticalAutoScroll = true;
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
if (delta) {
|
|
783
|
+
if (
|
|
784
|
+
self.attributes.autoScrollOnMousemove ||
|
|
785
|
+
disallowVerticalAutoScroll ||
|
|
786
|
+
disallowHorizontalAutoScroll
|
|
787
|
+
) {
|
|
788
|
+
var movedVertically =
|
|
789
|
+
!disallowVerticalAutoScroll &&
|
|
790
|
+
delta.y > self.attributes.autoScrollMargin;
|
|
791
|
+
var movedHorizontally =
|
|
792
|
+
!disallowHorizontalAutoScroll &&
|
|
793
|
+
delta.x > self.attributes.autoScrollMargin;
|
|
727
794
|
|
|
728
795
|
if (movedVertically && !movedHorizontally)
|
|
729
796
|
self.autoScrollZone(e, -1, y, ctrl);
|
|
@@ -791,6 +858,15 @@ export default function (self) {
|
|
|
791
858
|
return;
|
|
792
859
|
}
|
|
793
860
|
|
|
861
|
+
const unhideIndicator = self.getUnhideIndicator(pos.x, pos.y);
|
|
862
|
+
if (unhideIndicator) {
|
|
863
|
+
const { dir, orderIndex0, orderIndex1 } = unhideIndicator;
|
|
864
|
+
if (dir === 'l' || dir === 'r')
|
|
865
|
+
self.unhideColumns(orderIndex0, orderIndex1);
|
|
866
|
+
else self.unhideRows(orderIndex0, orderIndex1);
|
|
867
|
+
return;
|
|
868
|
+
}
|
|
869
|
+
|
|
794
870
|
let group = self.getColumnGroupAt(pos.x, pos.y);
|
|
795
871
|
if (!group) group = self.getRowGroupAt(pos.x, pos.y);
|
|
796
872
|
if (group) {
|
|
@@ -948,12 +1024,8 @@ export default function (self) {
|
|
|
948
1024
|
}
|
|
949
1025
|
|
|
950
1026
|
self.resize();
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
self.dragResizeColumn,
|
|
954
|
-
false,
|
|
955
|
-
);
|
|
956
|
-
document.body.removeEventListener('mouseup', self.stopDragResize, false);
|
|
1027
|
+
window.removeEventListener('mousemove', self.dragResizeColumn, false);
|
|
1028
|
+
window.removeEventListener('mouseup', self.stopDragResize, false);
|
|
957
1029
|
self.setStorageData();
|
|
958
1030
|
self.draw(true);
|
|
959
1031
|
self.ignoreNextClick = true;
|
|
@@ -1060,7 +1132,7 @@ export default function (self) {
|
|
|
1060
1132
|
if (document.exitPointerLock) {
|
|
1061
1133
|
document.exitPointerLock();
|
|
1062
1134
|
}
|
|
1063
|
-
|
|
1135
|
+
window.removeEventListener('mousemove', self.scrollGrid, false);
|
|
1064
1136
|
};
|
|
1065
1137
|
self.dragReorder = function (e) {
|
|
1066
1138
|
var pos,
|
|
@@ -1078,10 +1150,7 @@ export default function (self) {
|
|
|
1078
1150
|
return;
|
|
1079
1151
|
}
|
|
1080
1152
|
if ((e.ctrlKey || e.metaKey || e.shiftKey) && self.reorderObject) {
|
|
1081
|
-
if (
|
|
1082
|
-
self.dragMode === 'column-reorder' &&
|
|
1083
|
-
!self.isMultiColumnsSelected(self.draggingItem.header.index)
|
|
1084
|
-
) {
|
|
1153
|
+
if (self.dragMode === 'column-reorder' && !self.isMultiColumnsSelected) {
|
|
1085
1154
|
self.selectColumn(self.draggingItem.header.index, false, false);
|
|
1086
1155
|
}
|
|
1087
1156
|
}
|
|
@@ -1105,6 +1174,11 @@ export default function (self) {
|
|
|
1105
1174
|
-1,
|
|
1106
1175
|
self.activeCell.rowIndex,
|
|
1107
1176
|
);
|
|
1177
|
+
if (self.isMultiColumnsSelected)
|
|
1178
|
+
self.reorderObject = self.getVisibleCellByIndex(
|
|
1179
|
+
self.activeCell.columnIndex,
|
|
1180
|
+
-1,
|
|
1181
|
+
);
|
|
1108
1182
|
if (!self.reorderObject) return;
|
|
1109
1183
|
self.reorderTarget = self.currentCell;
|
|
1110
1184
|
self.reorderObject.dragOffset = {
|
|
@@ -1131,8 +1205,8 @@ export default function (self) {
|
|
|
1131
1205
|
'row-reorder': 'rowIndex',
|
|
1132
1206
|
'column-reorder': 'sortColumnIndex',
|
|
1133
1207
|
}[self.dragMode];
|
|
1134
|
-
|
|
1135
|
-
|
|
1208
|
+
window.removeEventListener('mousemove', self.dragReorder, false);
|
|
1209
|
+
window.removeEventListener('mouseup', self.stopDragReorder, false);
|
|
1136
1210
|
if (
|
|
1137
1211
|
self.reorderObject &&
|
|
1138
1212
|
self.reorderTarget &&
|
|
@@ -1155,23 +1229,34 @@ export default function (self) {
|
|
|
1155
1229
|
tIndex = cr[self.dragMode].indexOf(self.reorderTarget[i]);
|
|
1156
1230
|
if (self.dragMode === 'column-reorder') {
|
|
1157
1231
|
var sortColumnIndices = [];
|
|
1158
|
-
var
|
|
1232
|
+
var selectedColumnIndices = [];
|
|
1159
1233
|
if (self.selections[0]) {
|
|
1234
|
+
oIndex = self.selections[0][0];
|
|
1160
1235
|
self.selections[0].forEach(function (value) {
|
|
1161
1236
|
sortColumnIndices.push(self.orders.columns[value]);
|
|
1162
1237
|
});
|
|
1163
1238
|
}
|
|
1164
1239
|
var deleteCount = sortColumnIndices.length;
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
cr[self.dragMode].splice(
|
|
1240
|
+
if (
|
|
1241
|
+
tIndex < oIndex ||
|
|
1242
|
+
(tIndex > oIndex && Math.abs(tIndex - oIndex) >= deleteCount)
|
|
1243
|
+
) {
|
|
1244
|
+
cr[self.dragMode].splice(oIndex, deleteCount);
|
|
1245
|
+
if (tIndex > oIndex) tIndex = tIndex - (deleteCount - 1);
|
|
1246
|
+
|
|
1247
|
+
self.selectedColumns = [];
|
|
1248
|
+
for (var i = 0; i < sortColumnIndices.length; i++) {
|
|
1249
|
+
if (i === 0) self.activeCell.columnIndex = tIndex;
|
|
1250
|
+
selectedColumnIndices.push(tIndex + i);
|
|
1251
|
+
self.selectedColumns.push(sortColumnIndices[i]);
|
|
1252
|
+
cr[self.dragMode].splice(tIndex + i, 0, sortColumnIndices[i]);
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1255
|
+
self.orders.columns = cr[self.dragMode];
|
|
1256
|
+
self.viewData.forEach(function (row, rowIndex) {
|
|
1257
|
+
self.selections[rowIndex] = selectedColumnIndices;
|
|
1258
|
+
});
|
|
1170
1259
|
}
|
|
1171
|
-
self.orders.columns = cr[self.dragMode];
|
|
1172
|
-
self.viewData.forEach(function (row, rowIndex) {
|
|
1173
|
-
self.selections[rowIndex] = seletedColumnIndices;
|
|
1174
|
-
});
|
|
1175
1260
|
} else {
|
|
1176
1261
|
var selectedRows = [];
|
|
1177
1262
|
self.selections.forEach(function (row, rowIndex) {
|
|
@@ -1180,13 +1265,21 @@ export default function (self) {
|
|
|
1180
1265
|
odata.push(self.viewData[rowIndex]);
|
|
1181
1266
|
}
|
|
1182
1267
|
});
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
self.
|
|
1189
|
-
self.
|
|
1268
|
+
if (
|
|
1269
|
+
tIndex < oIndex ||
|
|
1270
|
+
(tIndex > oIndex && Math.abs(tIndex - oIndex) >= odata.length)
|
|
1271
|
+
) {
|
|
1272
|
+
self.viewData.splice(oIndex, odata.length);
|
|
1273
|
+
self.selections = [];
|
|
1274
|
+
self.selectedRows = [];
|
|
1275
|
+
if (tIndex > oIndex) tIndex = tIndex - (odata.length - 1);
|
|
1276
|
+
self.activeCell.rowIndex = tIndex;
|
|
1277
|
+
|
|
1278
|
+
for (var i = 0; i < odata.length; i++) {
|
|
1279
|
+
self.viewData.splice(tIndex + i, 0, odata[i]);
|
|
1280
|
+
self.selections[tIndex + i] = selectedRows[i];
|
|
1281
|
+
self.selectedRows.push(tIndex + i);
|
|
1282
|
+
}
|
|
1190
1283
|
}
|
|
1191
1284
|
}
|
|
1192
1285
|
self.resize();
|
|
@@ -1217,8 +1310,8 @@ export default function (self) {
|
|
|
1217
1310
|
}
|
|
1218
1311
|
};
|
|
1219
1312
|
self.stopDragMove = function (e) {
|
|
1220
|
-
|
|
1221
|
-
|
|
1313
|
+
window.removeEventListener('mousemove', self.dragMove, false);
|
|
1314
|
+
window.removeEventListener('mouseup', self.stopDragMove, false);
|
|
1222
1315
|
var b = self.getSelectionBounds();
|
|
1223
1316
|
if (
|
|
1224
1317
|
self.dispatchEvent('endmove', { NativeEvent: e, cell: self.currentCell })
|
|
@@ -1249,16 +1342,30 @@ export default function (self) {
|
|
|
1249
1342
|
) {
|
|
1250
1343
|
return;
|
|
1251
1344
|
}
|
|
1252
|
-
var pos = self.getLayerPos(e)
|
|
1345
|
+
var pos = self.getLayerPos(e);
|
|
1346
|
+
|
|
1347
|
+
self.ignoreNextClick = true;
|
|
1348
|
+
self.freezeMarkerPosition = pos;
|
|
1349
|
+
pos.x -= self.getRowGroupAreaWidth();
|
|
1350
|
+
pos.y -= self.getColumnGroupAreaHeight();
|
|
1351
|
+
if (
|
|
1352
|
+
Math.abs(pos.x) > self.attributes.reorderDeadZone ||
|
|
1353
|
+
Math.abs(pos.y) > self.attributes.reorderDeadZone
|
|
1354
|
+
) {
|
|
1355
|
+
setTimeout(function () {
|
|
1356
|
+
self.autoScrollZone(e, pos.x, pos.y, false);
|
|
1357
|
+
}, 1);
|
|
1358
|
+
}
|
|
1359
|
+
};
|
|
1360
|
+
self.stopFreezeMove = function (e) {
|
|
1361
|
+
let pos = self.getLayerPos(e),
|
|
1253
1362
|
bm = self.style.gridBorderCollapse === 'collapse' ? 1 : 2,
|
|
1254
1363
|
columnHeaderCellBorder = self.style.columnHeaderCellBorderWidth * bm,
|
|
1255
1364
|
columnHeaderCellHeight = self.getColumnHeaderCellHeight(),
|
|
1256
1365
|
rowHeaderCellWidth = self.getRowHeaderCellWidth();
|
|
1257
|
-
|
|
1258
|
-
self.ignoreNextClick = true;
|
|
1259
|
-
self.freezeMarkerPosition = pos;
|
|
1260
1366
|
pos.x -= self.getRowGroupAreaWidth();
|
|
1261
1367
|
pos.y -= self.getColumnGroupAreaHeight();
|
|
1368
|
+
|
|
1262
1369
|
if (
|
|
1263
1370
|
self.currentCell &&
|
|
1264
1371
|
self.currentCell.rowIndex !== undefined &&
|
|
@@ -1294,15 +1401,20 @@ export default function (self) {
|
|
|
1294
1401
|
self.currentCell.columnIndex !== undefined &&
|
|
1295
1402
|
self.dragMode === 'frozen-column-marker'
|
|
1296
1403
|
) {
|
|
1404
|
+
const dataWidth = self.refreshScrollCacheX();
|
|
1297
1405
|
self.scrollBox.scrollLeft = 0;
|
|
1298
|
-
|
|
1406
|
+
let x =
|
|
1407
|
+
self.currentCell.x -
|
|
1408
|
+
self.style.frozenMarkerWidth -
|
|
1409
|
+
self.style.frozenMarkerBorderWidth;
|
|
1410
|
+
if (pos.x > x + self.currentCell.width / 2)
|
|
1411
|
+
self.frozenColumn = self.currentCell.columnIndex + 1;
|
|
1412
|
+
else if (self.currentCell.columnIndex >= 0)
|
|
1413
|
+
self.frozenColumn = self.currentCell.columnIndex;
|
|
1299
1414
|
self.scrollBox.bar.h.x =
|
|
1300
|
-
rowHeaderCellWidth + self.scrollCache.x[self.frozenColumn
|
|
1301
|
-
self.scrollBox.box.h.x =
|
|
1302
|
-
rowHeaderCellWidth + self.scrollCache.x[self.frozenColumn - 1];
|
|
1303
|
-
var dataWidth = self.scrollCache.x[self.scrollCache.x.length - 1];
|
|
1415
|
+
rowHeaderCellWidth + self.scrollCache.x[self.frozenColumn];
|
|
1304
1416
|
self.scrollBox.widthBoxRatio =
|
|
1305
|
-
(self.scrollBox.width - self.scrollCache.x[self.frozenColumn
|
|
1417
|
+
(self.scrollBox.width - self.scrollCache.x[self.frozenColumn]) /
|
|
1306
1418
|
dataWidth;
|
|
1307
1419
|
self.scrollBox.scrollBoxWidth =
|
|
1308
1420
|
self.scrollBox.width * self.scrollBox.widthBoxRatio -
|
|
@@ -1321,10 +1433,9 @@ export default function (self) {
|
|
|
1321
1433
|
self.autoScrollZone(e, pos.x, pos.y, false);
|
|
1322
1434
|
}, 1);
|
|
1323
1435
|
}
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
document.body.removeEventListener('mouseup', self.stopFreezeMove, false);
|
|
1436
|
+
|
|
1437
|
+
window.removeEventListener('mousemove', self.freezeMove, false);
|
|
1438
|
+
window.removeEventListener('mouseup', self.stopFreezeMove, false);
|
|
1328
1439
|
self.freezeMarkerPosition = undefined;
|
|
1329
1440
|
if (
|
|
1330
1441
|
self.dispatchEvent('endfreezemove', {
|
|
@@ -1338,6 +1449,7 @@ export default function (self) {
|
|
|
1338
1449
|
return;
|
|
1339
1450
|
}
|
|
1340
1451
|
self.draw(true);
|
|
1452
|
+
self.resize();
|
|
1341
1453
|
};
|
|
1342
1454
|
self.mousedown = function (e, overridePos) {
|
|
1343
1455
|
self.lastMouseDownTarget = e.target;
|
|
@@ -1358,7 +1470,9 @@ export default function (self) {
|
|
|
1358
1470
|
var ctrl = e.ctrlKey || e.metaKey,
|
|
1359
1471
|
move = /-move/.test(self.dragMode),
|
|
1360
1472
|
freeze = /frozen-row-marker|frozen-column-marker/.test(self.dragMode),
|
|
1361
|
-
resize = /-resize/.test(self.dragMode)
|
|
1473
|
+
resize = /-resize/.test(self.dragMode),
|
|
1474
|
+
selectionHandleMove = /selection-handle-br/.test(self.dragMode);
|
|
1475
|
+
const onUnhideIndicator = self.hovers && self.hovers.unhideIndicator;
|
|
1362
1476
|
self.dragStart = overridePos || self.getLayerPos(e);
|
|
1363
1477
|
self.scrollStart = {
|
|
1364
1478
|
left: self.scrollBox.scrollLeft,
|
|
@@ -1376,19 +1490,25 @@ export default function (self) {
|
|
|
1376
1490
|
!self.currentCell.isColumnHeader &&
|
|
1377
1491
|
!move &&
|
|
1378
1492
|
!freeze &&
|
|
1379
|
-
!resize
|
|
1493
|
+
!resize &&
|
|
1494
|
+
!selectionHandleMove
|
|
1380
1495
|
) {
|
|
1381
1496
|
if (
|
|
1382
1497
|
!(self.dragMode == 'row-reorder' && self.isMultiRowsSelected) &&
|
|
1383
1498
|
!(self.currentCell.hovered && self.hovers.onFilterButton)
|
|
1384
1499
|
) {
|
|
1385
1500
|
self.selections = [];
|
|
1501
|
+
self.selectedRows = [];
|
|
1502
|
+
self.selectedColumns = [];
|
|
1386
1503
|
}
|
|
1387
1504
|
}
|
|
1388
1505
|
if (self.dragStartObject.isGrid) {
|
|
1389
1506
|
return;
|
|
1390
1507
|
}
|
|
1391
|
-
if (
|
|
1508
|
+
if (
|
|
1509
|
+
self.scrollModes.indexOf(self.dragStartObject.context) !== -1 &&
|
|
1510
|
+
!onUnhideIndicator
|
|
1511
|
+
) {
|
|
1392
1512
|
self.scrollMode = self.dragStartObject.context;
|
|
1393
1513
|
self.scrollStartMode = self.dragStartObject.context;
|
|
1394
1514
|
self.scrollGrid(e);
|
|
@@ -1404,8 +1524,8 @@ export default function (self) {
|
|
|
1404
1524
|
};
|
|
1405
1525
|
self.canvas.requestPointerLock();
|
|
1406
1526
|
}
|
|
1407
|
-
|
|
1408
|
-
|
|
1527
|
+
window.addEventListener('mousemove', self.scrollGrid, false);
|
|
1528
|
+
window.addEventListener('mouseup', self.stopScrollGrid, false);
|
|
1409
1529
|
self.ignoreNextClick = true;
|
|
1410
1530
|
return;
|
|
1411
1531
|
}
|
|
@@ -1423,11 +1543,30 @@ export default function (self) {
|
|
|
1423
1543
|
self.dragStartObject.columnIndex > -1
|
|
1424
1544
|
) {
|
|
1425
1545
|
self.selectColumn(self.currentCell.header.index, ctrl, e.shiftKey);
|
|
1426
|
-
|
|
1546
|
+
return;
|
|
1547
|
+
}
|
|
1548
|
+
if (self.attributes.selectionMode !== 'row') {
|
|
1427
1549
|
self.mousemove(e);
|
|
1428
1550
|
}
|
|
1429
1551
|
return;
|
|
1430
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
|
+
}
|
|
1431
1570
|
if (move) {
|
|
1432
1571
|
self.draggingItem = self.dragItem;
|
|
1433
1572
|
self.movingSelection = self.selections.concat([]);
|
|
@@ -1440,8 +1579,8 @@ export default function (self) {
|
|
|
1440
1579
|
) {
|
|
1441
1580
|
return;
|
|
1442
1581
|
}
|
|
1443
|
-
|
|
1444
|
-
|
|
1582
|
+
window.addEventListener('mousemove', self.dragMove, false);
|
|
1583
|
+
window.addEventListener('mouseup', self.stopDragMove, false);
|
|
1445
1584
|
return self.mousemove(e);
|
|
1446
1585
|
}
|
|
1447
1586
|
if (freeze) {
|
|
@@ -1453,11 +1592,15 @@ export default function (self) {
|
|
|
1453
1592
|
if (self.dispatchEvent('beginfreezemove', { NativeEvent: e })) {
|
|
1454
1593
|
return;
|
|
1455
1594
|
}
|
|
1456
|
-
|
|
1457
|
-
|
|
1595
|
+
|
|
1596
|
+
self.freezeMarkerPosition = self.getLayerPos(e);
|
|
1597
|
+
self.freezeMarkerPosition.isGrab = true;
|
|
1598
|
+
|
|
1599
|
+
window.addEventListener('mousemove', self.freezeMove, false);
|
|
1600
|
+
window.addEventListener('mouseup', self.stopFreezeMove, false);
|
|
1458
1601
|
return self.mousemove(e);
|
|
1459
1602
|
}
|
|
1460
|
-
if (resize) {
|
|
1603
|
+
if (resize && !onUnhideIndicator) {
|
|
1461
1604
|
self.draggingItem = self.dragItem;
|
|
1462
1605
|
if (self.draggingItem.rowOpen) {
|
|
1463
1606
|
self.resizingStartingHeight =
|
|
@@ -1472,22 +1615,19 @@ export default function (self) {
|
|
|
1472
1615
|
? 'cornerCell'
|
|
1473
1616
|
: self.draggingItem.sortColumnIndex
|
|
1474
1617
|
] || self.draggingItem.width;
|
|
1475
|
-
|
|
1476
|
-
|
|
1618
|
+
window.addEventListener('mousemove', self.dragResizeColumn, false);
|
|
1619
|
+
window.addEventListener('mouseup', self.stopDragResize, false);
|
|
1477
1620
|
return;
|
|
1478
1621
|
}
|
|
1479
1622
|
if (['row-reorder', 'column-reorder'].indexOf(self.dragMode) !== -1) {
|
|
1480
1623
|
self.draggingItem = self.dragStartObject;
|
|
1481
|
-
if (
|
|
1482
|
-
self.dragMode === 'column-reorder' &&
|
|
1483
|
-
!self.isMultiColumnsSelected(self.currentCell.header.index)
|
|
1484
|
-
) {
|
|
1624
|
+
if (self.dragMode === 'column-reorder' && !self.isMultiColumnsSelected) {
|
|
1485
1625
|
self.selectColumn(self.currentCell.header.index, ctrl, e.shiftKey);
|
|
1486
1626
|
} else if (self.dragMode === 'row-reorder' && !self.isMultiRowsSelected) {
|
|
1487
1627
|
self.selectRow(self.dragStartObject.rowIndex, ctrl, null);
|
|
1488
1628
|
}
|
|
1489
|
-
|
|
1490
|
-
|
|
1629
|
+
window.addEventListener('mousemove', self.dragReorder, false);
|
|
1630
|
+
window.addEventListener('mouseup', self.stopDragReorder, false);
|
|
1491
1631
|
return;
|
|
1492
1632
|
}
|
|
1493
1633
|
};
|
|
@@ -1715,6 +1855,8 @@ export default function (self) {
|
|
|
1715
1855
|
if (!e.shiftKey && self.attributes.selectionFollowsActiveCell) {
|
|
1716
1856
|
if (!ctrl) {
|
|
1717
1857
|
self.selections = [];
|
|
1858
|
+
self.selectedRows = [];
|
|
1859
|
+
self.selectedColumns = [];
|
|
1718
1860
|
}
|
|
1719
1861
|
self.selections[y] = self.selections[y] || [];
|
|
1720
1862
|
self.selections[y].push(x);
|
|
@@ -1849,6 +1991,8 @@ export default function (self) {
|
|
|
1849
1991
|
mimeType,
|
|
1850
1992
|
startRowIndex,
|
|
1851
1993
|
startColIndex,
|
|
1994
|
+
minRowsLength = 0,
|
|
1995
|
+
minColumnsLength = 0,
|
|
1852
1996
|
) {
|
|
1853
1997
|
if (mimeType === 'text/html' && !isSupportedHtml(pasteValue)) {
|
|
1854
1998
|
console.warn(
|
|
@@ -1860,61 +2004,49 @@ export default function (self) {
|
|
|
1860
2004
|
|
|
1861
2005
|
return;
|
|
1862
2006
|
}
|
|
1863
|
-
|
|
1864
|
-
|
|
2007
|
+
|
|
2008
|
+
self.selectedRows = [];
|
|
2009
|
+
self.selectedColumns = [];
|
|
2010
|
+
|
|
2011
|
+
const rows = parseData(pasteValue, mimeType);
|
|
2012
|
+
const columnsLength = rows[0].length;
|
|
1865
2013
|
|
|
1866
2014
|
// selected cell. This mimics Excel's paste functionality, and works
|
|
1867
2015
|
// as a poor-man's fill-down.
|
|
1868
|
-
if (
|
|
2016
|
+
if (
|
|
2017
|
+
rows.length === 1 &&
|
|
2018
|
+
columnsLength === 1 &&
|
|
2019
|
+
minRowsLength <= 1 &&
|
|
2020
|
+
minColumnsLength <= 1
|
|
2021
|
+
) {
|
|
1869
2022
|
var cellData = rows[0][0].value.map((item) => item.value).join();
|
|
1870
2023
|
|
|
1871
2024
|
self.forEachSelectedCell(function (data, rowIndex, colName) {
|
|
1872
2025
|
data[rowIndex][colName] = cellData;
|
|
1873
2026
|
});
|
|
1874
2027
|
} else {
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
var newRowData = Object.assign({}, existingRowData);
|
|
1884
|
-
|
|
1885
|
-
selections[realRowIndex] = [];
|
|
1886
|
-
|
|
1887
|
-
for (var colIndex = 0; colIndex < cells.length; colIndex++) {
|
|
1888
|
-
var column = schema[startColIndex + colIndex];
|
|
1889
|
-
|
|
1890
|
-
if (!column) {
|
|
1891
|
-
console.warn('Paste data exceeded grid bounds. Skipping.');
|
|
1892
|
-
continue;
|
|
1893
|
-
}
|
|
1894
|
-
|
|
1895
|
-
var columnName = column.name;
|
|
1896
|
-
var cellData = cells[colIndex].value
|
|
1897
|
-
.map((item) => item.value)
|
|
1898
|
-
.join('');
|
|
1899
|
-
|
|
1900
|
-
if (cellData === undefined || cellData === null) {
|
|
1901
|
-
newRowData[columnName] = existingRowData[columnName];
|
|
1902
|
-
continue;
|
|
1903
|
-
}
|
|
1904
|
-
|
|
1905
|
-
selections[realRowIndex].push(startColIndex + colIndex);
|
|
1906
|
-
|
|
1907
|
-
newRowData[columnName] = cellData;
|
|
1908
|
-
}
|
|
1909
|
-
|
|
1910
|
-
self.originalData[self.boundRowIndexMap.get(realRowIndex)] = newRowData;
|
|
1911
|
-
// Update view date here to avoid a full refresh of `viewData`.
|
|
1912
|
-
// To stay in line with Excel and Google Sheet behaviour,
|
|
1913
|
-
// don't perform a full refresh (and filter/sort results)
|
|
1914
|
-
// as this would make any pasted values disappear and/or suddenly change position.
|
|
1915
|
-
self.viewData[realRowIndex] = newRowData;
|
|
2028
|
+
let direction = null;
|
|
2029
|
+
|
|
2030
|
+
if (minRowsLength > rows.length && minColumnsLength > columnsLength) {
|
|
2031
|
+
direction = 'both';
|
|
2032
|
+
} else if (minRowsLength > rows.length) {
|
|
2033
|
+
direction = 'vertical';
|
|
2034
|
+
} else if (minColumnsLength > columnsLength) {
|
|
2035
|
+
direction = 'horizontal';
|
|
1916
2036
|
}
|
|
1917
|
-
|
|
2037
|
+
|
|
2038
|
+
self.insert({
|
|
2039
|
+
rows: rows,
|
|
2040
|
+
startRowIndex: startRowIndex,
|
|
2041
|
+
startColumnIndex: startColIndex,
|
|
2042
|
+
minRowsLength: minRowsLength,
|
|
2043
|
+
minColumnsLength: minColumnsLength,
|
|
2044
|
+
reverseRows: false,
|
|
2045
|
+
reverseColumns: false,
|
|
2046
|
+
clearSelections: true,
|
|
2047
|
+
alwaysFilling: false,
|
|
2048
|
+
direction: direction,
|
|
2049
|
+
});
|
|
1918
2050
|
}
|
|
1919
2051
|
|
|
1920
2052
|
// selections is a sparse array, so we condense:
|
|
@@ -1939,6 +2071,165 @@ export default function (self) {
|
|
|
1939
2071
|
|
|
1940
2072
|
return rows.length;
|
|
1941
2073
|
};
|
|
2074
|
+
self.insert = function ({
|
|
2075
|
+
rows = [],
|
|
2076
|
+
startRowIndex = 0,
|
|
2077
|
+
startColumnIndex = 0,
|
|
2078
|
+
minRowsLength = 0,
|
|
2079
|
+
minColumnsLength = 0,
|
|
2080
|
+
reverseRows = false,
|
|
2081
|
+
reverseColumns = false,
|
|
2082
|
+
clearSelections = false,
|
|
2083
|
+
alwaysFilling = false,
|
|
2084
|
+
direction = 'both',
|
|
2085
|
+
}) {
|
|
2086
|
+
var schema = self.getSchema();
|
|
2087
|
+
const rowsLength = Math.max(rows.length, minRowsLength);
|
|
2088
|
+
const fillCellCallback = self.fillCellCallback;
|
|
2089
|
+
const selections = clearSelections ? [] : self.selections;
|
|
2090
|
+
const filledCells = [];
|
|
2091
|
+
|
|
2092
|
+
for (
|
|
2093
|
+
let rowPosReal = 0, rowDataPos = 0;
|
|
2094
|
+
rowPosReal < rowsLength;
|
|
2095
|
+
rowPosReal++, rowDataPos++
|
|
2096
|
+
) {
|
|
2097
|
+
if (rowDataPos >= rows.length) {
|
|
2098
|
+
rowDataPos = 0;
|
|
2099
|
+
}
|
|
2100
|
+
|
|
2101
|
+
const fillingRow = rowPosReal >= rows.length;
|
|
2102
|
+
const rowPosition = reverseRows
|
|
2103
|
+
? rowsLength - rowPosReal - 1
|
|
2104
|
+
: rowPosReal;
|
|
2105
|
+
// Rows may have been moved by user, so get the actual row index
|
|
2106
|
+
// (instead of the row index at which the row is rendered):
|
|
2107
|
+
var realRowIndex = self.orders.rows[startRowIndex + rowPosition];
|
|
2108
|
+
var cells = rows[rowDataPos];
|
|
2109
|
+
const cellsLength = Math.max(cells.length, minColumnsLength);
|
|
2110
|
+
|
|
2111
|
+
var existingRowData = self.viewData[realRowIndex];
|
|
2112
|
+
var newRowData = Object.assign({}, existingRowData);
|
|
2113
|
+
const fillArgs = fillCellCallback
|
|
2114
|
+
? {
|
|
2115
|
+
rows: rows,
|
|
2116
|
+
direction: direction,
|
|
2117
|
+
rowData: newRowData,
|
|
2118
|
+
existingRowData: existingRowData,
|
|
2119
|
+
rowIndex: realRowIndex,
|
|
2120
|
+
rowOffset: rowDataPos,
|
|
2121
|
+
cells: cells,
|
|
2122
|
+
reversed: direction === 'horizontal' ? reverseColumns : reverseRows,
|
|
2123
|
+
isFillingRow: fillingRow || alwaysFilling,
|
|
2124
|
+
fillingRowPosition: alwaysFilling
|
|
2125
|
+
? rowPosReal
|
|
2126
|
+
: fillingRow
|
|
2127
|
+
? rowPosReal - rows.length
|
|
2128
|
+
: -1,
|
|
2129
|
+
fillingRowLength: alwaysFilling
|
|
2130
|
+
? rowsLength
|
|
2131
|
+
: fillingRow
|
|
2132
|
+
? rowsLength - rows.length
|
|
2133
|
+
: -1,
|
|
2134
|
+
}
|
|
2135
|
+
: undefined;
|
|
2136
|
+
|
|
2137
|
+
self.selectedRows.push(realRowIndex);
|
|
2138
|
+
|
|
2139
|
+
if (selections[realRowIndex] === undefined) {
|
|
2140
|
+
selections[realRowIndex] = [];
|
|
2141
|
+
}
|
|
2142
|
+
|
|
2143
|
+
for (
|
|
2144
|
+
var colPosReal = 0, cellDataPos = 0;
|
|
2145
|
+
colPosReal < cellsLength;
|
|
2146
|
+
colPosReal++, cellDataPos++
|
|
2147
|
+
) {
|
|
2148
|
+
if (cellDataPos >= cells.length) {
|
|
2149
|
+
cellDataPos = 0;
|
|
2150
|
+
}
|
|
2151
|
+
|
|
2152
|
+
const fillingColumn = colPosReal >= cells.length;
|
|
2153
|
+
const colPosition = reverseColumns
|
|
2154
|
+
? cellsLength - colPosReal - 1
|
|
2155
|
+
: colPosReal;
|
|
2156
|
+
const columnIndex = startColumnIndex + colPosition;
|
|
2157
|
+
var column = schema[columnIndex];
|
|
2158
|
+
|
|
2159
|
+
if (!column) {
|
|
2160
|
+
console.warn('Paste data exceeded grid bounds. Skipping.');
|
|
2161
|
+
continue;
|
|
2162
|
+
}
|
|
2163
|
+
|
|
2164
|
+
var columnName = column.name;
|
|
2165
|
+
var cellData = cells[cellDataPos];
|
|
2166
|
+
if (cellData && cellData.value) {
|
|
2167
|
+
cellData = cellData.value.map((item) => item.value).join('');
|
|
2168
|
+
}
|
|
2169
|
+
|
|
2170
|
+
const existingCellData = existingRowData[columnName];
|
|
2171
|
+
|
|
2172
|
+
if (
|
|
2173
|
+
fillCellCallback &&
|
|
2174
|
+
(fillingColumn || fillingRow || alwaysFilling)
|
|
2175
|
+
) {
|
|
2176
|
+
newRowData[columnName] = fillCellCallback({
|
|
2177
|
+
...fillArgs,
|
|
2178
|
+
column: column,
|
|
2179
|
+
columnIndex: columnIndex,
|
|
2180
|
+
columnOffset: cellDataPos,
|
|
2181
|
+
newCellData: cellData,
|
|
2182
|
+
existingCellData: existingCellData,
|
|
2183
|
+
isFillingColumn: fillingColumn || alwaysFilling,
|
|
2184
|
+
fillingColumnPosition: alwaysFilling
|
|
2185
|
+
? colPosReal
|
|
2186
|
+
: fillingColumn
|
|
2187
|
+
? colPosReal - cells.length
|
|
2188
|
+
: -1,
|
|
2189
|
+
fillingColumnLength: alwaysFilling
|
|
2190
|
+
? cellsLength
|
|
2191
|
+
: fillingColumn
|
|
2192
|
+
? cellsLength - cells.length
|
|
2193
|
+
: -1,
|
|
2194
|
+
});
|
|
2195
|
+
} else {
|
|
2196
|
+
newRowData[columnName] =
|
|
2197
|
+
cellData === undefined || cellData === null
|
|
2198
|
+
? existingCellData
|
|
2199
|
+
: cellData;
|
|
2200
|
+
}
|
|
2201
|
+
|
|
2202
|
+
selections[realRowIndex].push(columnIndex);
|
|
2203
|
+
|
|
2204
|
+
if (alwaysFilling || fillingRow || fillingColumn) {
|
|
2205
|
+
filledCells.push([
|
|
2206
|
+
realRowIndex,
|
|
2207
|
+
columnIndex,
|
|
2208
|
+
self.getBoundRowIndexFromViewRowIndex(realRowIndex),
|
|
2209
|
+
self.getBoundColumnIndexFromViewColumnIndex(columnIndex),
|
|
2210
|
+
]);
|
|
2211
|
+
}
|
|
2212
|
+
|
|
2213
|
+
if (self.selectedColumns.indexOf(columnIndex) === -1)
|
|
2214
|
+
self.selectedColumns.push(columnIndex);
|
|
2215
|
+
}
|
|
2216
|
+
|
|
2217
|
+
self.originalData[self.boundRowIndexMap.get(realRowIndex)] = newRowData;
|
|
2218
|
+
// Update view date here to avoid a full refresh of `viewData`.
|
|
2219
|
+
// To stay in line with Excel and Google Sheet behaviour,
|
|
2220
|
+
// don't perform a full refresh (and filter/sort results)
|
|
2221
|
+
// as this would make any pasted values disappear and/or suddenly change position.
|
|
2222
|
+
self.viewData[realRowIndex] = newRowData;
|
|
2223
|
+
}
|
|
2224
|
+
|
|
2225
|
+
self.selections = selections;
|
|
2226
|
+
|
|
2227
|
+
if (filledCells.length > 0 || alwaysFilling) {
|
|
2228
|
+
self.dispatchEvent('afterfill', {
|
|
2229
|
+
filledCells: filledCells,
|
|
2230
|
+
});
|
|
2231
|
+
}
|
|
2232
|
+
};
|
|
1942
2233
|
self.getNextVisibleColumnIndex = function (visibleColumnIndex) {
|
|
1943
2234
|
var x,
|
|
1944
2235
|
s = self.getVisibleSchema();
|
|
@@ -1959,6 +2250,27 @@ export default function (self) {
|
|
|
1959
2250
|
}
|
|
1960
2251
|
return -1;
|
|
1961
2252
|
};
|
|
2253
|
+
self.getSelectionIndex = function () {
|
|
2254
|
+
for (
|
|
2255
|
+
let rowIndex = 0, len = self.selections.length;
|
|
2256
|
+
rowIndex < len;
|
|
2257
|
+
rowIndex++
|
|
2258
|
+
) {
|
|
2259
|
+
const row = self.selections[rowIndex];
|
|
2260
|
+
if (row) {
|
|
2261
|
+
if (row[0] === undefined) break;
|
|
2262
|
+
|
|
2263
|
+
return {
|
|
2264
|
+
row: rowIndex,
|
|
2265
|
+
column: row[0] < 0 ? row[1] : row[0],
|
|
2266
|
+
rowLength: len - rowIndex,
|
|
2267
|
+
columnLength: row.length - (row[0] < 0 ? 1 : 0),
|
|
2268
|
+
};
|
|
2269
|
+
}
|
|
2270
|
+
}
|
|
2271
|
+
|
|
2272
|
+
return null;
|
|
2273
|
+
};
|
|
1962
2274
|
self.paste = function (event) {
|
|
1963
2275
|
if (!self.attributes.editable) {
|
|
1964
2276
|
return;
|
|
@@ -1995,28 +2307,24 @@ export default function (self) {
|
|
|
1995
2307
|
return;
|
|
1996
2308
|
}
|
|
1997
2309
|
|
|
1998
|
-
|
|
2310
|
+
const selectionIndex = self.getSelectionIndex();
|
|
2311
|
+
if (!selectionIndex) return;
|
|
1999
2312
|
|
|
2000
|
-
|
|
2001
|
-
for (
|
|
2002
|
-
let rowIndex = 0, len = self.selections.length;
|
|
2003
|
-
rowIndex < len;
|
|
2004
|
-
rowIndex++
|
|
2005
|
-
) {
|
|
2006
|
-
const row = self.selections[rowIndex];
|
|
2007
|
-
if (row) {
|
|
2008
|
-
if (row[0] === undefined) return;
|
|
2009
|
-
startCell = [rowIndex, row[0] < 0 ? row[1] : row[0]];
|
|
2010
|
-
break;
|
|
2011
|
-
}
|
|
2012
|
-
}
|
|
2313
|
+
var itemToPaste = pasteableItems[0];
|
|
2013
2314
|
|
|
2014
2315
|
// itemToPaste is cleared once accessed (getData or getAsString),
|
|
2015
2316
|
// so we need to store the type here, before reading its value:
|
|
2016
2317
|
var pasteType = itemToPaste.type;
|
|
2017
2318
|
|
|
2018
2319
|
itemToPaste.getAsString(function (pasteValue) {
|
|
2019
|
-
self.pasteData(
|
|
2320
|
+
self.pasteData(
|
|
2321
|
+
pasteValue,
|
|
2322
|
+
pasteType,
|
|
2323
|
+
selectionIndex.row,
|
|
2324
|
+
selectionIndex.column,
|
|
2325
|
+
selectionIndex.rowLength,
|
|
2326
|
+
selectionIndex.columnLength,
|
|
2327
|
+
);
|
|
2020
2328
|
|
|
2021
2329
|
self.draw();
|
|
2022
2330
|
});
|
|
@@ -2056,5 +2364,186 @@ export default function (self) {
|
|
|
2056
2364
|
|
|
2057
2365
|
event.preventDefault();
|
|
2058
2366
|
};
|
|
2367
|
+
self.selectionHandleMove = function (e) {
|
|
2368
|
+
if (!self.movingSelectionHandle) {
|
|
2369
|
+
return;
|
|
2370
|
+
}
|
|
2371
|
+
|
|
2372
|
+
const clippingRect = self.getClippingRect(e);
|
|
2373
|
+
const rowIndex = self.currentCell.rowIndex;
|
|
2374
|
+
const columnIndex = self.currentCell.columnIndex;
|
|
2375
|
+
const isInSelectionBounds =
|
|
2376
|
+
rowIndex >= -1 &&
|
|
2377
|
+
columnIndex >= -1 &&
|
|
2378
|
+
self.fillOverlay.selection.left <= columnIndex &&
|
|
2379
|
+
self.fillOverlay.selection.right >= columnIndex &&
|
|
2380
|
+
self.fillOverlay.selection.top <= rowIndex &&
|
|
2381
|
+
self.fillOverlay.selection.bottom >= rowIndex;
|
|
2382
|
+
|
|
2383
|
+
self.fillOverlay.minX = clippingRect.x;
|
|
2384
|
+
self.fillOverlay.minY = clippingRect.y;
|
|
2385
|
+
self.fillOverlay.x = Math.max(clippingRect.x, e.clientX);
|
|
2386
|
+
self.fillOverlay.y = Math.max(clippingRect.y, e.clientY);
|
|
2387
|
+
|
|
2388
|
+
// If we are in the selection bounds, allow user to change directions.
|
|
2389
|
+
if (isInSelectionBounds) {
|
|
2390
|
+
self.fillOverlay.lastInBoundsLocation = {
|
|
2391
|
+
x: e.clientX,
|
|
2392
|
+
y: e.clientY,
|
|
2393
|
+
};
|
|
2394
|
+
} else if (
|
|
2395
|
+
self.fillOverlay.lastInBoundsLocation ||
|
|
2396
|
+
!self.fillOverlay.direction
|
|
2397
|
+
) {
|
|
2398
|
+
const lastInBoundsLocation = self.fillOverlay.lastInBoundsLocation;
|
|
2399
|
+
self.fillOverlay.lastInBoundsLocation = undefined;
|
|
2400
|
+
|
|
2401
|
+
const x = lastInBoundsLocation
|
|
2402
|
+
? lastInBoundsLocation.x
|
|
2403
|
+
: self.fillOverlay.handle.x;
|
|
2404
|
+
const y = lastInBoundsLocation
|
|
2405
|
+
? lastInBoundsLocation.y
|
|
2406
|
+
: self.fillOverlay.handle.y;
|
|
2407
|
+
const dx = Math.abs(e.clientX - x);
|
|
2408
|
+
const dy = Math.abs(e.clientY - y);
|
|
2409
|
+
|
|
2410
|
+
if (dx > 5 || dy > 5) {
|
|
2411
|
+
self.fillOverlay.direction = dx > dy ? 'x' : 'y';
|
|
2412
|
+
}
|
|
2413
|
+
}
|
|
2414
|
+
|
|
2415
|
+
if (rowIndex >= 0) {
|
|
2416
|
+
self.fillOverlay.rowIndex = rowIndex;
|
|
2417
|
+
}
|
|
2418
|
+
if (columnIndex >= 0) {
|
|
2419
|
+
self.fillOverlay.columnIndex = columnIndex;
|
|
2420
|
+
if (rowIndex === -1 && self.visibleRows.length) {
|
|
2421
|
+
self.fillOverlay.rowIndex = self.visibleRows[0];
|
|
2422
|
+
}
|
|
2423
|
+
}
|
|
2424
|
+
|
|
2425
|
+
if (rowIndex >= -1 && columnIndex >= -1) {
|
|
2426
|
+
self.fillOverlay.snap = self.currentCell;
|
|
2427
|
+
} else {
|
|
2428
|
+
self.fillOverlay.snap = undefined;
|
|
2429
|
+
}
|
|
2430
|
+
};
|
|
2431
|
+
self.stopSelectionHandleMove = function (e) {
|
|
2432
|
+
if (!self.fillOverlay.handle) {
|
|
2433
|
+
return false;
|
|
2434
|
+
}
|
|
2435
|
+
|
|
2436
|
+
self.ignoreNextClick = true;
|
|
2437
|
+
|
|
2438
|
+
window.removeEventListener('mousemove', self.selectionHandleMove, false);
|
|
2439
|
+
window.removeEventListener('mouseup', self.stopSelectionHandleMove, false);
|
|
2440
|
+
|
|
2441
|
+
const overlay = self.fillOverlay;
|
|
2442
|
+
const selectionIndex = self.getSelectionIndex();
|
|
2443
|
+
const bounds = overlay.selection;
|
|
2444
|
+
if (!selectionIndex) return;
|
|
2445
|
+
|
|
2446
|
+
self.movingSelectionHandle = undefined;
|
|
2447
|
+
self.fillOverlay = {};
|
|
2448
|
+
|
|
2449
|
+
if (overlay.rowIndex >= 0 && overlay.columnIndex >= 0) {
|
|
2450
|
+
const boundsOld = { ...bounds };
|
|
2451
|
+
const isVertical = overlay.direction === 'y';
|
|
2452
|
+
const isHorizontal = overlay.direction === 'x';
|
|
2453
|
+
|
|
2454
|
+
let startRow,
|
|
2455
|
+
rowLength,
|
|
2456
|
+
startColumn,
|
|
2457
|
+
columnLength,
|
|
2458
|
+
reverseVertically = false,
|
|
2459
|
+
reverseHorizontally = false;
|
|
2460
|
+
|
|
2461
|
+
if (isVertical) {
|
|
2462
|
+
if (overlay.rowIndex < bounds.top) {
|
|
2463
|
+
bounds.top = overlay.rowIndex;
|
|
2464
|
+
reverseVertically = true;
|
|
2465
|
+
} else if (overlay.rowIndex > bounds.bottom) {
|
|
2466
|
+
bounds.bottom = overlay.rowIndex;
|
|
2467
|
+
}
|
|
2468
|
+
|
|
2469
|
+
startRow =
|
|
2470
|
+
bounds.top < boundsOld.top ? bounds.top : boundsOld.bottom + 1;
|
|
2471
|
+
rowLength =
|
|
2472
|
+
bounds.top < boundsOld.top
|
|
2473
|
+
? boundsOld.top - bounds.top
|
|
2474
|
+
: bounds.bottom - boundsOld.bottom;
|
|
2475
|
+
startColumn = selectionIndex.column;
|
|
2476
|
+
columnLength = selectionIndex.columnLength;
|
|
2477
|
+
} else if (isHorizontal) {
|
|
2478
|
+
if (overlay.columnIndex < bounds.left) {
|
|
2479
|
+
bounds.left = overlay.columnIndex;
|
|
2480
|
+
reverseHorizontally = true;
|
|
2481
|
+
} else if (overlay.columnIndex > bounds.right) {
|
|
2482
|
+
bounds.right = overlay.columnIndex;
|
|
2483
|
+
}
|
|
2484
|
+
|
|
2485
|
+
startColumn =
|
|
2486
|
+
bounds.left < boundsOld.left ? bounds.left : boundsOld.right + 1;
|
|
2487
|
+
columnLength =
|
|
2488
|
+
bounds.left < boundsOld.left
|
|
2489
|
+
? boundsOld.left - bounds.left
|
|
2490
|
+
: bounds.right - boundsOld.right;
|
|
2491
|
+
startRow = selectionIndex.row;
|
|
2492
|
+
rowLength = selectionIndex.rowLength;
|
|
2493
|
+
}
|
|
2494
|
+
|
|
2495
|
+
if (
|
|
2496
|
+
bounds.left <= bounds.right &&
|
|
2497
|
+
bounds.top <= bounds.bottom &&
|
|
2498
|
+
(bounds.left < boundsOld.left ||
|
|
2499
|
+
bounds.top < boundsOld.top ||
|
|
2500
|
+
bounds.right > boundsOld.right ||
|
|
2501
|
+
bounds.bottom > boundsOld.bottom)
|
|
2502
|
+
) {
|
|
2503
|
+
const schema = self.getSchema();
|
|
2504
|
+
const rows = [];
|
|
2505
|
+
|
|
2506
|
+
for (
|
|
2507
|
+
let rowIndex = 0;
|
|
2508
|
+
rowIndex < Math.min(rowLength, selectionIndex.rowLength);
|
|
2509
|
+
rowIndex++
|
|
2510
|
+
) {
|
|
2511
|
+
const rowData = self.viewData[selectionIndex.row + rowIndex];
|
|
2512
|
+
|
|
2513
|
+
rows[rowIndex] = [];
|
|
2514
|
+
|
|
2515
|
+
for (
|
|
2516
|
+
let columnIndex = 0;
|
|
2517
|
+
columnIndex < Math.min(columnLength, selectionIndex.columnLength);
|
|
2518
|
+
columnIndex++
|
|
2519
|
+
) {
|
|
2520
|
+
const column = schema[selectionIndex.column + columnIndex];
|
|
2521
|
+
if (!column) continue;
|
|
2522
|
+
|
|
2523
|
+
const cellData = rowData[column.name];
|
|
2524
|
+
|
|
2525
|
+
rows[rowIndex][columnIndex] = cellData;
|
|
2526
|
+
}
|
|
2527
|
+
}
|
|
2528
|
+
|
|
2529
|
+
self.insert({
|
|
2530
|
+
rows: rows,
|
|
2531
|
+
startRowIndex: startRow,
|
|
2532
|
+
startColumnIndex: startColumn,
|
|
2533
|
+
minRowsLength: rowLength,
|
|
2534
|
+
minColumnsLength: columnLength,
|
|
2535
|
+
reverseRows: reverseVertically,
|
|
2536
|
+
reverseColumns: reverseHorizontally,
|
|
2537
|
+
clearSelections: false,
|
|
2538
|
+
alwaysFilling: true,
|
|
2539
|
+
direction: isHorizontal ? 'horizontal' : 'vertical',
|
|
2540
|
+
});
|
|
2541
|
+
|
|
2542
|
+
self.draw();
|
|
2543
|
+
}
|
|
2544
|
+
}
|
|
2545
|
+
|
|
2546
|
+
return true;
|
|
2547
|
+
};
|
|
2059
2548
|
return;
|
|
2060
2549
|
}
|