canvas-datagrid 0.3.17 → 0.3.21

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/lib/draw.js CHANGED
@@ -164,6 +164,34 @@ export default function (self) {
164
164
  self.ctx.fill();
165
165
  return ml + aw + mr;
166
166
  }
167
+ function drawFilterButtonArrow(x, y) {
168
+ var mt =
169
+ ((self.style.filterButtonHeight - self.style.filterButtonArrowHeight) /
170
+ 2) *
171
+ self.scale,
172
+ ml =
173
+ ((self.style.filterButtonWidth - self.style.filterButtonArrowWidth) /
174
+ 2) *
175
+ self.scale,
176
+ aw = self.style.filterButtonArrowWidth * self.scale,
177
+ ah = self.style.filterButtonArrowHeight * self.scale;
178
+ x += self.canvasOffsetLeft;
179
+ y += self.canvasOffsetTop;
180
+ self.ctx.fillStyle = self.style.filterButtonArrowColor;
181
+ self.ctx.strokeStyle = self.style.filterButtonArrowBorderColor;
182
+ self.ctx.beginPath();
183
+ x = x + ml;
184
+ y = y + mt;
185
+
186
+ self.ctx.moveTo(x, y);
187
+ self.ctx.lineTo(x + aw, y);
188
+ self.ctx.lineTo(x + aw * 0.5, y + ah);
189
+ self.ctx.moveTo(x, y);
190
+
191
+ self.ctx.stroke();
192
+ self.ctx.fill();
193
+ return ml + aw;
194
+ }
167
195
  function radiusRect(x, y, w, h, radius) {
168
196
  x += self.canvasOffsetLeft;
169
197
  y += self.canvasOffsetTop;
@@ -601,15 +629,29 @@ export default function (self) {
601
629
  m = self.style.scrollBarBoxMargin * 2;
602
630
  self.ctx.strokeStyle = self.style.scrollBarBorderColor;
603
631
  self.ctx.lineWidth = self.style.scrollBarBorderWidth;
604
- en.horizontalBox.x =
605
- rowHeaderCellWidth +
606
- self.style.scrollBarBoxMargin +
607
- (en.horizontalBar.width - self.scrollBox.scrollBoxWidth) *
608
- (self.scrollBox.scrollLeft / self.scrollBox.scrollWidth);
632
+ if (self.frozenColumn > 0) {
633
+ en.horizontalBox.x =
634
+ rowHeaderCellWidth +
635
+ self.style.scrollBarBoxMargin +
636
+ self.scrollCache.x[self.frozenColumn - 1] +
637
+ (en.horizontalBar.width -
638
+ self.scrollCache.x[self.frozenColumn - 1] -
639
+ self.scrollBox.scrollBoxWidth) *
640
+ (self.scrollBox.scrollLeft / self.scrollBox.scrollWidth);
641
+ } else {
642
+ en.horizontalBox.x =
643
+ rowHeaderCellWidth +
644
+ self.style.scrollBarBoxMargin +
645
+ (en.horizontalBar.width - self.scrollBox.scrollBoxWidth) *
646
+ (self.scrollBox.scrollLeft / self.scrollBox.scrollWidth);
647
+ }
609
648
  en.verticalBox.y =
610
649
  columnHeaderCellHeight +
611
650
  self.style.scrollBarBoxMargin +
612
- (en.verticalBar.height - self.scrollBox.scrollBoxHeight) *
651
+ self.scrollCache.y[self.frozenRow] +
652
+ (en.verticalBar.height -
653
+ self.scrollBox.scrollBoxHeight -
654
+ self.scrollCache.y[self.frozenRow]) *
613
655
  (self.scrollBox.scrollTop / self.scrollBox.scrollHeight);
614
656
  if (self.scrollBox.horizontalBarVisible) {
615
657
  self.ctx.fillStyle = self.style.scrollBarBackgroundColor;
@@ -802,6 +844,9 @@ export default function (self) {
802
844
  isCorner = /cornerCell/.test(cellStyle),
803
845
  isRowHeader = 'rowHeaderCell' === cellStyle,
804
846
  isColumnHeader = 'columnHeaderCell' === cellStyle,
847
+ isFilterable =
848
+ self.filterable.rows.includes(rowIndex) &&
849
+ self.filterable.columns.includes(headerIndex),
805
850
  wrap = self.style.cellWhiteSpace !== 'nowrap',
806
851
  selected =
807
852
  self.selections[rowOrderIndex] &&
@@ -810,6 +855,9 @@ export default function (self) {
810
855
  self.hovers.rowIndex === rowOrderIndex &&
811
856
  (self.attributes.hoverMode === 'row' ||
812
857
  self.hovers.columnIndex === columnOrderIndex),
858
+ openedFilter =
859
+ self.selectedFilterButton.rowIndex == rowIndex &&
860
+ self.selectedFilterButton.columnIndex == headerIndex,
813
861
  active =
814
862
  self.activeCell.rowIndex === rowOrderIndex &&
815
863
  self.activeCell.columnIndex === columnOrderIndex,
@@ -901,6 +949,8 @@ export default function (self) {
901
949
  isColumnHeader: isColumnHeader,
902
950
  isColumnHeaderCellCap: isColumnHeaderCellCap,
903
951
  isRowHeader: isRowHeader,
952
+ isFilterable: isFilterable,
953
+ openedFilter: openedFilter,
904
954
  rowOpen: rowOpen,
905
955
  header: header,
906
956
 
@@ -1100,6 +1150,10 @@ export default function (self) {
1100
1150
  }
1101
1151
  self.ctx.restore();
1102
1152
 
1153
+ if (isFilterable) {
1154
+ drawFilterButton(cell);
1155
+ }
1156
+
1103
1157
  // Gaps may occur in row numbers between consecutively rendered rows
1104
1158
  // when we are filtering. We draw attention to this by drawing a thick
1105
1159
  // border overlapping the two consecutive row headers. If sorting, visible
@@ -1140,6 +1194,34 @@ export default function (self) {
1140
1194
  return cell.width;
1141
1195
  };
1142
1196
  }
1197
+ function drawFilterButton(cell, ev) {
1198
+ var posX = cell.x + cell.width - self.style.filterButtonWidth - 1;
1199
+ var posY = cell.y + cell.height - self.style.filterButtonHeight - 2;
1200
+ if (self.dispatchEvent('beforerenderfilterbutton', ev)) {
1201
+ return;
1202
+ }
1203
+ self.ctx.save();
1204
+ self.ctx.strokeStyle = self.style.filterButtonBorderColor;
1205
+ self.ctx.fillStyle = self.style.filterButtonBackgroundColor;
1206
+ if (cell.openedFilter) {
1207
+ self.ctx.fillStyle = self.style.filterButtonActiveBackgroundColor;
1208
+ } else if (cell.hovered && self.hovers.onFilterButton) {
1209
+ self.ctx.fillStyle = self.style.filterButtonHoverBackgroundColor;
1210
+ }
1211
+ radiusRect(
1212
+ posX,
1213
+ posY,
1214
+ self.style.filterButtonWidth,
1215
+ self.style.filterButtonHeight,
1216
+ self.style.filterButtonBorderRadius,
1217
+ );
1218
+ self.ctx.stroke();
1219
+ self.ctx.fill();
1220
+ drawFilterButtonArrow(posX, posY);
1221
+ self.ctx.clip();
1222
+ self.dispatchEvent('afterrenderfilterbutton', ev);
1223
+ self.ctx.restore();
1224
+ }
1143
1225
  function drawRowHeader(rowData, rowIndex, rowOrderIndex) {
1144
1226
  if (self.attributes.showRowHeaders) {
1145
1227
  x = 0;
@@ -1520,6 +1602,10 @@ export default function (self) {
1520
1602
  self.ctx.lineWidth = self.style.reorderMarkerBorderWidth;
1521
1603
  self.ctx.strokeStyle = self.style.reorderMarkerBorderColor;
1522
1604
  if (self.dragMode === 'row-reorder') {
1605
+ for (var k = 0; k < self.selections.length; k++) {
1606
+ if (!self.selections[k] || k == self.reorderObject.rowIndex) continue;
1607
+ b.height += self.getRowHeight(k);
1608
+ }
1523
1609
  b.width = w;
1524
1610
  b.x = 0;
1525
1611
  m.width = w;
@@ -1542,6 +1628,12 @@ export default function (self) {
1542
1628
  );
1543
1629
  }
1544
1630
  } else if (self.dragMode === 'column-reorder' && self.reorderObject) {
1631
+ var selectedColumns = self.selections[0];
1632
+ for (var k = 1; k < selectedColumns.length; k++) {
1633
+ b.width += self.getColumnWidth(
1634
+ self.orders.columns[selectedColumns[k]],
1635
+ );
1636
+ }
1545
1637
  b.height = h;
1546
1638
  b.y = 0;
1547
1639
  m.height = h;
@@ -254,7 +254,13 @@ export default function (self) {
254
254
  setScrollBoxSize();
255
255
  self.scrollBox.scrollWidth = dataWidth - self.scrollBox.width;
256
256
  self.scrollBox.scrollHeight = dataHeight - self.scrollBox.height;
257
- self.scrollBox.widthBoxRatio = self.scrollBox.width / dataWidth;
257
+ if (self.frozenColumn > 0) {
258
+ self.scrollBox.widthBoxRatio =
259
+ (self.scrollBox.width - self.scrollCache.x[self.frozenColumn - 1]) /
260
+ dataWidth;
261
+ } else {
262
+ self.scrollBox.widthBoxRatio = self.scrollBox.width / dataWidth;
263
+ }
258
264
  self.scrollBox.scrollBoxWidth =
259
265
  self.scrollBox.width * self.scrollBox.widthBoxRatio -
260
266
  self.style.scrollBarWidth -
@@ -266,7 +272,10 @@ export default function (self) {
266
272
  // the dragged mouse.
267
273
  // https://github.com/TonyGermaneri/canvas-datagrid/issues/97
268
274
  self.scrollBox.heightBoxRatio =
269
- (self.scrollBox.height - columnHeaderCellHeight) / dataHeight;
275
+ (self.scrollBox.height -
276
+ columnHeaderCellHeight -
277
+ self.scrollCache.y[self.frozenRow]) /
278
+ dataHeight;
270
279
  self.scrollBox.scrollBoxHeight =
271
280
  self.scrollBox.height * self.scrollBox.heightBoxRatio -
272
281
  self.style.scrollBarWidth -
@@ -296,12 +305,13 @@ export default function (self) {
296
305
  self.style.scrollBarWidth -
297
306
  self.style.scrollBarBorderWidth -
298
307
  d;
299
- v.y += columnHeaderCellHeight;
308
+ v.y += columnHeaderCellHeight + self.scrollCache.y[self.frozenRow];
300
309
  v.width = self.style.scrollBarWidth + self.style.scrollBarBorderWidth + d;
301
310
  v.height =
302
311
  self.height - columnHeaderCellHeight - self.style.scrollBarWidth - d - m;
303
312
  // vertical box
304
313
  vb.x = v.x + self.style.scrollBarBoxMargin;
314
+ vb.y += self.scrollCache.y[self.frozenRow];
305
315
  vb.width = self.style.scrollBarBoxWidth;
306
316
  vb.height = self.scrollBox.scrollBoxHeight;
307
317
  // corner
@@ -458,7 +468,26 @@ export default function (self) {
458
468
  self.hovers = {
459
469
  rowIndex: cell.rowIndex,
460
470
  columnIndex: cell.columnIndex,
471
+ onFilterButton: false,
461
472
  };
473
+ if (
474
+ cell.isFilterable &&
475
+ x >
476
+ cell.x +
477
+ cell.width +
478
+ self.canvasOffsetLeft -
479
+ self.style.filterButtonWidth &&
480
+ x < cell.x + cell.width + self.canvasOffsetLeft &&
481
+ y >
482
+ cell.y +
483
+ cell.height +
484
+ self.canvasOffsetTop -
485
+ self.style.filterButtonHeight &&
486
+ y < cell.y + cell.height + self.canvasOffsetTop
487
+ ) {
488
+ self.hovers.onFilterButton = true;
489
+ self.draw();
490
+ }
462
491
  }
463
492
  if (self.selecting || self.reorderObject) {
464
493
  delta = {
@@ -502,30 +531,57 @@ export default function (self) {
502
531
  ) {
503
532
  self.selectRow(cell.rowIndex, ctrl, null, true);
504
533
  } else if (self.attributes.selectionMode !== 'row') {
505
- if (!self.dragAddToSelection && cell.rowIndex !== undefined) {
506
- if (
507
- self.selections[cell.rowIndex] &&
508
- self.selections[cell.rowIndex].indexOf(cell.columnIndex) !== -1
509
- ) {
510
- self.selections[cell.rowIndex].splice(
511
- self.selections[cell.rowIndex].indexOf(cell.columnIndex),
512
- 1,
513
- );
534
+ if (cell.hovered && self.hovers.onFilterButton) {
535
+ if (cell.openedFilter) {
536
+ cell.openedFilter = false;
537
+ self.selectedFilterButton = {
538
+ columnIndex: -1,
539
+ rowIndex: -1,
540
+ };
541
+ } else {
542
+ self.selectedFilterButton.rowIndex = cell.rowIndex;
543
+ self.selectedFilterButton.columnIndex = cell.columnIndex;
544
+ self.contextmenuEvent(e, {
545
+ x: cell.x + cell.width - self.style.filterButtonWidth,
546
+ y: cell.y + cell.height,
547
+ rect: { left: 0, top: 0 },
548
+ });
514
549
  }
550
+ self.draw();
551
+ return;
515
552
  } else {
516
- self.selections[cell.rowIndex] =
517
- self.selections[cell.rowIndex] || [];
518
- if (
519
- self.selections[cell.rowIndex].indexOf(cell.columnIndex) === -1
520
- ) {
521
- self.selections[cell.rowIndex].push(cell.columnIndex);
522
- const event = {
523
- selections: self.selections,
524
- selectedData: self.getSelectedData(),
525
- selectedCells: self.getSelectedCells(),
526
- selectionBounds: self.getSelectionBounds(),
527
- };
528
- self.dispatchEvent('selectionchanged', event);
553
+ self.selectedFilterButton = {
554
+ columnIndex: -1,
555
+ rowIndex: -1,
556
+ };
557
+ if (self.hovers.onFilterButton) return;
558
+ if (!self.dragAddToSelection && cell.rowIndex !== undefined) {
559
+ if (
560
+ self.selections[cell.rowIndex] &&
561
+ self.selections[cell.rowIndex].indexOf(cell.columnIndex) !==
562
+ -1
563
+ ) {
564
+ self.selections[cell.rowIndex].splice(
565
+ self.selections[cell.rowIndex].indexOf(cell.columnIndex),
566
+ 1,
567
+ );
568
+ }
569
+ } else {
570
+ self.selections[cell.rowIndex] =
571
+ self.selections[cell.rowIndex] || [];
572
+ if (
573
+ self.selections[cell.rowIndex].indexOf(cell.columnIndex) ===
574
+ -1
575
+ ) {
576
+ self.selections[cell.rowIndex].push(cell.columnIndex);
577
+ var event = {
578
+ selections: self.selections,
579
+ selectedData: self.getSelectedData(),
580
+ selectedCells: self.getSelectedCells(),
581
+ selectionBounds: self.getSelectionBounds(),
582
+ };
583
+ self.dispatchEvent('selectionchanged', event);
584
+ }
529
585
  }
530
586
  }
531
587
  }
@@ -538,14 +594,21 @@ export default function (self) {
538
594
  dragBounds.right !== self.selectionBounds.right) &&
539
595
  !ctrl
540
596
  ) {
541
- self.selections = [];
597
+ if (!(cell.hovered && self.hovers.onFilterButton)) {
598
+ self.selections = [];
599
+ }
600
+ if (dragBounds.top === -1) {
601
+ dragBounds.top = 0;
602
+ }
542
603
  sBounds = dragBounds;
543
604
  if (self.attributes.selectionMode === 'row') {
544
605
  for (i = sBounds.top; i <= sBounds.bottom; i += 1) {
545
606
  self.selectRow(i, true, null, true);
546
607
  }
547
- } else if (dragBounds.top !== -1) {
608
+ } else {
548
609
  self.selectArea(sBounds, true);
610
+ if (sBounds.left == -1 && sBounds.top !== sBounds.bottom)
611
+ self.isMultiRowsSelected = true;
549
612
  }
550
613
  }
551
614
 
@@ -620,7 +683,9 @@ export default function (self) {
620
683
  -1 &&
621
684
  !ctrl
622
685
  ) {
623
- self.setActiveCell(i.columnIndex, i.rowIndex);
686
+ if (!self.hovers.onFilterButton) {
687
+ self.setActiveCell(i.columnIndex, i.rowIndex);
688
+ }
624
689
  }
625
690
  if (self.currentCell.context === 'cell') {
626
691
  if (self.currentCell.style === 'cornerCell') {
@@ -641,11 +706,6 @@ export default function (self) {
641
706
  checkSelectionChange();
642
707
  return;
643
708
  }
644
- if (self.attributes.columnHeaderClickBehavior === 'select') {
645
- self.selectColumn(i.header.index, ctrl, e.shiftKey);
646
- self.draw();
647
- return;
648
- }
649
709
  }
650
710
  self.selections[i.rowIndex] = self.selections[i.rowIndex] || [];
651
711
  if (
@@ -868,6 +928,14 @@ export default function (self) {
868
928
  if (!self.attributes.allowRowReordering && rowReorder) {
869
929
  return;
870
930
  }
931
+ if ((e.ctrlKey || e.metaKey || e.shiftKey) && self.reorderObject) {
932
+ if (
933
+ self.dragMode === 'column-reorder' &&
934
+ !self.isMultiColumnsSelected(self.draggingItem.header.index)
935
+ ) {
936
+ self.selectColumn(self.draggingItem.header.index, false, false);
937
+ }
938
+ }
871
939
  if (
872
940
  self.dispatchEvent('reordering', {
873
941
  NativeEvent: e,
@@ -883,6 +951,11 @@ export default function (self) {
883
951
  Math.abs(y) > self.attributes.reorderDeadZone
884
952
  ) {
885
953
  self.reorderObject = self.draggingItem;
954
+ if (self.isMultiRowsSelected)
955
+ self.reorderObject = self.getVisibleCellByIndex(
956
+ -1,
957
+ self.activeCell.rowIndex,
958
+ );
886
959
  self.reorderTarget = self.currentCell;
887
960
  self.reorderObject.dragOffset = {
888
961
  x: x,
@@ -899,7 +972,7 @@ export default function (self) {
899
972
  self.stopDragReorder = function (e) {
900
973
  var oIndex,
901
974
  tIndex,
902
- odata,
975
+ odata = [],
903
976
  cr = {
904
977
  'row-reorder': self.orders.rows,
905
978
  'column-reorder': self.orders.columns,
@@ -931,14 +1004,40 @@ export default function (self) {
931
1004
  oIndex = cr[self.dragMode].indexOf(self.reorderObject[i]);
932
1005
  tIndex = cr[self.dragMode].indexOf(self.reorderTarget[i]);
933
1006
  if (self.dragMode === 'column-reorder') {
934
- cr[self.dragMode].splice(oIndex, 1);
935
- cr[self.dragMode].splice(tIndex, 0, self.reorderObject[i]);
1007
+ var sortColumnIndices = [];
1008
+ var seletedColumnIndices = [];
1009
+ if (self.selections[0]) {
1010
+ self.selections[0].forEach(function (value) {
1011
+ sortColumnIndices.push(self.orders.columns[value]);
1012
+ });
1013
+ }
1014
+ var deleteCount = sortColumnIndices.length;
1015
+ cr[self.dragMode].splice(oIndex, deleteCount);
1016
+ if (tIndex > oIndex) tIndex = tIndex - (deleteCount - 1);
1017
+ for (var i = 0; i < sortColumnIndices.length; i++) {
1018
+ seletedColumnIndices.push(tIndex + i);
1019
+ cr[self.dragMode].splice(tIndex + i, 0, sortColumnIndices[i]);
1020
+ }
936
1021
  self.orders.columns = cr[self.dragMode];
1022
+ self.viewData.forEach(function (row, rowIndex) {
1023
+ self.selections[rowIndex] = seletedColumnIndices;
1024
+ });
937
1025
  } else {
938
- // self.orders.rows = cr[self.dragMode];
939
- odata = self.viewData[oIndex];
940
- self.viewData[oIndex] = self.viewData[tIndex];
941
- self.viewData[tIndex] = odata;
1026
+ var selectedRows = [];
1027
+ self.selections.forEach(function (row, rowIndex) {
1028
+ if (row) {
1029
+ selectedRows.push(row);
1030
+ odata.push(self.viewData[rowIndex]);
1031
+ }
1032
+ });
1033
+ self.viewData.splice(oIndex, odata.length);
1034
+ self.selections = [];
1035
+ if (tIndex > oIndex) tIndex = tIndex - (odata.length - 1);
1036
+ self.activeCell.rowIndex = tIndex;
1037
+ for (var i = 0; i < odata.length; i++) {
1038
+ self.viewData.splice(tIndex + i, 0, odata[i]);
1039
+ self.selections[tIndex + i] = selectedRows[i];
1040
+ }
942
1041
  }
943
1042
  self.resize();
944
1043
  self.setStorageData();
@@ -1000,7 +1099,12 @@ export default function (self) {
1000
1099
  ) {
1001
1100
  return;
1002
1101
  }
1003
- var pos = self.getLayerPos(e);
1102
+ var pos = self.getLayerPos(e),
1103
+ bm = self.style.gridBorderCollapse === 'collapse' ? 1 : 2,
1104
+ columnHeaderCellBorder = self.style.columnHeaderCellBorderWidth * bm,
1105
+ columnHeaderCellHeight = self.getColumnHeaderCellHeight(),
1106
+ rowHeaderCellWidth = self.getRowHeaderCellWidth();
1107
+
1004
1108
  self.ignoreNextClick = true;
1005
1109
  self.freezeMarkerPosition = pos;
1006
1110
  if (
@@ -1010,6 +1114,28 @@ export default function (self) {
1010
1114
  ) {
1011
1115
  self.scrollBox.scrollTop = 0;
1012
1116
  self.frozenRow = self.currentCell.rowIndex + 1;
1117
+ self.scrollBox.bar.v.y =
1118
+ columnHeaderCellHeight +
1119
+ columnHeaderCellBorder +
1120
+ self.scrollCache.y[self.frozenRow];
1121
+ self.scrollBox.box.v.y =
1122
+ columnHeaderCellHeight +
1123
+ columnHeaderCellBorder +
1124
+ self.scrollCache.y[self.frozenRow];
1125
+ var dataHeight = self.scrollCache.y[self.scrollCache.y.length - 1];
1126
+ self.scrollBox.heightBoxRatio =
1127
+ (self.scrollBox.height -
1128
+ columnHeaderCellHeight -
1129
+ self.scrollCache.y[self.frozenRow]) /
1130
+ dataHeight;
1131
+ self.scrollBox.scrollBoxHeight =
1132
+ self.scrollBox.height * self.scrollBox.heightBoxRatio -
1133
+ self.style.scrollBarWidth;
1134
+ self.scrollBox.scrollBoxHeight = Math.max(
1135
+ self.scrollBox.scrollBoxHeight,
1136
+ self.style.scrollBarBoxMinSize,
1137
+ );
1138
+ self.scrollBox.box.v.height = self.scrollBox.scrollBoxHeight;
1013
1139
  }
1014
1140
  if (
1015
1141
  self.currentCell &&
@@ -1018,6 +1144,22 @@ export default function (self) {
1018
1144
  ) {
1019
1145
  self.scrollBox.scrollLeft = 0;
1020
1146
  self.frozenColumn = self.currentCell.columnIndex + 1;
1147
+ self.scrollBox.bar.h.x =
1148
+ rowHeaderCellWidth + self.scrollCache.x[self.frozenColumn - 1];
1149
+ self.scrollBox.box.h.x =
1150
+ rowHeaderCellWidth + self.scrollCache.x[self.frozenColumn - 1];
1151
+ var dataWidth = self.scrollCache.x[self.scrollCache.x.length - 1];
1152
+ self.scrollBox.widthBoxRatio =
1153
+ (self.scrollBox.width - self.scrollCache.x[self.frozenColumn - 1]) /
1154
+ dataWidth;
1155
+ self.scrollBox.scrollBoxWidth =
1156
+ self.scrollBox.width * self.scrollBox.widthBoxRatio -
1157
+ self.style.scrollBarWidth;
1158
+ self.scrollBox.scrollBoxWidth = Math.max(
1159
+ self.scrollBox.scrollBoxWidth,
1160
+ self.style.scrollBarBoxMinSize,
1161
+ );
1162
+ self.scrollBox.box.h.width = self.scrollBox.scrollBoxWidth;
1021
1163
  }
1022
1164
  if (
1023
1165
  Math.abs(pos.x) > self.attributes.reorderDeadZone ||
@@ -1084,7 +1226,12 @@ export default function (self) {
1084
1226
  !freeze &&
1085
1227
  !resize
1086
1228
  ) {
1087
- self.selections = [];
1229
+ if (
1230
+ !(self.dragMode == 'row-reorder' && self.isMultiRowsSelected) &&
1231
+ !(self.currentCell.hovered && self.hovers.onFilterButton)
1232
+ ) {
1233
+ self.selections = [];
1234
+ }
1088
1235
  }
1089
1236
  if (self.dragStartObject.isGrid) {
1090
1237
  return;
@@ -1175,10 +1322,11 @@ export default function (self) {
1175
1322
  self.draggingItem = self.dragStartObject;
1176
1323
  if (
1177
1324
  self.dragMode === 'column-reorder' &&
1178
- self.attributes.columnHeaderClickBehavior === 'select'
1325
+ !self.isMultiColumnsSelected(self.currentCell.header.index)
1179
1326
  ) {
1180
1327
  self.selectColumn(self.currentCell.header.index, ctrl, e.shiftKey);
1181
- self.draw();
1328
+ } else if (self.dragMode === 'row-reorder' && !self.isMultiRowsSelected) {
1329
+ self.selectRow(self.dragStartObject.rowIndex, ctrl, null);
1182
1330
  }
1183
1331
  document.body.addEventListener('mousemove', self.dragReorder, false);
1184
1332
  document.body.addEventListener('mouseup', self.stopDragReorder, false);
@@ -1187,14 +1335,9 @@ export default function (self) {
1187
1335
  };
1188
1336
  self.mouseup = function (e) {
1189
1337
  clearTimeout(self.scrollTimer);
1190
- var ctrl = e.ctrlKey || e.metaKey;
1191
1338
  self.cellBoundaryCrossed = true;
1192
1339
  self.rowBoundaryCrossed = true;
1193
1340
  self.columnBoundaryCrossed = true;
1194
- if (self.draggingItem) {
1195
- self.selectColumn(self.currentCell.header.index, ctrl, e.shiftKey);
1196
- self.draw();
1197
- }
1198
1341
  self.selecting = undefined;
1199
1342
  self.draggingItem = undefined;
1200
1343
  self.dragStartObject = undefined;
@@ -1285,6 +1428,8 @@ export default function (self) {
1285
1428
  self.selectNone();
1286
1429
  } else if (ctrl && e.key === 'a') {
1287
1430
  self.selectAll();
1431
+ } else if (['Backspace', 'Delete'].includes(e.key)) {
1432
+ self.deleteSelectedData();
1288
1433
  } else if (e.key === 'ArrowDown') {
1289
1434
  y += 1;
1290
1435
  } else if (e.key === 'ArrowUp') {
@@ -1470,7 +1615,10 @@ export default function (self) {
1470
1615
  self.currentCell.style === 'cornerCell'
1471
1616
  ) {
1472
1617
  self.autosize();
1473
- } else if (['cell', 'activeCell'].indexOf(self.currentCell.style) !== -1) {
1618
+ } else if (
1619
+ ['cell', 'activeCell'].includes(self.currentCell.style) &&
1620
+ !self.hovers.onFilterButton
1621
+ ) {
1474
1622
  self.beginEditAt(self.currentCell.columnIndex, self.currentCell.rowIndex);
1475
1623
  }
1476
1624
  };
@@ -1723,6 +1871,8 @@ export default function (self) {
1723
1871
  if (self.dispatchEvent('cut', { NativeEvent: e, cells: affectedCells })) {
1724
1872
  return;
1725
1873
  }
1874
+
1875
+ requestAnimationFrame(() => self.draw());
1726
1876
  };
1727
1877
  self.copy = function (e) {
1728
1878
  if (self.dispatchEvent('copy', { NativeEvent: e })) {
@@ -1740,6 +1890,7 @@ export default function (self) {
1740
1890
  firstRowKeys,
1741
1891
  isNeat = true; // Selected like [[0, 1], [0, 1]] of [[0, 3]] is neat; Selected like [[0, 1], [1, 2]] is untidy
1742
1892
  function htmlSafe(v) {
1893
+ if (typeof v === 'number') return v;
1743
1894
  return v.replace(/</g, '&lt;').replace(/>/g, '&gt;');
1744
1895
  }
1745
1896
  s.forEach(function (column, columnIndex) {
@@ -1753,8 +1904,8 @@ export default function (self) {
1753
1904
  if (!firstRowKeys) firstRowKeys = Object.keys(row);
1754
1905
  if (isNeat && rowKeys.length !== firstRowKeys.length) isNeat = false;
1755
1906
  sSorted.forEach(function (column, columnIndex) {
1756
- if (rowKeys.indexOf(column.name) < 0) {
1757
- if (firstRowKeys.indexOf(column.name) < 0) {
1907
+ if (rowKeys.indexOf(String(column.name)) < 0) {
1908
+ if (firstRowKeys.indexOf(String(column.name)) < 0) {
1758
1909
  return;
1759
1910
  } else if (isNeat) {
1760
1911
  isNeat = false;