slickgrid 2.3.16.1 → 2.4.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/slickgrid.gemspec +1 -1
- data/vendor/assets/javascripts/slickgrid/controls/columnpicker.js +49 -34
- data/vendor/assets/javascripts/slickgrid/controls/gridmenu.js +32 -13
- data/vendor/assets/javascripts/slickgrid/core.js +174 -0
- data/vendor/assets/javascripts/slickgrid/dataview.js +47 -18
- data/vendor/assets/javascripts/slickgrid/editors.js +49 -27
- data/vendor/assets/javascripts/slickgrid/grid.js +5357 -3990
- data/vendor/assets/javascripts/slickgrid/groupitemmetadataprovider.js +4 -4
- data/vendor/assets/javascripts/slickgrid/plugins/autotooltips.js +2 -1
- data/vendor/assets/javascripts/slickgrid/plugins/cellcopymanager.js +2 -0
- data/vendor/assets/javascripts/slickgrid/plugins/cellexternalcopymanager.js +29 -9
- data/vendor/assets/javascripts/slickgrid/plugins/cellrangedecorator.js +2 -1
- data/vendor/assets/javascripts/slickgrid/plugins/cellrangeselector.js +70 -9
- data/vendor/assets/javascripts/slickgrid/plugins/cellselectionmodel.js +27 -5
- data/vendor/assets/javascripts/slickgrid/plugins/checkboxselectcolumn.js +157 -26
- data/vendor/assets/javascripts/slickgrid/plugins/draggablegrouping.js +145 -19
- data/vendor/assets/javascripts/slickgrid/plugins/headerbuttons.js +1 -0
- data/vendor/assets/javascripts/slickgrid/plugins/headermenu.js +8 -2
- data/vendor/assets/javascripts/slickgrid/plugins/rowdetailview.js +542 -231
- data/vendor/assets/javascripts/slickgrid/plugins/rowmovemanager.js +2 -1
- data/vendor/assets/javascripts/slickgrid/plugins/rowselectionmodel.js +1 -0
- data/vendor/assets/stylesheets/slickgrid/controls/draggablegrouping.scss +52 -0
- data/vendor/assets/stylesheets/slickgrid/controls/gridmenu.css +17 -3
- data/vendor/assets/stylesheets/slickgrid/grid.scss +54 -5
- data/vendor/assets/stylesheets/slickgrid/plugins/headermenu.scss +14 -0
- data/vendor/assets/stylesheets/slickgrid/plugins/rowdetailview.scss +9 -11
- metadata +3 -2
@@ -44,7 +44,7 @@
|
|
44
44
|
options = $.extend(true, {}, _defaults, options);
|
45
45
|
|
46
46
|
|
47
|
-
function defaultGroupCellFormatter(row, cell, value, columnDef, item) {
|
47
|
+
function defaultGroupCellFormatter(row, cell, value, columnDef, item, grid) {
|
48
48
|
if (!options.enableExpandCollapse) {
|
49
49
|
return item.title;
|
50
50
|
}
|
@@ -62,8 +62,8 @@
|
|
62
62
|
"</span>";
|
63
63
|
}
|
64
64
|
|
65
|
-
function defaultTotalsCellFormatter(row, cell, value, columnDef, item) {
|
66
|
-
return (columnDef.groupTotalsFormatter && columnDef.groupTotalsFormatter(item, columnDef)) || "";
|
65
|
+
function defaultTotalsCellFormatter(row, cell, value, columnDef, item, grid) {
|
66
|
+
return (columnDef.groupTotalsFormatter && columnDef.groupTotalsFormatter(item, columnDef, grid)) || "";
|
67
67
|
}
|
68
68
|
|
69
69
|
|
@@ -112,7 +112,7 @@
|
|
112
112
|
|
113
113
|
// TODO: add -/+ handling
|
114
114
|
function handleGridKeyDown(e, args) {
|
115
|
-
if (options.enableExpandCollapse && (e.which ==
|
115
|
+
if (options.enableExpandCollapse && (e.which == Slick.keyCode.SPACE)) {
|
116
116
|
var activeCell = this.getActiveCell();
|
117
117
|
if (activeCell) {
|
118
118
|
var item = this.getDataItem(activeCell.row);
|
@@ -28,6 +28,7 @@
|
|
28
28
|
onCopySuccess: optional handler to run when copy action is complete
|
29
29
|
newRowCreator: function to add rows to table if paste overflows bottom of table, if this function is not provided new rows will be ignored.
|
30
30
|
readOnlyMode: suppresses paste
|
31
|
+
headerColumnValueExtractor : option to specify a custom column header value extractor function
|
31
32
|
*/
|
32
33
|
var _grid;
|
33
34
|
var _self = this;
|
@@ -67,12 +68,21 @@
|
|
67
68
|
_grid.onKeyDown.unsubscribe(handleKeyDown);
|
68
69
|
}
|
69
70
|
|
70
|
-
function
|
71
|
+
function getHeaderValueForColumn(columnDef) {
|
72
|
+
if (_options.headerColumnValueExtractor) {
|
73
|
+
var val = _options.headerColumnValueExtractor(columnDef);
|
74
|
+
|
75
|
+
if (val) { return val; }
|
76
|
+
}
|
77
|
+
|
78
|
+
return columnDef.name;
|
79
|
+
}
|
80
|
+
|
81
|
+
function getDataItemValueForColumn(item, columnDef, e) {
|
71
82
|
if (_options.dataItemColumnValueExtractor) {
|
72
|
-
var
|
83
|
+
var val = _options.dataItemColumnValueExtractor(item, columnDef);
|
73
84
|
|
74
|
-
if (
|
75
|
-
return dataItemColumnValueExtractorValue;
|
85
|
+
if (val) { return val; }
|
76
86
|
}
|
77
87
|
|
78
88
|
var retVal = '';
|
@@ -83,7 +93,8 @@
|
|
83
93
|
'container':$("<p>"), // a dummy container
|
84
94
|
'column':columnDef,
|
85
95
|
'position':{'top':0, 'left':0}, // a dummy position required by some editors
|
86
|
-
'grid':_grid
|
96
|
+
'grid':_grid,
|
97
|
+
'event':e
|
87
98
|
};
|
88
99
|
var editor = new columnDef.editor(editorArgs);
|
89
100
|
editor.loadValue(item);
|
@@ -97,6 +108,8 @@
|
|
97
108
|
}
|
98
109
|
|
99
110
|
function setDataItemValueForColumn(item, columnDef, value) {
|
111
|
+
if (columnDef.denyPaste) { return null; }
|
112
|
+
|
100
113
|
if (_options.dataItemColumnValueSetter) {
|
101
114
|
return _options.dataItemColumnValueSetter(item, columnDef, value);
|
102
115
|
}
|
@@ -348,13 +361,13 @@
|
|
348
361
|
var clipTextHeaders = [];
|
349
362
|
for (var j = range.fromCell; j < range.toCell + 1 ; j++) {
|
350
363
|
if (columns[j].name.length > 0)
|
351
|
-
clipTextHeaders.push(columns[j]
|
364
|
+
clipTextHeaders.push(getHeaderValueForColumn(columns[j]));
|
352
365
|
}
|
353
366
|
clipTextRows.push(clipTextHeaders.join("\t"));
|
354
367
|
}
|
355
368
|
|
356
369
|
for (var j=range.fromCell; j< range.toCell+1 ; j++){
|
357
|
-
clipTextCells.push(getDataItemValueForColumn(dt, columns[j]));
|
370
|
+
clipTextCells.push(getDataItemValueForColumn(dt, columns[j], e));
|
358
371
|
}
|
359
372
|
clipTextRows.push(clipTextCells.join("\t"));
|
360
373
|
}
|
@@ -438,15 +451,22 @@
|
|
438
451
|
_grid.removeCellCssStyles(_copiedCellStyleLayerKey);
|
439
452
|
}
|
440
453
|
|
454
|
+
function setIncludeHeaderWhenCopying(includeHeaderWhenCopying) {
|
455
|
+
_options.includeHeaderWhenCopying = includeHeaderWhenCopying;
|
456
|
+
}
|
457
|
+
|
441
458
|
$.extend(this, {
|
442
459
|
"init": init,
|
443
460
|
"destroy": destroy,
|
461
|
+
"pluginName": "CellExternalCopyManager",
|
462
|
+
|
444
463
|
"clearCopySelection": clearCopySelection,
|
445
464
|
"handleKeyDown":handleKeyDown,
|
446
465
|
|
447
466
|
"onCopyCells": new Slick.Event(),
|
448
467
|
"onCopyCancelled": new Slick.Event(),
|
449
|
-
"onPasteCells": new Slick.Event()
|
468
|
+
"onPasteCells": new Slick.Event(),
|
469
|
+
"setIncludeHeaderWhenCopying" : setIncludeHeaderWhenCopying
|
450
470
|
});
|
451
471
|
}
|
452
|
-
})(jQuery);
|
472
|
+
})(jQuery);
|
@@ -41,7 +41,7 @@
|
|
41
41
|
_elem = $("<div></div>", {css: options.selectionCss})
|
42
42
|
.addClass(options.selectionCssClass)
|
43
43
|
.css("position", "absolute")
|
44
|
-
.appendTo(grid.
|
44
|
+
.appendTo(grid.getActiveCanvasNode());
|
45
45
|
}
|
46
46
|
|
47
47
|
var from = grid.getCellNodeBox(range.fromRow, range.fromCell);
|
@@ -65,6 +65,7 @@
|
|
65
65
|
}
|
66
66
|
|
67
67
|
$.extend(this, {
|
68
|
+
"pluginName": "CellRangeDecorator",
|
68
69
|
"show": show,
|
69
70
|
"hide": hide
|
70
71
|
});
|
@@ -10,6 +10,8 @@
|
|
10
10
|
var _grid;
|
11
11
|
var _currentlySelectedRange;
|
12
12
|
var _canvas;
|
13
|
+
var _gridOptions;
|
14
|
+
var _$activeCanvas;
|
13
15
|
var _dragging;
|
14
16
|
var _decorator;
|
15
17
|
var _self = this;
|
@@ -20,12 +22,24 @@
|
|
20
22
|
}
|
21
23
|
};
|
22
24
|
|
25
|
+
// Frozen row & column variables
|
26
|
+
var _rowOffset;
|
27
|
+
var _columnOffset;
|
28
|
+
var _isRightCanvas;
|
29
|
+
var _isBottomCanvas;
|
30
|
+
|
31
|
+
// Scrollings
|
32
|
+
var _scrollTop = 0;
|
33
|
+
var _scrollLeft = 0;
|
34
|
+
|
23
35
|
function init(grid) {
|
24
36
|
options = $.extend(true, {}, _defaults, options);
|
25
37
|
_decorator = options.cellDecorator || new Slick.CellRangeDecorator(grid, options);
|
26
38
|
_grid = grid;
|
27
39
|
_canvas = _grid.getCanvasNode();
|
40
|
+
_gridOptions = _grid.getOptions();
|
28
41
|
_handler
|
42
|
+
.subscribe(_grid.onScroll, handleScroll)
|
29
43
|
.subscribe(_grid.onDragInit, handleDragInit)
|
30
44
|
.subscribe(_grid.onDragStart, handleDragStart)
|
31
45
|
.subscribe(_grid.onDrag, handleDrag)
|
@@ -40,7 +54,32 @@
|
|
40
54
|
return _decorator;
|
41
55
|
}
|
42
56
|
|
57
|
+
function handleScroll(e, args) {
|
58
|
+
_scrollTop = args.scrollTop;
|
59
|
+
_scrollLeft = args.scrollLeft;
|
60
|
+
}
|
61
|
+
|
43
62
|
function handleDragInit(e, dd) {
|
63
|
+
// Set the active canvas node because the decorator needs to append its
|
64
|
+
// box to the correct canvas
|
65
|
+
_$activeCanvas = $(_grid.getActiveCanvasNode(e));
|
66
|
+
|
67
|
+
var c = _$activeCanvas.offset();
|
68
|
+
|
69
|
+
_rowOffset = 0;
|
70
|
+
_columnOffset = 0;
|
71
|
+
_isBottomCanvas = _$activeCanvas.hasClass('grid-canvas-bottom');
|
72
|
+
|
73
|
+
if (_gridOptions.frozenRow > -1 && _isBottomCanvas) {
|
74
|
+
_rowOffset = (_gridOptions.frozenBottom) ? $('.grid-canvas-bottom').height() : $('.grid-canvas-top').height();
|
75
|
+
}
|
76
|
+
|
77
|
+
_isRightCanvas = _$activeCanvas.hasClass('grid-canvas-right');
|
78
|
+
|
79
|
+
if (_gridOptions.frozenColumn > -1 && _isRightCanvas) {
|
80
|
+
_columnOffset = $('.grid-canvas-left').width();
|
81
|
+
}
|
82
|
+
|
44
83
|
// prevent the grid from cancelling drag'n'drop by default
|
45
84
|
e.stopImmediatePropagation();
|
46
85
|
}
|
@@ -59,11 +98,19 @@
|
|
59
98
|
|
60
99
|
_grid.focus();
|
61
100
|
|
62
|
-
var
|
63
|
-
|
64
|
-
|
101
|
+
var startX = dd.startX - $(_canvas).offset().left;
|
102
|
+
if (_gridOptions.frozenColumn >= 0 && _isRightCanvas) {
|
103
|
+
startX += _scrollLeft;
|
104
|
+
}
|
105
|
+
|
106
|
+
var startY = dd.startY - $(_canvas).offset().top;
|
107
|
+
if (_gridOptions.frozenRow >= 0 && _isBottomCanvas) {
|
108
|
+
startY += _scrollTop;
|
109
|
+
}
|
110
|
+
|
111
|
+
var start = _grid.getCellFromPoint(startX, startY);
|
65
112
|
|
66
|
-
dd.range = {start: start, end: {}};
|
113
|
+
dd.range = { start: start, end: {} };
|
67
114
|
_currentlySelectedRange = dd.range;
|
68
115
|
return _decorator.show(new Slick.Range(start.row, start.cell));
|
69
116
|
}
|
@@ -75,15 +122,27 @@
|
|
75
122
|
e.stopImmediatePropagation();
|
76
123
|
|
77
124
|
var end = _grid.getCellFromPoint(
|
78
|
-
e.pageX - $
|
79
|
-
e.pageY - $
|
125
|
+
e.pageX - _$activeCanvas.offset().left + _columnOffset,
|
126
|
+
e.pageY - _$activeCanvas.offset().top + _rowOffset
|
127
|
+
);
|
80
128
|
|
129
|
+
// ... frozen column(s),
|
130
|
+
if ( _gridOptions.frozenColumn >= 0 && (!_isRightCanvas && (end.cell > _gridOptions.frozenColumn)) || (_isRightCanvas && (end.cell <= _gridOptions.frozenColumn)) ) {
|
131
|
+
return;
|
132
|
+
}
|
133
|
+
|
134
|
+
// ... or frozen row(s)
|
135
|
+
if ( _gridOptions.frozenRow >= 0 && (!_isBottomCanvas && (end.row >= _gridOptions.frozenRow)) || (_isBottomCanvas && (end.row < _gridOptions.frozenRow)) ) {
|
136
|
+
return;
|
137
|
+
}
|
138
|
+
|
139
|
+
// ... or regular grid (without any frozen options)
|
81
140
|
if (!_grid.canCellBeSelected(end.row, end.cell)) {
|
82
141
|
return;
|
83
142
|
}
|
84
143
|
|
85
144
|
dd.range.end = end;
|
86
|
-
|
145
|
+
|
87
146
|
_decorator.show(new Slick.Range(dd.range.start.row, dd.range.start.cell, end.row, end.cell));
|
88
147
|
}
|
89
148
|
|
@@ -105,7 +164,7 @@
|
|
105
164
|
)
|
106
165
|
});
|
107
166
|
}
|
108
|
-
|
167
|
+
|
109
168
|
function getCurrentRange() {
|
110
169
|
return _currentlySelectedRange;
|
111
170
|
}
|
@@ -113,6 +172,8 @@
|
|
113
172
|
$.extend(this, {
|
114
173
|
"init": init,
|
115
174
|
"destroy": destroy,
|
175
|
+
"pluginName": "CellRangeSelector",
|
176
|
+
|
116
177
|
"getCellDecorator": getCellDecorator,
|
117
178
|
"getCurrentRange": getCurrentRange,
|
118
179
|
|
@@ -120,4 +181,4 @@
|
|
120
181
|
"onCellRangeSelected": new Slick.Event()
|
121
182
|
});
|
122
183
|
}
|
123
|
-
})(jQuery);
|
184
|
+
})(jQuery);
|
@@ -13,7 +13,7 @@
|
|
13
13
|
var _self = this;
|
14
14
|
var _selector;
|
15
15
|
|
16
|
-
if (typeof options === "undefined" || typeof options.cellRangeSelector === "undefined") {
|
16
|
+
if (typeof options === "undefined" || typeof options.cellRangeSelector === "undefined") {
|
17
17
|
_selector = new Slick.CellRangeSelector({
|
18
18
|
"selectionCss": {
|
19
19
|
"border": "2px solid black"
|
@@ -60,12 +60,33 @@
|
|
60
60
|
return result;
|
61
61
|
}
|
62
62
|
|
63
|
+
function rangesAreEqual(range1, range2) {
|
64
|
+
var areDifferent = (range1.length !== range2.length);
|
65
|
+
if (!areDifferent) {
|
66
|
+
for (var i = 0; i < range1.length; i++) {
|
67
|
+
if (
|
68
|
+
range1[i].fromCell !== range2[i].fromCell
|
69
|
+
|| range1[i].fromRow !== range2[i].fromRow
|
70
|
+
|| range1[i].toCell !== range2[i].toCell
|
71
|
+
|| range1[i].toRow !== range2[i].toRow
|
72
|
+
) {
|
73
|
+
areDifferent = true;
|
74
|
+
break;
|
75
|
+
}
|
76
|
+
}
|
77
|
+
}
|
78
|
+
return !areDifferent;
|
79
|
+
}
|
80
|
+
|
63
81
|
function setSelectedRanges(ranges) {
|
64
82
|
// simple check for: empty selection didn't change, prevent firing onSelectedRangesChanged
|
65
83
|
if ((!_ranges || _ranges.length === 0) && (!ranges || ranges.length === 0)) { return; }
|
66
84
|
|
85
|
+
// if range has not changed, don't fire onSelectedRangesChanged
|
86
|
+
var rangeHasChanged = !rangesAreEqual(_ranges, ranges);
|
87
|
+
|
67
88
|
_ranges = removeInvalidRanges(ranges);
|
68
|
-
_self.onSelectedRangesChanged.notify(_ranges);
|
89
|
+
if (rangeHasChanged) { _self.onSelectedRangesChanged.notify(_ranges); }
|
69
90
|
}
|
70
91
|
|
71
92
|
function getSelectedRanges() {
|
@@ -109,11 +130,11 @@
|
|
109
130
|
if (active && e.shiftKey && !metaKey && !e.altKey &&
|
110
131
|
(e.which == 37 || e.which == 39 || e.which == 38 || e.which == 40)) {
|
111
132
|
|
112
|
-
ranges = getSelectedRanges();
|
133
|
+
ranges = getSelectedRanges().slice();
|
113
134
|
if (!ranges.length)
|
114
135
|
ranges.push(new Slick.Range(active.row, active.cell));
|
115
136
|
|
116
|
-
// keyboard can work with last range only
|
137
|
+
// keyboard can work with last range only
|
117
138
|
last = ranges.pop();
|
118
139
|
|
119
140
|
// can't handle selection out of active cell
|
@@ -136,7 +157,7 @@
|
|
136
157
|
dRow += dirRow;
|
137
158
|
}
|
138
159
|
|
139
|
-
// define new selection range
|
160
|
+
// define new selection range
|
140
161
|
var new_last = new Slick.Range(active.row, active.cell, active.row + dirRow * dRow, active.cell + dirCell * dCell);
|
141
162
|
if (removeInvalidRanges([new_last]).length) {
|
142
163
|
ranges.push(new_last);
|
@@ -161,6 +182,7 @@
|
|
161
182
|
|
162
183
|
"init": init,
|
163
184
|
"destroy": destroy,
|
185
|
+
"pluginName": "CellSelectionModel",
|
164
186
|
|
165
187
|
"onSelectedRangesChanged": new Slick.Event()
|
166
188
|
});
|
@@ -9,15 +9,20 @@
|
|
9
9
|
|
10
10
|
function CheckboxSelectColumn(options) {
|
11
11
|
var _grid;
|
12
|
-
var
|
12
|
+
var _selectableOverride = null;
|
13
|
+
var _selectAll_UID = createUID();
|
13
14
|
var _handler = new Slick.EventHandler();
|
14
15
|
var _selectedRowsLookup = {};
|
15
16
|
var _defaults = {
|
16
17
|
columnId: "_checkbox_selector",
|
17
18
|
cssClass: null,
|
19
|
+
hideSelectAllCheckbox: false,
|
18
20
|
toolTip: "Select/Deselect All",
|
19
|
-
width: 30
|
21
|
+
width: 30,
|
22
|
+
hideInColumnTitleRow: false,
|
23
|
+
hideInFilterHeaderRow: true
|
20
24
|
};
|
25
|
+
var _isSelectAllChecked = false;
|
21
26
|
|
22
27
|
var _options = $.extend(true, {}, _defaults, options);
|
23
28
|
|
@@ -26,24 +31,85 @@
|
|
26
31
|
_handler
|
27
32
|
.subscribe(_grid.onSelectedRowsChanged, handleSelectedRowsChanged)
|
28
33
|
.subscribe(_grid.onClick, handleClick)
|
29
|
-
.subscribe(_grid.onHeaderClick, handleHeaderClick)
|
30
34
|
.subscribe(_grid.onKeyDown, handleKeyDown);
|
35
|
+
|
36
|
+
if (!_options.hideInFilterHeaderRow) {
|
37
|
+
addCheckboxToFilterHeaderRow(grid);
|
38
|
+
}
|
39
|
+
if (!_options.hideInColumnTitleRow) {
|
40
|
+
_handler.subscribe(_grid.onHeaderClick, handleHeaderClick)
|
41
|
+
}
|
31
42
|
}
|
32
43
|
|
33
44
|
function destroy() {
|
34
45
|
_handler.unsubscribeAll();
|
35
46
|
}
|
36
47
|
|
48
|
+
function getOptions() {
|
49
|
+
return _options;
|
50
|
+
}
|
51
|
+
|
52
|
+
function setOptions(options) {
|
53
|
+
_options = $.extend(true, {}, _options, options);
|
54
|
+
|
55
|
+
if (_options.hideSelectAllCheckbox) {
|
56
|
+
hideSelectAllFromColumnHeaderTitleRow();
|
57
|
+
hideSelectAllFromColumnHeaderFilterRow();
|
58
|
+
} else {
|
59
|
+
if (!_options.hideInColumnTitleRow) {
|
60
|
+
renderSelectAllCheckbox(_isSelectAllChecked);
|
61
|
+
_handler.subscribe(_grid.onHeaderClick, handleHeaderClick);
|
62
|
+
} else {
|
63
|
+
hideSelectAllFromColumnHeaderTitleRow();
|
64
|
+
}
|
65
|
+
|
66
|
+
if (!_options.hideInFilterHeaderRow) {
|
67
|
+
var selectAllContainer = $("#filter-checkbox-selectall-container");
|
68
|
+
selectAllContainer.show();
|
69
|
+
selectAllContainer.find('input[type="checkbox"]').prop("checked", _isSelectAllChecked);
|
70
|
+
} else {
|
71
|
+
hideSelectAllFromColumnHeaderFilterRow();
|
72
|
+
}
|
73
|
+
}
|
74
|
+
}
|
75
|
+
|
76
|
+
function hideSelectAllFromColumnHeaderTitleRow() {
|
77
|
+
_grid.updateColumnHeader(_options.columnId, "", "");
|
78
|
+
}
|
79
|
+
|
80
|
+
function hideSelectAllFromColumnHeaderFilterRow() {
|
81
|
+
$("#filter-checkbox-selectall-container").hide();
|
82
|
+
}
|
83
|
+
|
37
84
|
function handleSelectedRowsChanged(e, args) {
|
38
|
-
var UID = createUID();
|
39
85
|
var selectedRows = _grid.getSelectedRows();
|
40
86
|
var lookup = {}, row, i;
|
87
|
+
var disabledCount = 0;
|
88
|
+
if (typeof _selectableOverride === 'function') {
|
89
|
+
for (k = 0; k < _grid.getDataLength(); k++) {
|
90
|
+
// If we are allowed to select the row
|
91
|
+
var dataItem = _grid.getDataItem(k);
|
92
|
+
if (!checkSelectableOverride(i, dataItem, _grid)) {
|
93
|
+
disabledCount++;
|
94
|
+
}
|
95
|
+
}
|
96
|
+
}
|
97
|
+
|
98
|
+
var removeList = [];
|
41
99
|
for (i = 0; i < selectedRows.length; i++) {
|
42
100
|
row = selectedRows[i];
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
101
|
+
|
102
|
+
// If we are allowed to select the row
|
103
|
+
var rowItem = _grid.getDataItem(row);
|
104
|
+
if (checkSelectableOverride(i, rowItem, _grid)) {
|
105
|
+
lookup[row] = true;
|
106
|
+
if (lookup[row] !== _selectedRowsLookup[row]) {
|
107
|
+
_grid.invalidateRow(row);
|
108
|
+
delete _selectedRowsLookup[row];
|
109
|
+
}
|
110
|
+
}
|
111
|
+
else {
|
112
|
+
removeList.push(row);
|
47
113
|
}
|
48
114
|
}
|
49
115
|
for (i in _selectedRowsLookup) {
|
@@ -51,11 +117,22 @@
|
|
51
117
|
}
|
52
118
|
_selectedRowsLookup = lookup;
|
53
119
|
_grid.render();
|
120
|
+
_isSelectAllChecked = selectedRows.length && selectedRows.length + disabledCount >= _grid.getDataLength();
|
54
121
|
|
55
|
-
if (
|
56
|
-
|
57
|
-
}
|
58
|
-
|
122
|
+
if (!_options.hideInColumnTitleRow && !_options.hideSelectAllCheckbox) {
|
123
|
+
renderSelectAllCheckbox(_isSelectAllChecked);
|
124
|
+
}
|
125
|
+
if (!_options.hideInFilterHeaderRow) {
|
126
|
+
var selectAllElm = $("#header-filter-selector" + _selectAll_UID);
|
127
|
+
selectAllElm.prop("checked", _isSelectAllChecked);
|
128
|
+
}
|
129
|
+
// Remove items that shouln't of been selected in the first place (Got here Ctrl + click)
|
130
|
+
if (removeList.length > 0) {
|
131
|
+
for (i = 0; i < removeList.length; i++) {
|
132
|
+
var remIdx = selectedRows.indexOf(removeList[i]);
|
133
|
+
selectedRows.splice(remIdx, 1);
|
134
|
+
}
|
135
|
+
_grid.setSelectedRows(selectedRows);
|
59
136
|
}
|
60
137
|
}
|
61
138
|
|
@@ -89,6 +166,11 @@
|
|
89
166
|
}
|
90
167
|
|
91
168
|
function toggleRowSelection(row) {
|
169
|
+
var dataContext = _grid.getDataItem(row);
|
170
|
+
if (!checkSelectableOverride(row, dataContext, _grid)) {
|
171
|
+
return;
|
172
|
+
}
|
173
|
+
|
92
174
|
if (_selectedRowsLookup[row]) {
|
93
175
|
_grid.setSelectedRows($.grep(_grid.getSelectedRows(), function (n) {
|
94
176
|
return n != row
|
@@ -97,12 +179,11 @@
|
|
97
179
|
_grid.setSelectedRows(_grid.getSelectedRows().concat(row));
|
98
180
|
}
|
99
181
|
_grid.setActiveCell(row, getCheckboxColumnCellIndex());
|
100
|
-
_grid.focus();
|
101
182
|
}
|
102
183
|
|
103
184
|
function selectRows(rowArray) {
|
104
|
-
var i, l=rowArray.length, addRows = [];
|
105
|
-
for(i=0; i<l; i++) {
|
185
|
+
var i, l = rowArray.length, addRows = [];
|
186
|
+
for (i = 0; i < l; i++) {
|
106
187
|
if (!_selectedRowsLookup[rowArray[i]]) {
|
107
188
|
addRows[addRows.length] = rowArray[i];
|
108
189
|
}
|
@@ -111,14 +192,14 @@
|
|
111
192
|
}
|
112
193
|
|
113
194
|
function deSelectRows(rowArray) {
|
114
|
-
var i, l=rowArray.length, removeRows = [];
|
115
|
-
for(i=0; i<l; i++) {
|
195
|
+
var i, l = rowArray.length, removeRows = [];
|
196
|
+
for (i = 0; i < l; i++) {
|
116
197
|
if (_selectedRowsLookup[rowArray[i]]) {
|
117
198
|
removeRows[removeRows.length] = rowArray[i];
|
118
199
|
}
|
119
200
|
}
|
120
201
|
_grid.setSelectedRows($.grep(_grid.getSelectedRows(), function (n) {
|
121
|
-
return removeRows.indexOf(n)<0
|
202
|
+
return removeRows.indexOf(n) < 0
|
122
203
|
}));
|
123
204
|
}
|
124
205
|
|
@@ -134,7 +215,11 @@
|
|
134
215
|
if ($(e.target).is(":checked")) {
|
135
216
|
var rows = [];
|
136
217
|
for (var i = 0; i < _grid.getDataLength(); i++) {
|
137
|
-
|
218
|
+
// Get the row and check it's a selectable row before pushing it onto the stack
|
219
|
+
var rowItem = _grid.getDataItem(i);
|
220
|
+
if (rowItem.selectableRow !== false) {
|
221
|
+
rows.push(i);
|
222
|
+
}
|
138
223
|
}
|
139
224
|
_grid.setSelectedRows(rows);
|
140
225
|
} else {
|
@@ -151,7 +236,7 @@
|
|
151
236
|
if (_checkboxColumnCellIndex === null) {
|
152
237
|
_checkboxColumnCellIndex = 0;
|
153
238
|
var colArr = _grid.getColumns();
|
154
|
-
for (var i=0; i < colArr.length; i++) {
|
239
|
+
for (var i = 0; i < colArr.length; i++) {
|
155
240
|
if (colArr[i].id == _options.columnId) {
|
156
241
|
_checkboxColumnCellIndex = i;
|
157
242
|
}
|
@@ -161,42 +246,88 @@
|
|
161
246
|
}
|
162
247
|
|
163
248
|
function getColumnDefinition() {
|
164
|
-
var UID = createUID();
|
165
|
-
|
166
249
|
return {
|
167
250
|
id: _options.columnId,
|
168
|
-
name: "<input id='header-selector" +
|
251
|
+
name: (_options.hideSelectAllCheckbox || _options.hideInColumnTitleRow) ? "" : "<input id='header-selector" + _selectAll_UID + "' type='checkbox'><label for='header-selector" + _selectAll_UID + "'></label>",
|
169
252
|
toolTip: _options.toolTip,
|
170
253
|
field: "sel",
|
171
254
|
width: _options.width,
|
172
255
|
resizable: false,
|
173
256
|
sortable: false,
|
174
257
|
cssClass: _options.cssClass,
|
258
|
+
hideSelectAllCheckbox: _options.hideSelectAllCheckbox,
|
175
259
|
formatter: checkboxSelectionFormatter
|
176
260
|
};
|
177
261
|
}
|
178
262
|
|
263
|
+
function addCheckboxToFilterHeaderRow(grid) {
|
264
|
+
grid.onHeaderRowCellRendered.subscribe(function (e, args) {
|
265
|
+
if (args.column.field === "sel") {
|
266
|
+
$(args.node).empty();
|
267
|
+
$("<span id='filter-checkbox-selectall-container'><input id='header-filter-selector" + _selectAll_UID + "' type='checkbox'><label for='header-filter-selector" + _selectAll_UID + "'></label></span>")
|
268
|
+
.appendTo(args.node)
|
269
|
+
.on('click', function (evnt) {
|
270
|
+
handleHeaderClick(evnt, args)
|
271
|
+
});
|
272
|
+
}
|
273
|
+
});
|
274
|
+
}
|
275
|
+
|
179
276
|
function createUID() {
|
180
277
|
return Math.round(10000000 * Math.random());
|
181
278
|
}
|
182
279
|
|
183
|
-
function checkboxSelectionFormatter(row, cell, value, columnDef, dataContext) {
|
280
|
+
function checkboxSelectionFormatter(row, cell, value, columnDef, dataContext, grid) {
|
184
281
|
var UID = createUID() + row;
|
185
282
|
|
186
283
|
if (dataContext) {
|
187
|
-
|
284
|
+
if (!checkSelectableOverride(row, dataContext, grid)) {
|
285
|
+
return null;
|
286
|
+
} else {
|
287
|
+
return _selectedRowsLookup[row]
|
188
288
|
? "<input id='selector" + UID + "' type='checkbox' checked='checked'><label for='selector" + UID + "'></label>"
|
189
289
|
: "<input id='selector" + UID + "' type='checkbox'><label for='selector" + UID + "'></label>";
|
290
|
+
}
|
190
291
|
}
|
191
292
|
return null;
|
192
293
|
}
|
193
294
|
|
295
|
+
function checkSelectableOverride(row, dataContext, grid) {
|
296
|
+
if (typeof _selectableOverride === 'function') {
|
297
|
+
return _selectableOverride(row, dataContext, grid);
|
298
|
+
}
|
299
|
+
return true;
|
300
|
+
}
|
301
|
+
|
302
|
+
function renderSelectAllCheckbox(isSelectAllChecked) {
|
303
|
+
if (isSelectAllChecked) {
|
304
|
+
_grid.updateColumnHeader(_options.columnId, "<input id='header-selector" + _selectAll_UID + "' type='checkbox' checked='checked'><label for='header-selector" + _selectAll_UID + "'></label>", _options.toolTip);
|
305
|
+
} else {
|
306
|
+
_grid.updateColumnHeader(_options.columnId, "<input id='header-selector" + _selectAll_UID + "' type='checkbox'><label for='header-selector" + _selectAll_UID + "'></label>", _options.toolTip);
|
307
|
+
}
|
308
|
+
}
|
309
|
+
|
310
|
+
/**
|
311
|
+
* Method that user can pass to override the default behavior or making every row a selectable row.
|
312
|
+
* In order word, user can choose which rows to be selectable or not by providing his own logic.
|
313
|
+
* @param overrideFn: override function callback
|
314
|
+
*/
|
315
|
+
function selectableOverride(overrideFn) {
|
316
|
+
_selectableOverride = overrideFn;
|
317
|
+
}
|
318
|
+
|
319
|
+
|
194
320
|
$.extend(this, {
|
195
321
|
"init": init,
|
196
322
|
"destroy": destroy,
|
323
|
+
"pluginName": "CheckboxSelectColumn",
|
324
|
+
|
197
325
|
"deSelectRows": deSelectRows,
|
198
326
|
"selectRows": selectRows,
|
199
|
-
"getColumnDefinition": getColumnDefinition
|
327
|
+
"getColumnDefinition": getColumnDefinition,
|
328
|
+
"getOptions": getOptions,
|
329
|
+
"selectableOverride": selectableOverride,
|
330
|
+
"setOptions": setOptions,
|
200
331
|
});
|
201
332
|
}
|
202
333
|
})(jQuery);
|