Skip to content

Commit 47247ab

Browse files
committed
Updated compatibility with FixedColumns extension. Improved handling of cells with duplicate data. Other fixes.
1 parent 10a594a commit 47247ab

File tree

2 files changed

+145
-133
lines changed

2 files changed

+145
-133
lines changed

js/dataTables.checkboxes.js

Lines changed: 144 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -183,11 +183,11 @@ Checkboxes.prototype = {
183183
// If row selection is enabled for this column
184184
if(ctx.aoColumns[i].checkboxes.selectRow){
185185

186-
// If Select extension is available
187-
if(DataTable.select){
186+
// If Select extension is enabled
187+
if(ctx._select){
188188
hasCheckboxesSelectRow = true;
189189

190-
// Otherwise, if Select extension is not available
190+
// Otherwise, if Select extension is not enabled
191191
} else {
192192
// Disable row selection for this column
193193
ctx.aoColumns[i].checkboxes.selectRow = false;
@@ -329,74 +329,66 @@ Checkboxes.prototype = {
329329
},
330330

331331
// Updates array holding data for selected checkboxes
332-
updateData: function(type, selector, isSelected){
332+
updateData: function(type, selector, isSelected, allowDups){
333333
var self = this;
334334
var dt = self.s.dt;
335335
var ctx = self.s.ctx;
336336

337-
var nodes = [];
338-
if(type === 'cell' || type === 'row'){
339-
if(type === 'row'){
340-
dt.rows(selector).every(function(rowIdx){
341-
// Get index of the first column that has checkbox and row selection enabled
342-
var colIdx = self.getSelectRowColIndex();
343-
if(colIdx !== null){
344-
selector = dt.cell(rowIdx, colIdx).node();
345-
}
346-
});
347-
}
337+
// By default, duplicate data is not allowed
338+
if(typeof allowDups === 'undefined'){ allowDups = false; }
348339

349-
dt.cells(selector).every(function (cellRow, cellCol) {
350-
// If Checkboxes extension is enabled for this column
351-
if(ctx.aoColumns[cellCol].checkboxes){
352-
// Get cell data
353-
var cellData = this.data();
354-
355-
// Determine whether data is in the list
356-
var hasData = ctx.checkboxes.s.data[cellCol].hasOwnProperty(cellData);
357-
358-
// If checkbox is checked and data is not in the list
359-
if(isSelected){
360-
if(hasData){
361-
ctx.checkboxes.s.data[cellCol][cellData]++;
362-
} else {
363-
ctx.checkboxes.s.data[cellCol][cellData] = 1;
364-
}
340+
var cellSelector;
365341

366-
// Otherwise, if checkbox is not checked and data is in the list
367-
} else if (!isSelected && hasData){
368-
if(ctx.checkboxes.s.data[cellCol][cellData] === 1){
369-
delete ctx.checkboxes.s.data[cellCol][cellData];
370-
} else {
371-
ctx.checkboxes.s.data[cellCol][cellData]--;
372-
}
373-
}
342+
if(type === 'cell'){
343+
cellSelector = selector;
344+
345+
} else if(type === 'row'){
346+
cellSelector = [];
347+
348+
dt.rows(selector).every(function(rowIdx){
349+
// Get index of the first column that has checkbox and row selection enabled
350+
var colIdx = self.getSelectRowColIndex();
351+
if(colIdx !== null){
352+
cellSelector.push({ row: rowIdx, column: colIdx });
374353
}
375354
});
355+
}
376356

377-
} else if(type === 'column'){
378-
// Determine column index
379-
var cellCol = dt.column(selector).index();
380-
357+
dt.cells(cellSelector).every(function (cellRow, cellCol) {
381358
// If Checkboxes extension is enabled for this column
382359
if(ctx.aoColumns[cellCol].checkboxes){
360+
// Get cell data
361+
var cellData = this.data();
362+
363+
// Determine whether data is in the list
364+
var hasData = ctx.checkboxes.s.data[cellCol].hasOwnProperty(cellData);
365+
366+
// If checkbox is checked and data is not in the list
383367
if(isSelected){
384-
ctx.checkboxes.s.data[cellCol] = {};
385-
$.each(dt.column(cellCol).data(), function(index, cellData){
386-
if(ctx.checkboxes.s.data[cellCol].hasOwnProperty(cellData)){
387-
ctx.checkboxes.s.data[cellCol][cellData]++;
388-
} else {
389-
ctx.checkboxes.s.data[cellCol][cellData] = 1;
390-
}
391-
});
368+
// If data is available and duplicates are allowed
369+
if(hasData && allowDups){
370+
ctx.checkboxes.s.data[cellCol][cellData]++;
392371

393-
} else {
394-
ctx.checkboxes.s.data[cellCol] = {};
372+
// Otherwise, if data is not available or duplicates are not allowed
373+
} else {
374+
ctx.checkboxes.s.data[cellCol][cellData] = 1;
375+
}
376+
377+
// Otherwise, if checkbox is not checked and data is in the list
378+
} else if (!isSelected && hasData){
379+
// If only data counter equals to 1 or duplicates are not allowed
380+
if(ctx.checkboxes.s.data[cellCol][cellData] === 1 || !allowDups){
381+
delete ctx.checkboxes.s.data[cellCol][cellData];
382+
383+
// Otherwise, if data counter is greater than 1 and duplicates are allowed
384+
} else {
385+
ctx.checkboxes.s.data[cellCol][cellData]--;
386+
}
395387
}
396388
}
397-
}
389+
});
398390

399-
// If state saving is enabled
391+
// If state saving is enabled
400392
if(ctx.oFeatures.bStateSave){
401393
// Save state
402394
dt.state.save();
@@ -409,35 +401,19 @@ Checkboxes.prototype = {
409401
var dt = self.s.dt;
410402
var ctx = self.s.ctx;
411403

412-
var rowSelector = [];
413-
if(type === 'row'){
414-
rowSelector = selector;
415-
416-
} else if(type === 'cell'){
417-
dt.cells(selector).every(function(cellRow, cellCol){
418-
// If Checkboxes extension is enabled
419-
// and row selection is enabled for this column
420-
if(ctx.aoColumns[cellCol].checkboxes && ctx.aoColumns[cellCol].checkboxes.selectRow){
421-
rowSelector.push(cellRow);
422-
}
423-
});
424-
}
425-
426-
if(rowSelector.length){
427-
// If Select extension is available
428-
if(DataTable.select){
429-
// Disable select event hanlder temporarily
430-
self.s.ignoreSelect = true;
431-
432-
if(isSelected){
433-
dt.rows(rowSelector).select();
434-
} else {
435-
dt.rows(rowSelector).deselect();
436-
}
404+
// If Select extension is enabled
405+
if(ctx._select){
406+
// Disable select event hanlder temporarily
407+
self.s.ignoreSelect = true;
437408

438-
// Re-enable select event handler
439-
self.s.ignoreSelect = false;
409+
if(isSelected){
410+
dt.rows(selector).select();
411+
} else {
412+
dt.rows(selector).deselect();
440413
}
414+
415+
// Re-enable select event handler
416+
self.s.ignoreSelect = false;
441417
}
442418
},
443419

@@ -489,13 +465,11 @@ Checkboxes.prototype = {
489465

490466
// If cell needs to be selected
491467
if(dataSeen[cellData] <= ctx.checkboxes.s.data[cellCol][cellData]){
492-
var cellNode = this.node();
493-
self.updateCheckbox('cell', cellNode, true);
468+
self.updateCheckbox('cell', { row: cellRow, column: cellCol }, true);
494469

495-
// If Checkboxes extension is enabled
496-
// and row selection is enabled for this column
497-
if(ctx.aoColumns[cellCol].checkboxes && ctx.aoColumns[cellCol].checkboxes.selectRow){
498-
self.updateSelect('cell', cellNode, true);
470+
// If row selection is enabled
471+
if(ctx.aoColumns[cellCol].checkboxes.selectRow){
472+
self.updateSelect('row', cellRow, true);
499473
}
500474
}
501475
}
@@ -508,10 +482,20 @@ Checkboxes.prototype = {
508482
var dt = self.s.dt;
509483
var ctx = self.s.ctx;
510484

485+
var cellSelector;
486+
511487
// Get cell
512488
var $cell = $(ctrl).closest('td');
513489

514-
dt.cell($cell).checkboxes.select(ctrl.checked);
490+
// If cell is in a fixed column using FixedColumns extension
491+
if($cell.parents('.DTFC_Cloned').length){
492+
cellSelector = dt.fixedColumns().cellIndex($cell);
493+
494+
} else {
495+
cellSelector = $cell;
496+
}
497+
498+
dt.cell(cellSelector).checkboxes.select(ctrl.checked, true);
515499

516500
// Prevent click event from propagating to parent
517501
e.stopPropagation();
@@ -527,7 +511,7 @@ Checkboxes.prototype = {
527511

528512
if(type === 'row'){
529513
self.updateCheckbox('row', indexes, (e.type === 'select') ? true : false);
530-
self.updateData('row', indexes, (e.type === 'select') ? true : false);
514+
self.updateData('row', indexes, (e.type === 'select') ? true : false, true);
531515

532516
// Get index of the first column that has checkbox and row selection enabled
533517
var colIdx = self.getSelectRowColIndex();
@@ -555,40 +539,16 @@ Checkboxes.prototype = {
555539
colIdx = dt.column($th).index();
556540
}
557541

558-
var cells = dt.cells('tr', colIdx, {
542+
dt.column(colIdx, {
559543
page: (
560544
(ctx.aoColumns[colIdx].checkboxes && ctx.aoColumns[colIdx].checkboxes.selectAllPages)
561545
? 'all'
562546
: 'current'
563547
),
564548
search: 'applied'
565-
});
566-
567-
self.updateData('column', colIdx, ctrl.checked);
568-
self.updateCheckbox('cell', cells.nodes(), ctrl.checked);
569-
570-
// If row selection is enabled
571-
if(ctx.aoColumns[colIdx].checkboxes.selectRow){
572-
var rows = dt.rows({
573-
page: (
574-
(ctx.aoColumns[colIdx].checkboxes && ctx.aoColumns[colIdx].checkboxes.selectAllPages)
575-
? 'all'
576-
: 'current'
577-
),
578-
search: 'applied'
579-
});
580-
581-
self.updateSelect('row', rows.nodes(), ctrl.checked);
582-
}
583-
584-
self.updateSelectAll(colIdx);
585-
586-
// If column is fixed using FixedColumns extension
587-
if($th.parents('.DTFC_Cloned').length){
588-
// Update columns in the cloned table
589-
dt.fixedColumns().update();
590-
}
549+
}).checkboxes.select(ctrl.checked, true);
591550

551+
// Prevent click event from propagating to parent
592552
e.stopPropagation();
593553
},
594554

@@ -721,7 +681,7 @@ Checkboxes.prototype = {
721681
var ctx = self.s.ctx;
722682

723683
// If FixedColumns extension is available
724-
if(DataTable.FixedColumns){
684+
if(ctx._oFixedColumns){
725685
return dt.fixedColumns().cellIndex(cell);
726686

727687
} else {
@@ -747,6 +707,23 @@ Checkboxes.prototype = {
747707
}
748708

749709
return colIdx;
710+
},
711+
712+
// Updates fixed column if FixedColumns extension is enabled
713+
// and given column is inside a fixed column
714+
updateFixedColumn: function(colIdx){
715+
var self = this;
716+
var dt = self.s.dt;
717+
var ctx = self.s.ctx;
718+
719+
// If FixedColumns extension is enabled
720+
if(ctx._oFixedColumns){
721+
var leftCols = ctx._oFixedColumns.s.iLeftColumns;
722+
var rightCols = ctx.aoColumns.length - ctx._oFixedColumns.s.iRightColumns - 1;
723+
if (colIdx < leftCols || colIdx > rightCols){
724+
dt.fixedColumns().update();
725+
}
726+
}
750727
}
751728
};
752729

@@ -795,40 +772,75 @@ Api.register( 'checkboxes()', function () {
795772
return this;
796773
} );
797774

798-
Api.registerPlural( 'columns().checkboxes.select()', 'column().checkboxes.select()', function ( select ) {
775+
Api.registerPlural( 'columns().checkboxes.select()', 'column().checkboxes.select()', function ( select, allowDups ) {
799776
if(typeof select === 'undefined'){ select = true; }
800777

801-
return this.iterator( 'column', function (ctx, colIdx){
778+
return this.iterator( 'column-rows', function ( ctx, colIdx, i, j, rowsIdx ) {
802779
if(ctx.checkboxes){
803-
var selector = this.cells('tr', colIdx).nodes();
780+
var selector = [];
781+
$.each(rowsIdx, function(index, rowIdx){
782+
selector.push({ row: rowIdx, column: colIdx });
783+
});
784+
804785
ctx.checkboxes.updateCheckbox('cell', selector, (select) ? true : false);
805-
ctx.checkboxes.updateData('column', colIdx, (select) ? true : false);
806-
ctx.checkboxes.updateSelect('cell', selector, (select) ? true : false);
807-
ctx.checkboxes.updateSelectAll(colIdx);
786+
ctx.checkboxes.updateData('cell', selector, (select) ? true : false, allowDups);
787+
788+
// If row selection is enabled
789+
if(ctx.aoColumns[colIdx].checkboxes.selectRow){
790+
ctx.checkboxes.updateSelect('row', rowsIdx, select);
791+
}
792+
793+
// If FixedColumns extension is enabled
794+
if(ctx._oFixedColumns){
795+
// Use timeout to let FixedColumns construct the header
796+
// before we update the "Select all" checkbox
797+
setTimeout(function(){ ctx.checkboxes.updateSelectAll(colIdx); }, 0);
798+
799+
} else {
800+
ctx.checkboxes.updateSelectAll(colIdx);
801+
}
802+
803+
ctx.checkboxes.updateFixedColumn(colIdx);
808804
}
809805
}, 1 );
810806
} );
811807

812-
Api.registerPlural( 'cells().checkboxes.select()', 'cell().checkboxes.select()', function ( select ) {
808+
Api.registerPlural( 'cells().checkboxes.select()', 'cell().checkboxes.select()', function ( select, allowDups ) {
813809
if(typeof select === 'undefined'){ select = true; }
814810

815811
return this.iterator( 'cell', function ( ctx, rowIdx, colIdx ) {
816812
if(ctx.checkboxes){
817813
var selector = { row: rowIdx, column: colIdx };
814+
818815
ctx.checkboxes.updateCheckbox('cell', selector, (select) ? true : false);
819-
ctx.checkboxes.updateData('cell', selector, (select) ? true : false);
820-
ctx.checkboxes.updateSelect('cell', selector, (select) ? true : false);
821-
ctx.checkboxes.updateSelectAll(colIdx);
816+
ctx.checkboxes.updateData('cell', selector, (select) ? true : false, allowDups);
817+
818+
// If row selection is enabled
819+
if(ctx.aoColumns[colIdx].checkboxes.selectRow){
820+
ctx.checkboxes.updateSelect('row', rowIdx, select);
821+
}
822+
823+
// If FixedColumns extension is enabled
824+
if(ctx._oFixedColumns){
825+
// Use timeout to let FixedColumns construct the header
826+
// before we update the "Select all" checkbox
827+
setTimeout(function(){ ctx.checkboxes.updateSelectAll(colIdx); }, 0);
828+
829+
} else {
830+
ctx.checkboxes.updateSelectAll(colIdx);
831+
}
832+
833+
ctx.checkboxes.updateFixedColumn(colIdx);
822834
}
823835
}, 1 );
824836
} );
825837

826-
Api.registerPlural( 'columns().checkboxes.deselect()', 'column().checkboxes.deselect()', function () {
827-
return this.checkboxes.select(false);
838+
Api.registerPlural( 'columns().checkboxes.deselect()', 'column().checkboxes.deselect()', function ( allowDups ) {
839+
return this.checkboxes.select(false, allowDups);
828840
} );
829841

830-
Api.registerPlural( 'cells().checkboxes.deselect()', 'cell().checkboxes.deselect()', function () {
831-
return this.checkboxes.select(false);
842+
Api.registerPlural( 'cells().checkboxes.deselect()', 'cell().checkboxes.deselect()', function ( allowDups ) {
843+
return this.checkboxes.select(false, allowDups);
832844
} );
833845

834846
Api.registerPlural( 'columns().checkboxes.selected()', 'column().checkboxes.selected()', function () {

0 commit comments

Comments
 (0)