datatables.net-select 2.0.5 → 3.0.0
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/js/dataTables.select.js +439 -72
- package/js/dataTables.select.min.js +2 -2
- package/js/dataTables.select.min.mjs +2 -2
- package/js/dataTables.select.mjs +439 -72
- package/package.json +1 -1
- package/types/types.d.ts +98 -3
package/js/dataTables.select.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! Select for DataTables
|
|
1
|
+
/*! Select for DataTables 3.0.0
|
|
2
2
|
* © SpryMedia Ltd - datatables.net/license/mit
|
|
3
3
|
*/
|
|
4
4
|
|
|
@@ -56,7 +56,7 @@ DataTable.select.classes = {
|
|
|
56
56
|
checkbox: 'dt-select-checkbox'
|
|
57
57
|
};
|
|
58
58
|
|
|
59
|
-
DataTable.select.version = '
|
|
59
|
+
DataTable.select.version = '3.0.0';
|
|
60
60
|
|
|
61
61
|
DataTable.select.init = function (dt) {
|
|
62
62
|
var ctx = dt.settings()[0];
|
|
@@ -126,11 +126,13 @@ DataTable.select.init = function (dt) {
|
|
|
126
126
|
var style = 'api';
|
|
127
127
|
var blurable = false;
|
|
128
128
|
var toggleable = true;
|
|
129
|
+
var selectable = null;
|
|
129
130
|
var info = true;
|
|
130
131
|
var selector = 'td, th';
|
|
131
132
|
var className = 'selected';
|
|
132
133
|
var headerCheckbox = true;
|
|
133
134
|
var setStyle = false;
|
|
135
|
+
var keys = false;
|
|
134
136
|
|
|
135
137
|
ctx._select = {
|
|
136
138
|
infoEls: []
|
|
@@ -182,6 +184,14 @@ DataTable.select.init = function (dt) {
|
|
|
182
184
|
if (opts.headerCheckbox !== undefined) {
|
|
183
185
|
headerCheckbox = opts.headerCheckbox;
|
|
184
186
|
}
|
|
187
|
+
|
|
188
|
+
if (opts.selectable !== undefined) {
|
|
189
|
+
selectable = opts.selectable;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (opts.keys !== undefined) {
|
|
193
|
+
keys = opts.keys;
|
|
194
|
+
}
|
|
185
195
|
}
|
|
186
196
|
|
|
187
197
|
dt.select.selector(selector);
|
|
@@ -190,6 +200,8 @@ DataTable.select.init = function (dt) {
|
|
|
190
200
|
dt.select.blurable(blurable);
|
|
191
201
|
dt.select.toggleable(toggleable);
|
|
192
202
|
dt.select.info(info);
|
|
203
|
+
dt.select.keys(keys);
|
|
204
|
+
dt.select.selectable(selectable);
|
|
193
205
|
ctx._select.className = className;
|
|
194
206
|
|
|
195
207
|
// If the init options haven't enabled select, but there is a selectable
|
|
@@ -199,11 +211,9 @@ DataTable.select.init = function (dt) {
|
|
|
199
211
|
}
|
|
200
212
|
|
|
201
213
|
// Insert a checkbox into the header if needed - might need to wait
|
|
202
|
-
// for init complete
|
|
214
|
+
// for init complete
|
|
203
215
|
if (headerCheckbox || headerCheckbox === 'select-page' || headerCheckbox === 'select-all') {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
dt.on('init', function () {
|
|
216
|
+
dt.ready(function () {
|
|
207
217
|
initCheckboxHeader(dt, headerCheckbox);
|
|
208
218
|
});
|
|
209
219
|
}
|
|
@@ -570,9 +580,17 @@ function info(api, node) {
|
|
|
570
580
|
return;
|
|
571
581
|
}
|
|
572
582
|
|
|
573
|
-
var
|
|
574
|
-
var
|
|
575
|
-
var
|
|
583
|
+
var ctx = api.settings()[0];
|
|
584
|
+
var rowSetLength = ctx._select_set.length;
|
|
585
|
+
var rows = rowSetLength ? rowSetLength : api.rows({ selected: true }).count();
|
|
586
|
+
var columns = api.columns({ selected: true }).count();
|
|
587
|
+
var cells = api.cells({ selected: true }).count();
|
|
588
|
+
|
|
589
|
+
// If subtractive selection, then we need to take the number of rows and
|
|
590
|
+
// subtract those that have been deselected
|
|
591
|
+
if (ctx._select_mode === 'subtractive') {
|
|
592
|
+
rows = api.page.info().recordsDisplay - rowSetLength;
|
|
593
|
+
}
|
|
576
594
|
|
|
577
595
|
var add = function (el, name, num) {
|
|
578
596
|
el.append(
|
|
@@ -612,7 +630,8 @@ function info(api, node) {
|
|
|
612
630
|
* @param {*} headerCheckbox the header checkbox option
|
|
613
631
|
*/
|
|
614
632
|
function initCheckboxHeader( dt, headerCheckbox ) {
|
|
615
|
-
var
|
|
633
|
+
var dtSettings = dt.settings()[0];
|
|
634
|
+
var dtInternalColumns = dtSettings.aoColumns;
|
|
616
635
|
|
|
617
636
|
// Find any checkbox column(s)
|
|
618
637
|
dt.columns().iterator('column', function (s, idx) {
|
|
@@ -636,33 +655,37 @@ function initCheckboxHeader( dt, headerCheckbox ) {
|
|
|
636
655
|
.on('change', function () {
|
|
637
656
|
if (this.checked) {
|
|
638
657
|
if (headerCheckbox == 'select-page') {
|
|
639
|
-
dt.rows({page: 'current'}).select()
|
|
640
|
-
}
|
|
658
|
+
dt.rows({page: 'current'}).select();
|
|
659
|
+
}
|
|
660
|
+
else {
|
|
641
661
|
dt.rows({search: 'applied'}).select();
|
|
642
662
|
}
|
|
643
663
|
}
|
|
644
664
|
else {
|
|
645
|
-
|
|
665
|
+
if (headerCheckbox == 'select-page') {
|
|
666
|
+
dt.rows({page: 'current', selected: true}).deselect();
|
|
667
|
+
}
|
|
668
|
+
else {
|
|
669
|
+
dt.rows({selected: true}).deselect();
|
|
670
|
+
}
|
|
646
671
|
}
|
|
647
672
|
})
|
|
648
673
|
.on('click', function (e) {
|
|
649
674
|
e.stopPropagation();
|
|
650
675
|
});
|
|
651
|
-
|
|
676
|
+
|
|
652
677
|
// Update the header checkbox's state when the selection in the
|
|
653
678
|
// table changes
|
|
654
679
|
dt.on('draw select deselect', function (e, pass, type) {
|
|
655
680
|
if (type === 'row' || ! type) {
|
|
656
|
-
var
|
|
657
|
-
var search = dt.rows({search: 'applied', selected: true}).count();
|
|
658
|
-
var available = headerCheckbox == 'select-page' ? dt.rows({page: 'current'}).count() : dt.rows({search: 'applied'}).count();
|
|
681
|
+
var nums = headerCheckboxState(dt, headerCheckbox);
|
|
659
682
|
|
|
660
|
-
if (search && search <= count && search === available) {
|
|
683
|
+
if (nums.search && nums.search <= nums.count && nums.search === nums.available) {
|
|
661
684
|
input
|
|
662
685
|
.prop('checked', true)
|
|
663
686
|
.prop('indeterminate', false);
|
|
664
687
|
}
|
|
665
|
-
else if (search === 0 && count === 0) {
|
|
688
|
+
else if (nums.search === 0 && nums.count === 0) {
|
|
666
689
|
input
|
|
667
690
|
.prop('checked', false)
|
|
668
691
|
.prop('indeterminate', false);
|
|
@@ -678,6 +701,188 @@ function initCheckboxHeader( dt, headerCheckbox ) {
|
|
|
678
701
|
});
|
|
679
702
|
}
|
|
680
703
|
|
|
704
|
+
function keysSet(dt) {
|
|
705
|
+
var ctx = dt.settings()[0];
|
|
706
|
+
var flag = ctx._select.keys;
|
|
707
|
+
var namespace = 'dts-keys-' + ctx.sTableId;
|
|
708
|
+
|
|
709
|
+
if (flag) {
|
|
710
|
+
// Need a tabindex of the `tr` elements to make them focusable by the browser
|
|
711
|
+
$(dt.rows({page: 'current'}).nodes()).attr('tabindex', 0);
|
|
712
|
+
|
|
713
|
+
dt.on('draw.' + namespace, function () {
|
|
714
|
+
$(dt.rows({page: 'current'}).nodes()).attr('tabindex', 0);
|
|
715
|
+
});
|
|
716
|
+
|
|
717
|
+
// Listen on document for tab, up and down
|
|
718
|
+
$(document).on('keydown.' + namespace, function (e) {
|
|
719
|
+
var key = e.keyCode;
|
|
720
|
+
var active = document.activeElement;
|
|
721
|
+
|
|
722
|
+
// Can't use e.key as it wasn't widely supported until 2017
|
|
723
|
+
// 9 Tab
|
|
724
|
+
// 13 Return
|
|
725
|
+
// 32 Space
|
|
726
|
+
// 38 ArrowUp
|
|
727
|
+
// 40 ArrowDown
|
|
728
|
+
if (! [9, 13, 32, 38, 40].includes(key)) {
|
|
729
|
+
return;
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
var nodes = dt.rows({page: 'current'}).nodes().toArray();
|
|
733
|
+
var idx = nodes.indexOf(active);
|
|
734
|
+
var preventDefault = true;
|
|
735
|
+
|
|
736
|
+
// Only take an action if a row has focus
|
|
737
|
+
if (idx === -1) {
|
|
738
|
+
return;
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
if (key === 9) {
|
|
742
|
+
// Tab focus change
|
|
743
|
+
if (e.shift === false && idx === nodes.length - 1) {
|
|
744
|
+
keysPageDown(dt);
|
|
745
|
+
}
|
|
746
|
+
else if (e.shift === true && idx === 0) {
|
|
747
|
+
keysPageUp(dt);
|
|
748
|
+
}
|
|
749
|
+
else {
|
|
750
|
+
// Browser will do it for us
|
|
751
|
+
preventDefault = false;
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
else if (key === 13 || key === 32) {
|
|
755
|
+
// Row selection / deselection
|
|
756
|
+
var row = dt.row(active);
|
|
757
|
+
|
|
758
|
+
if (row.selected()) {
|
|
759
|
+
row.deselect();
|
|
760
|
+
}
|
|
761
|
+
else {
|
|
762
|
+
row.select();
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
else if (key === 38) {
|
|
766
|
+
// Move up
|
|
767
|
+
if (idx > 0) {
|
|
768
|
+
nodes[idx-1].focus();
|
|
769
|
+
}
|
|
770
|
+
else {
|
|
771
|
+
keysPageUp(dt);
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
else {
|
|
775
|
+
// Move down
|
|
776
|
+
if (idx < nodes.length -1) {
|
|
777
|
+
nodes[idx+1].focus();
|
|
778
|
+
}
|
|
779
|
+
else {
|
|
780
|
+
keysPageDown(dt);
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
if (preventDefault) {
|
|
785
|
+
e.stopPropagation();
|
|
786
|
+
e.preventDefault();
|
|
787
|
+
}
|
|
788
|
+
});
|
|
789
|
+
}
|
|
790
|
+
else {
|
|
791
|
+
// Stop the rows from being able to gain focus
|
|
792
|
+
$(dt.rows().nodes()).removeAttr('tabindex');
|
|
793
|
+
|
|
794
|
+
// Nuke events
|
|
795
|
+
dt.off('draw.' + namespace);
|
|
796
|
+
$(document).off('keydown.' + namespace);
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
/**
|
|
801
|
+
* Change to the next page and focus on the first row
|
|
802
|
+
*
|
|
803
|
+
* @param {DataTable.Api} dt DataTable instance
|
|
804
|
+
*/
|
|
805
|
+
function keysPageDown(dt) {
|
|
806
|
+
// Is there another page to turn to?
|
|
807
|
+
var info = dt.page.info();
|
|
808
|
+
|
|
809
|
+
if (info.page < info.pages - 1) {
|
|
810
|
+
dt
|
|
811
|
+
.one('draw', function () {
|
|
812
|
+
dt.row(':first-child').node().focus();
|
|
813
|
+
})
|
|
814
|
+
.page('next')
|
|
815
|
+
.draw(false);
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
/**
|
|
820
|
+
* Change to the previous page and focus on the last row
|
|
821
|
+
*
|
|
822
|
+
* @param {DataTable.Api} dt DataTable instance
|
|
823
|
+
*/
|
|
824
|
+
function keysPageUp(dt) {
|
|
825
|
+
// Is there another page to turn to?
|
|
826
|
+
var info = dt.page.info();
|
|
827
|
+
|
|
828
|
+
if (info.page > 0) {
|
|
829
|
+
dt
|
|
830
|
+
.one('draw', function () {
|
|
831
|
+
dt.row(':last-child').node().focus();
|
|
832
|
+
})
|
|
833
|
+
.page('previous')
|
|
834
|
+
.draw(false);
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
/**
|
|
839
|
+
* Determine the counts used to define the header checkbox's state
|
|
840
|
+
*
|
|
841
|
+
* @param {*} dt DT API
|
|
842
|
+
* @param {*} headerCheckbox Configuration for what the header checkbox does
|
|
843
|
+
* @returns Counts object
|
|
844
|
+
*/
|
|
845
|
+
function headerCheckboxState(dt, headerCheckbox) {
|
|
846
|
+
var ctx = dt.settings()[0];
|
|
847
|
+
var selectable = ctx._select.selectable;
|
|
848
|
+
var available = 0;
|
|
849
|
+
var count = headerCheckbox == 'select-page'
|
|
850
|
+
? dt.rows({page: 'current', selected: true}).count()
|
|
851
|
+
: dt.rows({selected: true}).count();
|
|
852
|
+
var search = headerCheckbox == 'select-page'
|
|
853
|
+
? dt.rows({page: 'current', selected: true}).count()
|
|
854
|
+
: dt.rows({search: 'applied', selected: true}).count();
|
|
855
|
+
|
|
856
|
+
if (! selectable) {
|
|
857
|
+
available = headerCheckbox == 'select-page'
|
|
858
|
+
? dt.rows({page: 'current'}).count()
|
|
859
|
+
: dt.rows({search: 'applied'}).count();
|
|
860
|
+
}
|
|
861
|
+
else {
|
|
862
|
+
// Need to count how many rows are actually selectable to know if all selectable
|
|
863
|
+
// rows are selected or not
|
|
864
|
+
var indexes = headerCheckbox == 'select-page'
|
|
865
|
+
? dt.rows({page: 'current'}).indexes()
|
|
866
|
+
: dt.rows({search: 'applied'}).indexes();
|
|
867
|
+
|
|
868
|
+
for (var i=0 ; i<indexes.length ; i++) {
|
|
869
|
+
// For speed I use the internal DataTables object.
|
|
870
|
+
var rowInternal = ctx.aoData[indexes[i]];
|
|
871
|
+
var result = selectable(rowInternal._aData, rowInternal.nTr, indexes[i]);
|
|
872
|
+
|
|
873
|
+
if (result) {
|
|
874
|
+
available++;
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
return {
|
|
880
|
+
available: available,
|
|
881
|
+
count: count,
|
|
882
|
+
search: search
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
|
|
681
886
|
/**
|
|
682
887
|
* Initialisation of a new table. Attach event handlers and callbacks to allow
|
|
683
888
|
* Select to operate correctly.
|
|
@@ -692,6 +897,12 @@ function init(ctx) {
|
|
|
692
897
|
var api = new DataTable.Api(ctx);
|
|
693
898
|
ctx._select_init = true;
|
|
694
899
|
|
|
900
|
+
// When `additive` then `_select_set` contains a list of the row ids that
|
|
901
|
+
// are selected. If `subtractive` then all rows are selected, except those
|
|
902
|
+
// in `_select_set`, which is a list of ids.
|
|
903
|
+
ctx._select_mode = 'additive';
|
|
904
|
+
ctx._select_set = [];
|
|
905
|
+
|
|
695
906
|
// Row callback so that classes can be added to rows and cells if the item
|
|
696
907
|
// was selected before the element was created. This will happen with the
|
|
697
908
|
// `deferRender` option enabled.
|
|
@@ -702,9 +913,16 @@ function init(ctx) {
|
|
|
702
913
|
ctx.aoRowCreatedCallback.push(function (row, data, index) {
|
|
703
914
|
var i, ien;
|
|
704
915
|
var d = ctx.aoData[index];
|
|
916
|
+
var id = api.row(index).id();
|
|
705
917
|
|
|
706
918
|
// Row
|
|
707
|
-
if (
|
|
919
|
+
if (
|
|
920
|
+
d._select_selected ||
|
|
921
|
+
(ctx._select_mode === 'additive' && ctx._select_set.includes(id)) ||
|
|
922
|
+
(ctx._select_mode === 'subtractive' && ! ctx._select_set.includes(id))
|
|
923
|
+
) {
|
|
924
|
+
d._select_selected = true;
|
|
925
|
+
|
|
708
926
|
$(row)
|
|
709
927
|
.addClass(ctx._select.className)
|
|
710
928
|
.find('input.' + checkboxClass(true)).prop('checked', true);
|
|
@@ -723,46 +941,7 @@ function init(ctx) {
|
|
|
723
941
|
}
|
|
724
942
|
);
|
|
725
943
|
|
|
726
|
-
|
|
727
|
-
// if there is an rowId (i.e. a unique value to identify each row with)
|
|
728
|
-
api.on('preXhr.dt.dtSelect', function (e, settings) {
|
|
729
|
-
if (settings !== api.settings()[0]) {
|
|
730
|
-
// Not triggered by our DataTable!
|
|
731
|
-
return;
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
// note that column selection doesn't need to be cached and then
|
|
735
|
-
// reselected, as they are already selected
|
|
736
|
-
var rows = api
|
|
737
|
-
.rows({ selected: true })
|
|
738
|
-
.ids(true)
|
|
739
|
-
.filter(function (d) {
|
|
740
|
-
return d !== undefined;
|
|
741
|
-
});
|
|
742
|
-
|
|
743
|
-
var cells = api
|
|
744
|
-
.cells({ selected: true })
|
|
745
|
-
.eq(0)
|
|
746
|
-
.map(function (cellIdx) {
|
|
747
|
-
var id = api.row(cellIdx.row).id(true);
|
|
748
|
-
return id ? { row: id, column: cellIdx.column } : undefined;
|
|
749
|
-
})
|
|
750
|
-
.filter(function (d) {
|
|
751
|
-
return d !== undefined;
|
|
752
|
-
});
|
|
753
|
-
|
|
754
|
-
// On the next draw, reselect the currently selected items
|
|
755
|
-
api.one('draw.dt.dtSelect', function () {
|
|
756
|
-
api.rows(rows).select();
|
|
757
|
-
|
|
758
|
-
// `cells` is not a cell index selector, so it needs a loop
|
|
759
|
-
if (cells.any()) {
|
|
760
|
-
cells.each(function (id) {
|
|
761
|
-
api.cells(id.row, id.column).select();
|
|
762
|
-
});
|
|
763
|
-
}
|
|
764
|
-
});
|
|
765
|
-
});
|
|
944
|
+
_cumulativeEvents(api);
|
|
766
945
|
|
|
767
946
|
// Update the table information element with selected item summary
|
|
768
947
|
api.on('info.dt', function (e, ctx, node) {
|
|
@@ -935,6 +1114,73 @@ function _safeId(node) {
|
|
|
935
1114
|
return node.id.replace(/[^a-zA-Z0-9\-\_]/g, '-');
|
|
936
1115
|
}
|
|
937
1116
|
|
|
1117
|
+
/**
|
|
1118
|
+
* Set up event handlers for cumulative selection
|
|
1119
|
+
*
|
|
1120
|
+
* @param {*} api DT API instance
|
|
1121
|
+
*/
|
|
1122
|
+
function _cumulativeEvents(api) {
|
|
1123
|
+
// Add event listeners to add / remove from the _select_set
|
|
1124
|
+
api.on('select', function (e, dt, type, indexes) {
|
|
1125
|
+
// Only support for rows at the moment
|
|
1126
|
+
if (type !== 'row') {
|
|
1127
|
+
return;
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
var ctx = api.settings()[0];
|
|
1131
|
+
|
|
1132
|
+
if (ctx._select_mode === 'additive') {
|
|
1133
|
+
// Add row to the selection list if it isn't already there
|
|
1134
|
+
_add(api, ctx._select_set, indexes);
|
|
1135
|
+
}
|
|
1136
|
+
else {
|
|
1137
|
+
// Subtractive - if a row is selected it should not in the list
|
|
1138
|
+
// as in subtractive mode the list gives the rows which are not
|
|
1139
|
+
// selected
|
|
1140
|
+
_remove(api, ctx._select_set, indexes);
|
|
1141
|
+
}
|
|
1142
|
+
});
|
|
1143
|
+
|
|
1144
|
+
api.on('deselect', function (e, dt, type, indexes) {
|
|
1145
|
+
// Only support for rows at the moment
|
|
1146
|
+
if (type !== 'row') {
|
|
1147
|
+
return;
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1150
|
+
var ctx = api.settings()[0];
|
|
1151
|
+
|
|
1152
|
+
if (ctx._select_mode === 'additive') {
|
|
1153
|
+
// List is of those rows selected, so remove it
|
|
1154
|
+
_remove(api, ctx._select_set, indexes);
|
|
1155
|
+
}
|
|
1156
|
+
else {
|
|
1157
|
+
// List is of rows which are deselected, so add it!
|
|
1158
|
+
_add(api, ctx._select_set, indexes);
|
|
1159
|
+
}
|
|
1160
|
+
});
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
function _add(api, arr, indexes) {
|
|
1164
|
+
for (var i=0 ; i<indexes.length ; i++) {
|
|
1165
|
+
var id = api.row(indexes[i]).id();
|
|
1166
|
+
|
|
1167
|
+
if (id && id !== 'undefined' && ! arr.includes(id)) {
|
|
1168
|
+
arr.push(id);
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
function _remove(api, arr, indexes) {
|
|
1174
|
+
for (var i=0 ; i<indexes.length ; i++) {
|
|
1175
|
+
var id = api.row(indexes[i]).id();
|
|
1176
|
+
var idx = arr.indexOf(id);
|
|
1177
|
+
|
|
1178
|
+
if (idx !== -1) {
|
|
1179
|
+
arr.splice(idx, 1);
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
|
|
938
1184
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
939
1185
|
* DataTables selectors
|
|
940
1186
|
*/
|
|
@@ -1062,6 +1308,22 @@ apiRegister('select.items()', function (items) {
|
|
|
1062
1308
|
});
|
|
1063
1309
|
});
|
|
1064
1310
|
|
|
1311
|
+
apiRegister('select.keys()', function (flag) {
|
|
1312
|
+
if (flag === undefined) {
|
|
1313
|
+
return this.context[0]._select.keys;
|
|
1314
|
+
}
|
|
1315
|
+
|
|
1316
|
+
return this.iterator('table', function (ctx) {
|
|
1317
|
+
if (!ctx._select) {
|
|
1318
|
+
DataTable.select.init(new DataTable.Api(ctx));
|
|
1319
|
+
}
|
|
1320
|
+
|
|
1321
|
+
ctx._select.keys = flag;
|
|
1322
|
+
|
|
1323
|
+
keysSet(new DataTable.Api(ctx));
|
|
1324
|
+
});
|
|
1325
|
+
});
|
|
1326
|
+
|
|
1065
1327
|
// Takes effect from the _next_ selection. None disables future selection, but
|
|
1066
1328
|
// does not clear the current selection. Use the `deselect` methods for that
|
|
1067
1329
|
apiRegister('select.style()', function (style) {
|
|
@@ -1083,10 +1345,15 @@ apiRegister('select.style()', function (style) {
|
|
|
1083
1345
|
// Add / remove mouse event handlers. They aren't required when only
|
|
1084
1346
|
// API selection is available
|
|
1085
1347
|
var dt = new DataTable.Api(ctx);
|
|
1086
|
-
disableMouseSelection(dt);
|
|
1087
1348
|
|
|
1088
1349
|
if (style !== 'api') {
|
|
1089
|
-
|
|
1350
|
+
dt.ready(function () {
|
|
1351
|
+
disableMouseSelection(dt);
|
|
1352
|
+
enableMouseSelection(dt);
|
|
1353
|
+
});
|
|
1354
|
+
}
|
|
1355
|
+
else {
|
|
1356
|
+
disableMouseSelection(dt);
|
|
1090
1357
|
}
|
|
1091
1358
|
|
|
1092
1359
|
eventTrigger(new DataTable.Api(ctx), 'selectStyle', [style]);
|
|
@@ -1099,16 +1366,36 @@ apiRegister('select.selector()', function (selector) {
|
|
|
1099
1366
|
}
|
|
1100
1367
|
|
|
1101
1368
|
return this.iterator('table', function (ctx) {
|
|
1102
|
-
|
|
1369
|
+
var dt = new DataTable.Api(ctx);
|
|
1370
|
+
var style = ctx._select.style;
|
|
1371
|
+
|
|
1372
|
+
disableMouseSelection(dt);
|
|
1103
1373
|
|
|
1104
1374
|
ctx._select.selector = selector;
|
|
1105
1375
|
|
|
1106
|
-
if (
|
|
1107
|
-
|
|
1376
|
+
if (style && style !== 'api') {
|
|
1377
|
+
dt.ready(function () {
|
|
1378
|
+
disableMouseSelection(dt);
|
|
1379
|
+
enableMouseSelection(dt);
|
|
1380
|
+
});
|
|
1381
|
+
}
|
|
1382
|
+
else {
|
|
1383
|
+
disableMouseSelection(dt);
|
|
1108
1384
|
}
|
|
1109
1385
|
});
|
|
1110
1386
|
});
|
|
1111
1387
|
|
|
1388
|
+
apiRegister('select.selectable()', function (set) {
|
|
1389
|
+
let ctx = this.context[0];
|
|
1390
|
+
|
|
1391
|
+
if (set) {
|
|
1392
|
+
ctx._select.selectable = set;
|
|
1393
|
+
return this;
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1396
|
+
return ctx._select.selectable;
|
|
1397
|
+
});
|
|
1398
|
+
|
|
1112
1399
|
apiRegister('select.last()', function (set) {
|
|
1113
1400
|
let ctx = this.context[0];
|
|
1114
1401
|
|
|
@@ -1120,8 +1407,50 @@ apiRegister('select.last()', function (set) {
|
|
|
1120
1407
|
return ctx._select_lastCell;
|
|
1121
1408
|
});
|
|
1122
1409
|
|
|
1410
|
+
apiRegister('select.cumulative()', function (mode) {
|
|
1411
|
+
if (mode) {
|
|
1412
|
+
return this.iterator('table', function (ctx) {
|
|
1413
|
+
if (ctx._select_mode === mode) {
|
|
1414
|
+
return;
|
|
1415
|
+
}
|
|
1416
|
+
|
|
1417
|
+
var dt = new DataTable.Api(ctx);
|
|
1418
|
+
|
|
1419
|
+
// Convert from the current mode, to the new
|
|
1420
|
+
if (mode === 'subtractive') {
|
|
1421
|
+
// For subtractive mode we track the row ids which are not selected
|
|
1422
|
+
var unselected = dt.rows({selected: false}).ids().toArray();
|
|
1423
|
+
|
|
1424
|
+
ctx._select_mode = mode;
|
|
1425
|
+
ctx._select_set.length = 0;
|
|
1426
|
+
ctx._select_set.push.apply(ctx._select_set, unselected);
|
|
1427
|
+
}
|
|
1428
|
+
else {
|
|
1429
|
+
// Switching to additive, so selected rows are to be used
|
|
1430
|
+
var selected = dt.rows({selected: true}).ids().toArray();
|
|
1431
|
+
|
|
1432
|
+
ctx._select_mode = mode;
|
|
1433
|
+
ctx._select_set.length = 0;
|
|
1434
|
+
ctx._select_set.push.apply(ctx._select_set, selected);
|
|
1435
|
+
}
|
|
1436
|
+
}).draw(false);
|
|
1437
|
+
}
|
|
1438
|
+
|
|
1439
|
+
let ctx = this.context[0];
|
|
1440
|
+
|
|
1441
|
+
if (ctx && ctx._select_set) {
|
|
1442
|
+
return {
|
|
1443
|
+
mode: ctx._select_mode,
|
|
1444
|
+
rows: ctx._select_set
|
|
1445
|
+
};
|
|
1446
|
+
}
|
|
1447
|
+
|
|
1448
|
+
return null;
|
|
1449
|
+
});
|
|
1450
|
+
|
|
1123
1451
|
apiRegisterPlural('rows().select()', 'row().select()', function (select) {
|
|
1124
1452
|
var api = this;
|
|
1453
|
+
var selectedIndexes = [];
|
|
1125
1454
|
|
|
1126
1455
|
if (select === false) {
|
|
1127
1456
|
return this.deselect();
|
|
@@ -1136,9 +1465,20 @@ apiRegisterPlural('rows().select()', 'row().select()', function (select) {
|
|
|
1136
1465
|
var dtData = ctx.aoData[idx];
|
|
1137
1466
|
var dtColumns = ctx.aoColumns;
|
|
1138
1467
|
|
|
1468
|
+
if (ctx._select.selectable) {
|
|
1469
|
+
var result = ctx._select.selectable(dtData._aData, dtData.nTr, idx);
|
|
1470
|
+
|
|
1471
|
+
if (result === false) {
|
|
1472
|
+
// Not selectable - do nothing
|
|
1473
|
+
return;
|
|
1474
|
+
}
|
|
1475
|
+
}
|
|
1476
|
+
|
|
1139
1477
|
$(dtData.nTr).addClass(ctx._select.className);
|
|
1140
1478
|
dtData._select_selected = true;
|
|
1141
1479
|
|
|
1480
|
+
selectedIndexes.push(idx);
|
|
1481
|
+
|
|
1142
1482
|
for (var i=0 ; i<dtColumns.length ; i++) {
|
|
1143
1483
|
var col = dtColumns[i];
|
|
1144
1484
|
|
|
@@ -1163,8 +1503,8 @@ apiRegisterPlural('rows().select()', 'row().select()', function (select) {
|
|
|
1163
1503
|
}
|
|
1164
1504
|
});
|
|
1165
1505
|
|
|
1166
|
-
this.iterator('table', function (
|
|
1167
|
-
eventTrigger(api, 'select', ['row',
|
|
1506
|
+
this.iterator('table', function (ct) {
|
|
1507
|
+
eventTrigger(api, 'select', ['row', selectedIndexes], true);
|
|
1168
1508
|
});
|
|
1169
1509
|
|
|
1170
1510
|
return this;
|
|
@@ -1180,6 +1520,22 @@ apiRegister('row().selected()', function () {
|
|
|
1180
1520
|
return false;
|
|
1181
1521
|
});
|
|
1182
1522
|
|
|
1523
|
+
apiRegister('row().focus()', function () {
|
|
1524
|
+
var ctx = this.context[0];
|
|
1525
|
+
|
|
1526
|
+
if (ctx && this.length && ctx.aoData[this[0]] && ctx.aoData[this[0]].nTr) {
|
|
1527
|
+
ctx.aoData[this[0]].nTr.focus();
|
|
1528
|
+
}
|
|
1529
|
+
});
|
|
1530
|
+
|
|
1531
|
+
apiRegister('row().blur()', function () {
|
|
1532
|
+
var ctx = this.context[0];
|
|
1533
|
+
|
|
1534
|
+
if (ctx && this.length && ctx.aoData[this[0]] && ctx.aoData[this[0]].nTr) {
|
|
1535
|
+
ctx.aoData[this[0]].nTr.blur();
|
|
1536
|
+
}
|
|
1537
|
+
});
|
|
1538
|
+
|
|
1183
1539
|
apiRegisterPlural('columns().select()', 'column().select()', function (select) {
|
|
1184
1540
|
var api = this;
|
|
1185
1541
|
|
|
@@ -1526,6 +1882,8 @@ $.each(['Row', 'Column', 'Cell'], function (i, item) {
|
|
|
1526
1882
|
init: function (dt) {
|
|
1527
1883
|
var that = this;
|
|
1528
1884
|
|
|
1885
|
+
this.active(dt.select.items() === lc);
|
|
1886
|
+
|
|
1529
1887
|
dt.on('selectItems.dt.DT', function (e, ctx, items) {
|
|
1530
1888
|
that.active(items === lc);
|
|
1531
1889
|
});
|
|
@@ -1576,8 +1934,18 @@ DataTable.render.select = function (valueProp, nameProp) {
|
|
|
1576
1934
|
var dtRow = meta.settings.aoData[meta.row];
|
|
1577
1935
|
var selected = dtRow._select_selected;
|
|
1578
1936
|
var ariaLabel = meta.settings.oLanguage.select.aria.rowCheckbox;
|
|
1937
|
+
var selectable = meta.settings._select.selectable;
|
|
1579
1938
|
|
|
1580
1939
|
if (type === 'display') {
|
|
1940
|
+
// Check if the row is selectable before showing the checkbox
|
|
1941
|
+
if (selectable) {
|
|
1942
|
+
var result = selectable(row, dtRow.nTr, meta.row);
|
|
1943
|
+
|
|
1944
|
+
if (result === false) {
|
|
1945
|
+
return '';
|
|
1946
|
+
}
|
|
1947
|
+
}
|
|
1948
|
+
|
|
1581
1949
|
return $('<input>')
|
|
1582
1950
|
.attr({
|
|
1583
1951
|
'aria-label': ariaLabel,
|
|
@@ -1636,11 +2004,10 @@ $.fn.DataTable.select = DataTable.select;
|
|
|
1636
2004
|
* Initialisation
|
|
1637
2005
|
*/
|
|
1638
2006
|
|
|
1639
|
-
// DataTables creation -
|
|
1640
|
-
//
|
|
1641
|
-
//
|
|
1642
|
-
|
|
1643
|
-
$(document).on('preInit.dt.dtSelect', function (e, ctx) {
|
|
2007
|
+
// DataTables creation - we need this to run _before_ data is read in, but
|
|
2008
|
+
// for backwards compat. we also run again on preInit. If it happens twice
|
|
2009
|
+
// it will simply do nothing the second time around.
|
|
2010
|
+
$(document).on('i18n.dt.dtSelect preInit.dt.dtSelect', function (e, ctx) {
|
|
1644
2011
|
if (e.namespace !== 'dt') {
|
|
1645
2012
|
return;
|
|
1646
2013
|
}
|