canvas-datagrid 0.3.16 → 0.3.20
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 +798 -68
- 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 +14 -0
- package/lib/button.js +325 -0
- package/lib/contextMenu.js +47 -8
- package/lib/defaults.js +27 -0
- package/lib/dom.js +90 -0
- package/lib/draw.js +106 -8
- package/lib/events/index.js +191 -52
- package/lib/intf.js +17 -0
- package/lib/main.js +2 -0
- package/lib/publicMethods.js +70 -2
- package/package.json +1 -1
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
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
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
|
-
|
|
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,13 +1150,23 @@ 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
|
-
// border overlapping the two consecutive row headers.
|
|
1159
|
+
// border overlapping the two consecutive row headers. If sorting, visible
|
|
1160
|
+
// row numbers stay the same (i.e. they don't correspond to the underlying
|
|
1161
|
+
// data's row number), so we do not show row gaps in that case.
|
|
1162
|
+
const isSorting =
|
|
1163
|
+
self.orderings.columns && self.orderings.columns.length > 0;
|
|
1164
|
+
|
|
1106
1165
|
if (
|
|
1107
1166
|
isRowHeader &&
|
|
1108
1167
|
self.attributes.showRowNumbers &&
|
|
1109
|
-
self.attributes.showRowNumberGaps
|
|
1168
|
+
self.attributes.showRowNumberGaps &&
|
|
1169
|
+
isSorting === false
|
|
1110
1170
|
) {
|
|
1111
1171
|
const previousRowNumber = self.getBoundRowIndexFromViewRowIndex(
|
|
1112
1172
|
rowOrderIndex - 1,
|
|
@@ -1134,6 +1194,34 @@ export default function (self) {
|
|
|
1134
1194
|
return cell.width;
|
|
1135
1195
|
};
|
|
1136
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
|
+
}
|
|
1137
1225
|
function drawRowHeader(rowData, rowIndex, rowOrderIndex) {
|
|
1138
1226
|
if (self.attributes.showRowHeaders) {
|
|
1139
1227
|
x = 0;
|
|
@@ -1514,6 +1602,10 @@ export default function (self) {
|
|
|
1514
1602
|
self.ctx.lineWidth = self.style.reorderMarkerBorderWidth;
|
|
1515
1603
|
self.ctx.strokeStyle = self.style.reorderMarkerBorderColor;
|
|
1516
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
|
+
}
|
|
1517
1609
|
b.width = w;
|
|
1518
1610
|
b.x = 0;
|
|
1519
1611
|
m.width = w;
|
|
@@ -1536,6 +1628,12 @@ export default function (self) {
|
|
|
1536
1628
|
);
|
|
1537
1629
|
}
|
|
1538
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
|
+
}
|
|
1539
1637
|
b.height = h;
|
|
1540
1638
|
b.y = 0;
|
|
1541
1639
|
m.height = h;
|
package/lib/events/index.js
CHANGED
|
@@ -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.
|
|
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 -
|
|
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,18 @@ 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 > cell.x + cell.width - self.style.filterButtonWidth &&
|
|
476
|
+
x < cell.x + cell.width &&
|
|
477
|
+
y > cell.y + cell.height - self.style.filterButtonHeight &&
|
|
478
|
+
y < cell.y + cell.height
|
|
479
|
+
) {
|
|
480
|
+
self.hovers.onFilterButton = true;
|
|
481
|
+
self.draw();
|
|
482
|
+
}
|
|
462
483
|
}
|
|
463
484
|
if (self.selecting || self.reorderObject) {
|
|
464
485
|
delta = {
|
|
@@ -502,30 +523,57 @@ export default function (self) {
|
|
|
502
523
|
) {
|
|
503
524
|
self.selectRow(cell.rowIndex, ctrl, null, true);
|
|
504
525
|
} else if (self.attributes.selectionMode !== 'row') {
|
|
505
|
-
if (
|
|
506
|
-
if (
|
|
507
|
-
|
|
508
|
-
self.
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
526
|
+
if (cell.hovered && self.hovers.onFilterButton) {
|
|
527
|
+
if (cell.openedFilter) {
|
|
528
|
+
cell.openedFilter = false;
|
|
529
|
+
self.selectedFilterButton = {
|
|
530
|
+
columnIndex: -1,
|
|
531
|
+
rowIndex: -1,
|
|
532
|
+
};
|
|
533
|
+
} else {
|
|
534
|
+
self.selectedFilterButton.rowIndex = cell.rowIndex;
|
|
535
|
+
self.selectedFilterButton.columnIndex = cell.columnIndex;
|
|
536
|
+
self.contextmenuEvent(e, {
|
|
537
|
+
x: cell.x + cell.width - self.style.filterButtonWidth,
|
|
538
|
+
y: cell.y + cell.height,
|
|
539
|
+
rect: { left: 0, top: 0 },
|
|
540
|
+
});
|
|
514
541
|
}
|
|
542
|
+
self.draw();
|
|
543
|
+
return;
|
|
515
544
|
} else {
|
|
516
|
-
self.
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
)
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
545
|
+
self.selectedFilterButton = {
|
|
546
|
+
columnIndex: -1,
|
|
547
|
+
rowIndex: -1,
|
|
548
|
+
};
|
|
549
|
+
if (self.hovers.onFilterButton) return;
|
|
550
|
+
if (!self.dragAddToSelection && cell.rowIndex !== undefined) {
|
|
551
|
+
if (
|
|
552
|
+
self.selections[cell.rowIndex] &&
|
|
553
|
+
self.selections[cell.rowIndex].indexOf(cell.columnIndex) !==
|
|
554
|
+
-1
|
|
555
|
+
) {
|
|
556
|
+
self.selections[cell.rowIndex].splice(
|
|
557
|
+
self.selections[cell.rowIndex].indexOf(cell.columnIndex),
|
|
558
|
+
1,
|
|
559
|
+
);
|
|
560
|
+
}
|
|
561
|
+
} else {
|
|
562
|
+
self.selections[cell.rowIndex] =
|
|
563
|
+
self.selections[cell.rowIndex] || [];
|
|
564
|
+
if (
|
|
565
|
+
self.selections[cell.rowIndex].indexOf(cell.columnIndex) ===
|
|
566
|
+
-1
|
|
567
|
+
) {
|
|
568
|
+
self.selections[cell.rowIndex].push(cell.columnIndex);
|
|
569
|
+
var event = {
|
|
570
|
+
selections: self.selections,
|
|
571
|
+
selectedData: self.getSelectedData(),
|
|
572
|
+
selectedCells: self.getSelectedCells(),
|
|
573
|
+
selectionBounds: self.getSelectionBounds(),
|
|
574
|
+
};
|
|
575
|
+
self.dispatchEvent('selectionchanged', event);
|
|
576
|
+
}
|
|
529
577
|
}
|
|
530
578
|
}
|
|
531
579
|
}
|
|
@@ -538,14 +586,21 @@ export default function (self) {
|
|
|
538
586
|
dragBounds.right !== self.selectionBounds.right) &&
|
|
539
587
|
!ctrl
|
|
540
588
|
) {
|
|
541
|
-
self.
|
|
589
|
+
if (!(cell.hovered && self.hovers.onFilterButton)) {
|
|
590
|
+
self.selections = [];
|
|
591
|
+
}
|
|
592
|
+
if (dragBounds.top === -1) {
|
|
593
|
+
dragBounds.top = 0;
|
|
594
|
+
}
|
|
542
595
|
sBounds = dragBounds;
|
|
543
596
|
if (self.attributes.selectionMode === 'row') {
|
|
544
597
|
for (i = sBounds.top; i <= sBounds.bottom; i += 1) {
|
|
545
598
|
self.selectRow(i, true, null, true);
|
|
546
599
|
}
|
|
547
|
-
} else
|
|
600
|
+
} else {
|
|
548
601
|
self.selectArea(sBounds, true);
|
|
602
|
+
if (sBounds.left == -1 && sBounds.top !== sBounds.bottom)
|
|
603
|
+
self.isMultiRowsSelected = true;
|
|
549
604
|
}
|
|
550
605
|
}
|
|
551
606
|
|
|
@@ -620,7 +675,9 @@ export default function (self) {
|
|
|
620
675
|
-1 &&
|
|
621
676
|
!ctrl
|
|
622
677
|
) {
|
|
623
|
-
self.
|
|
678
|
+
if (!self.hovers.onFilterButton) {
|
|
679
|
+
self.setActiveCell(i.columnIndex, i.rowIndex);
|
|
680
|
+
}
|
|
624
681
|
}
|
|
625
682
|
if (self.currentCell.context === 'cell') {
|
|
626
683
|
if (self.currentCell.style === 'cornerCell') {
|
|
@@ -641,11 +698,6 @@ export default function (self) {
|
|
|
641
698
|
checkSelectionChange();
|
|
642
699
|
return;
|
|
643
700
|
}
|
|
644
|
-
if (self.attributes.columnHeaderClickBehavior === 'select') {
|
|
645
|
-
self.selectColumn(i.header.index, ctrl, e.shiftKey);
|
|
646
|
-
self.draw();
|
|
647
|
-
return;
|
|
648
|
-
}
|
|
649
701
|
}
|
|
650
702
|
self.selections[i.rowIndex] = self.selections[i.rowIndex] || [];
|
|
651
703
|
if (
|
|
@@ -868,6 +920,14 @@ export default function (self) {
|
|
|
868
920
|
if (!self.attributes.allowRowReordering && rowReorder) {
|
|
869
921
|
return;
|
|
870
922
|
}
|
|
923
|
+
if ((e.ctrlKey || e.metaKey || e.shiftKey) && self.reorderObject) {
|
|
924
|
+
if (
|
|
925
|
+
self.dragMode === 'column-reorder' &&
|
|
926
|
+
!self.isMultiColumnsSelected(self.draggingItem.header.index)
|
|
927
|
+
) {
|
|
928
|
+
self.selectColumn(self.draggingItem.header.index, false, false);
|
|
929
|
+
}
|
|
930
|
+
}
|
|
871
931
|
if (
|
|
872
932
|
self.dispatchEvent('reordering', {
|
|
873
933
|
NativeEvent: e,
|
|
@@ -883,6 +943,11 @@ export default function (self) {
|
|
|
883
943
|
Math.abs(y) > self.attributes.reorderDeadZone
|
|
884
944
|
) {
|
|
885
945
|
self.reorderObject = self.draggingItem;
|
|
946
|
+
if (self.isMultiRowsSelected)
|
|
947
|
+
self.reorderObject = self.getVisibleCellByIndex(
|
|
948
|
+
-1,
|
|
949
|
+
self.activeCell.rowIndex,
|
|
950
|
+
);
|
|
886
951
|
self.reorderTarget = self.currentCell;
|
|
887
952
|
self.reorderObject.dragOffset = {
|
|
888
953
|
x: x,
|
|
@@ -899,7 +964,7 @@ export default function (self) {
|
|
|
899
964
|
self.stopDragReorder = function (e) {
|
|
900
965
|
var oIndex,
|
|
901
966
|
tIndex,
|
|
902
|
-
odata,
|
|
967
|
+
odata = [],
|
|
903
968
|
cr = {
|
|
904
969
|
'row-reorder': self.orders.rows,
|
|
905
970
|
'column-reorder': self.orders.columns,
|
|
@@ -931,14 +996,40 @@ export default function (self) {
|
|
|
931
996
|
oIndex = cr[self.dragMode].indexOf(self.reorderObject[i]);
|
|
932
997
|
tIndex = cr[self.dragMode].indexOf(self.reorderTarget[i]);
|
|
933
998
|
if (self.dragMode === 'column-reorder') {
|
|
934
|
-
|
|
935
|
-
|
|
999
|
+
var sortColumnIndices = [];
|
|
1000
|
+
var seletedColumnIndices = [];
|
|
1001
|
+
if (self.selections[0]) {
|
|
1002
|
+
self.selections[0].forEach(function (value) {
|
|
1003
|
+
sortColumnIndices.push(self.orders.columns[value]);
|
|
1004
|
+
});
|
|
1005
|
+
}
|
|
1006
|
+
var deleteCount = sortColumnIndices.length;
|
|
1007
|
+
cr[self.dragMode].splice(oIndex, deleteCount);
|
|
1008
|
+
if (tIndex > oIndex) tIndex = tIndex - (deleteCount - 1);
|
|
1009
|
+
for (var i = 0; i < sortColumnIndices.length; i++) {
|
|
1010
|
+
seletedColumnIndices.push(tIndex + i);
|
|
1011
|
+
cr[self.dragMode].splice(tIndex + i, 0, sortColumnIndices[i]);
|
|
1012
|
+
}
|
|
936
1013
|
self.orders.columns = cr[self.dragMode];
|
|
1014
|
+
self.viewData.forEach(function (row, rowIndex) {
|
|
1015
|
+
self.selections[rowIndex] = seletedColumnIndices;
|
|
1016
|
+
});
|
|
937
1017
|
} else {
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
1018
|
+
var selectedRows = [];
|
|
1019
|
+
self.selections.forEach(function (row, rowIndex) {
|
|
1020
|
+
if (row) {
|
|
1021
|
+
selectedRows.push(row);
|
|
1022
|
+
odata.push(self.viewData[rowIndex]);
|
|
1023
|
+
}
|
|
1024
|
+
});
|
|
1025
|
+
self.viewData.splice(oIndex, odata.length);
|
|
1026
|
+
self.selections = [];
|
|
1027
|
+
if (tIndex > oIndex) tIndex = tIndex - (odata.length - 1);
|
|
1028
|
+
self.activeCell.rowIndex = tIndex;
|
|
1029
|
+
for (var i = 0; i < odata.length; i++) {
|
|
1030
|
+
self.viewData.splice(tIndex + i, 0, odata[i]);
|
|
1031
|
+
self.selections[tIndex + i] = selectedRows[i];
|
|
1032
|
+
}
|
|
942
1033
|
}
|
|
943
1034
|
self.resize();
|
|
944
1035
|
self.setStorageData();
|
|
@@ -1000,7 +1091,12 @@ export default function (self) {
|
|
|
1000
1091
|
) {
|
|
1001
1092
|
return;
|
|
1002
1093
|
}
|
|
1003
|
-
var pos = self.getLayerPos(e)
|
|
1094
|
+
var pos = self.getLayerPos(e),
|
|
1095
|
+
bm = self.style.gridBorderCollapse === 'collapse' ? 1 : 2,
|
|
1096
|
+
columnHeaderCellBorder = self.style.columnHeaderCellBorderWidth * bm,
|
|
1097
|
+
columnHeaderCellHeight = self.getColumnHeaderCellHeight(),
|
|
1098
|
+
rowHeaderCellWidth = self.getRowHeaderCellWidth();
|
|
1099
|
+
|
|
1004
1100
|
self.ignoreNextClick = true;
|
|
1005
1101
|
self.freezeMarkerPosition = pos;
|
|
1006
1102
|
if (
|
|
@@ -1010,6 +1106,28 @@ export default function (self) {
|
|
|
1010
1106
|
) {
|
|
1011
1107
|
self.scrollBox.scrollTop = 0;
|
|
1012
1108
|
self.frozenRow = self.currentCell.rowIndex + 1;
|
|
1109
|
+
self.scrollBox.bar.v.y =
|
|
1110
|
+
columnHeaderCellHeight +
|
|
1111
|
+
columnHeaderCellBorder +
|
|
1112
|
+
self.scrollCache.y[self.frozenRow];
|
|
1113
|
+
self.scrollBox.box.v.y =
|
|
1114
|
+
columnHeaderCellHeight +
|
|
1115
|
+
columnHeaderCellBorder +
|
|
1116
|
+
self.scrollCache.y[self.frozenRow];
|
|
1117
|
+
var dataHeight = self.scrollCache.y[self.scrollCache.y.length - 1];
|
|
1118
|
+
self.scrollBox.heightBoxRatio =
|
|
1119
|
+
(self.scrollBox.height -
|
|
1120
|
+
columnHeaderCellHeight -
|
|
1121
|
+
self.scrollCache.y[self.frozenRow]) /
|
|
1122
|
+
dataHeight;
|
|
1123
|
+
self.scrollBox.scrollBoxHeight =
|
|
1124
|
+
self.scrollBox.height * self.scrollBox.heightBoxRatio -
|
|
1125
|
+
self.style.scrollBarWidth;
|
|
1126
|
+
self.scrollBox.scrollBoxHeight = Math.max(
|
|
1127
|
+
self.scrollBox.scrollBoxHeight,
|
|
1128
|
+
self.style.scrollBarBoxMinSize,
|
|
1129
|
+
);
|
|
1130
|
+
self.scrollBox.box.v.height = self.scrollBox.scrollBoxHeight;
|
|
1013
1131
|
}
|
|
1014
1132
|
if (
|
|
1015
1133
|
self.currentCell &&
|
|
@@ -1018,6 +1136,22 @@ export default function (self) {
|
|
|
1018
1136
|
) {
|
|
1019
1137
|
self.scrollBox.scrollLeft = 0;
|
|
1020
1138
|
self.frozenColumn = self.currentCell.columnIndex + 1;
|
|
1139
|
+
self.scrollBox.bar.h.x =
|
|
1140
|
+
rowHeaderCellWidth + self.scrollCache.x[self.frozenColumn - 1];
|
|
1141
|
+
self.scrollBox.box.h.x =
|
|
1142
|
+
rowHeaderCellWidth + self.scrollCache.x[self.frozenColumn - 1];
|
|
1143
|
+
var dataWidth = self.scrollCache.x[self.scrollCache.x.length - 1];
|
|
1144
|
+
self.scrollBox.widthBoxRatio =
|
|
1145
|
+
(self.scrollBox.width - self.scrollCache.x[self.frozenColumn - 1]) /
|
|
1146
|
+
dataWidth;
|
|
1147
|
+
self.scrollBox.scrollBoxWidth =
|
|
1148
|
+
self.scrollBox.width * self.scrollBox.widthBoxRatio -
|
|
1149
|
+
self.style.scrollBarWidth;
|
|
1150
|
+
self.scrollBox.scrollBoxWidth = Math.max(
|
|
1151
|
+
self.scrollBox.scrollBoxWidth,
|
|
1152
|
+
self.style.scrollBarBoxMinSize,
|
|
1153
|
+
);
|
|
1154
|
+
self.scrollBox.box.h.width = self.scrollBox.scrollBoxWidth;
|
|
1021
1155
|
}
|
|
1022
1156
|
if (
|
|
1023
1157
|
Math.abs(pos.x) > self.attributes.reorderDeadZone ||
|
|
@@ -1084,7 +1218,12 @@ export default function (self) {
|
|
|
1084
1218
|
!freeze &&
|
|
1085
1219
|
!resize
|
|
1086
1220
|
) {
|
|
1087
|
-
|
|
1221
|
+
if (
|
|
1222
|
+
!(self.dragMode == 'row-reorder' && self.isMultiRowsSelected) &&
|
|
1223
|
+
!(self.currentCell.hovered && self.hovers.onFilterButton)
|
|
1224
|
+
) {
|
|
1225
|
+
self.selections = [];
|
|
1226
|
+
}
|
|
1088
1227
|
}
|
|
1089
1228
|
if (self.dragStartObject.isGrid) {
|
|
1090
1229
|
return;
|
|
@@ -1175,10 +1314,11 @@ export default function (self) {
|
|
|
1175
1314
|
self.draggingItem = self.dragStartObject;
|
|
1176
1315
|
if (
|
|
1177
1316
|
self.dragMode === 'column-reorder' &&
|
|
1178
|
-
self.
|
|
1317
|
+
!self.isMultiColumnsSelected(self.currentCell.header.index)
|
|
1179
1318
|
) {
|
|
1180
1319
|
self.selectColumn(self.currentCell.header.index, ctrl, e.shiftKey);
|
|
1181
|
-
|
|
1320
|
+
} else if (self.dragMode === 'row-reorder' && !self.isMultiRowsSelected) {
|
|
1321
|
+
self.selectRow(self.dragStartObject.rowIndex, ctrl, null);
|
|
1182
1322
|
}
|
|
1183
1323
|
document.body.addEventListener('mousemove', self.dragReorder, false);
|
|
1184
1324
|
document.body.addEventListener('mouseup', self.stopDragReorder, false);
|
|
@@ -1187,14 +1327,9 @@ export default function (self) {
|
|
|
1187
1327
|
};
|
|
1188
1328
|
self.mouseup = function (e) {
|
|
1189
1329
|
clearTimeout(self.scrollTimer);
|
|
1190
|
-
var ctrl = e.ctrlKey || e.metaKey;
|
|
1191
1330
|
self.cellBoundaryCrossed = true;
|
|
1192
1331
|
self.rowBoundaryCrossed = true;
|
|
1193
1332
|
self.columnBoundaryCrossed = true;
|
|
1194
|
-
if (self.draggingItem) {
|
|
1195
|
-
self.selectColumn(self.currentCell.header.index, ctrl, e.shiftKey);
|
|
1196
|
-
self.draw();
|
|
1197
|
-
}
|
|
1198
1333
|
self.selecting = undefined;
|
|
1199
1334
|
self.draggingItem = undefined;
|
|
1200
1335
|
self.dragStartObject = undefined;
|
|
@@ -1470,7 +1605,10 @@ export default function (self) {
|
|
|
1470
1605
|
self.currentCell.style === 'cornerCell'
|
|
1471
1606
|
) {
|
|
1472
1607
|
self.autosize();
|
|
1473
|
-
} else if (
|
|
1608
|
+
} else if (
|
|
1609
|
+
['cell', 'activeCell'].includes(self.currentCell.style) &&
|
|
1610
|
+
!self.hovers.onFilterButton
|
|
1611
|
+
) {
|
|
1474
1612
|
self.beginEditAt(self.currentCell.columnIndex, self.currentCell.rowIndex);
|
|
1475
1613
|
}
|
|
1476
1614
|
};
|
|
@@ -1740,6 +1878,7 @@ export default function (self) {
|
|
|
1740
1878
|
firstRowKeys,
|
|
1741
1879
|
isNeat = true; // Selected like [[0, 1], [0, 1]] of [[0, 3]] is neat; Selected like [[0, 1], [1, 2]] is untidy
|
|
1742
1880
|
function htmlSafe(v) {
|
|
1881
|
+
if (typeof v === 'number') return v;
|
|
1743
1882
|
return v.replace(/</g, '<').replace(/>/g, '>');
|
|
1744
1883
|
}
|
|
1745
1884
|
s.forEach(function (column, columnIndex) {
|
|
@@ -1753,8 +1892,8 @@ export default function (self) {
|
|
|
1753
1892
|
if (!firstRowKeys) firstRowKeys = Object.keys(row);
|
|
1754
1893
|
if (isNeat && rowKeys.length !== firstRowKeys.length) isNeat = false;
|
|
1755
1894
|
sSorted.forEach(function (column, columnIndex) {
|
|
1756
|
-
if (rowKeys.indexOf(column.name) < 0) {
|
|
1757
|
-
if (firstRowKeys.indexOf(column.name) < 0) {
|
|
1895
|
+
if (rowKeys.indexOf(String(column.name)) < 0) {
|
|
1896
|
+
if (firstRowKeys.indexOf(String(column.name)) < 0) {
|
|
1758
1897
|
return;
|
|
1759
1898
|
} else if (isNeat) {
|
|
1760
1899
|
isNeat = false;
|
package/lib/intf.js
CHANGED
|
@@ -61,6 +61,14 @@ export default function (self, ctor) {
|
|
|
61
61
|
trees: {},
|
|
62
62
|
};
|
|
63
63
|
self.selections = [];
|
|
64
|
+
self.filterable = {
|
|
65
|
+
rows: [],
|
|
66
|
+
columns: [],
|
|
67
|
+
};
|
|
68
|
+
self.selectedFilterButton = {
|
|
69
|
+
columnIndex: -1,
|
|
70
|
+
rowIndex: -1,
|
|
71
|
+
};
|
|
64
72
|
self.hovers = {};
|
|
65
73
|
self.attributes = {};
|
|
66
74
|
self.style = {};
|
|
@@ -88,6 +96,7 @@ export default function (self, ctor) {
|
|
|
88
96
|
self.eventNames = [
|
|
89
97
|
'afterdraw',
|
|
90
98
|
'afterrendercell',
|
|
99
|
+
'afterrenderfilterbutton',
|
|
91
100
|
'attributechanged',
|
|
92
101
|
'beforebeginedit',
|
|
93
102
|
'beforecreatecellgrid',
|
|
@@ -95,6 +104,7 @@ export default function (self, ctor) {
|
|
|
95
104
|
'beforeendedit',
|
|
96
105
|
'beforerendercell',
|
|
97
106
|
'beforerendercellgrid',
|
|
107
|
+
'beforerenderfilterbutton',
|
|
98
108
|
'beginedit',
|
|
99
109
|
'cellmouseout',
|
|
100
110
|
'cellmouseover',
|
|
@@ -755,6 +765,7 @@ export default function (self, ctor) {
|
|
|
755
765
|
self.intf.clearChangeLog = self.clearChangeLog;
|
|
756
766
|
self.intf.gotoCell = self.gotoCell;
|
|
757
767
|
self.intf.gotoRow = self.gotoRow;
|
|
768
|
+
self.intf.addButton = self.addButton;
|
|
758
769
|
self.intf.getHeaderByName = self.getHeaderByName;
|
|
759
770
|
self.intf.findColumnScrollLeft = self.findColumnScrollLeft;
|
|
760
771
|
self.intf.findRowScrollTop = self.findRowScrollTop;
|
|
@@ -1534,6 +1545,9 @@ export default function (self, ctor) {
|
|
|
1534
1545
|
if (!preventScrollEvent) {
|
|
1535
1546
|
self.scroll();
|
|
1536
1547
|
}
|
|
1548
|
+
if (self.button) {
|
|
1549
|
+
self.moveButtonPos();
|
|
1550
|
+
}
|
|
1537
1551
|
}
|
|
1538
1552
|
function setScrollLeft(value, preventScrollEvent) {
|
|
1539
1553
|
if (isNaN(value)) {
|
|
@@ -1552,6 +1566,9 @@ export default function (self, ctor) {
|
|
|
1552
1566
|
if (!preventScrollEvent) {
|
|
1553
1567
|
self.scroll();
|
|
1554
1568
|
}
|
|
1569
|
+
if (self.button) {
|
|
1570
|
+
self.moveButtonPos();
|
|
1571
|
+
}
|
|
1555
1572
|
}
|
|
1556
1573
|
self.scrollBox.toString = function () {
|
|
1557
1574
|
return (
|
package/lib/main.js
CHANGED
|
@@ -9,6 +9,7 @@ import events from './events';
|
|
|
9
9
|
import touch from './touch';
|
|
10
10
|
import intf from './intf';
|
|
11
11
|
import contextMenu from './contextMenu';
|
|
12
|
+
import button from './button';
|
|
12
13
|
import dom from './dom';
|
|
13
14
|
import publicMethods from './publicMethods';
|
|
14
15
|
|
|
@@ -21,6 +22,7 @@ var modules = [
|
|
|
21
22
|
touch,
|
|
22
23
|
intf,
|
|
23
24
|
contextMenu,
|
|
25
|
+
button,
|
|
24
26
|
dom,
|
|
25
27
|
publicMethods,
|
|
26
28
|
];
|