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.mjs
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
|
|
|
@@ -16,7 +16,7 @@ DataTable.select.classes = {
|
|
|
16
16
|
checkbox: 'dt-select-checkbox'
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
-
DataTable.select.version = '
|
|
19
|
+
DataTable.select.version = '3.0.0';
|
|
20
20
|
|
|
21
21
|
DataTable.select.init = function (dt) {
|
|
22
22
|
var ctx = dt.settings()[0];
|
|
@@ -86,11 +86,13 @@ DataTable.select.init = function (dt) {
|
|
|
86
86
|
var style = 'api';
|
|
87
87
|
var blurable = false;
|
|
88
88
|
var toggleable = true;
|
|
89
|
+
var selectable = null;
|
|
89
90
|
var info = true;
|
|
90
91
|
var selector = 'td, th';
|
|
91
92
|
var className = 'selected';
|
|
92
93
|
var headerCheckbox = true;
|
|
93
94
|
var setStyle = false;
|
|
95
|
+
var keys = false;
|
|
94
96
|
|
|
95
97
|
ctx._select = {
|
|
96
98
|
infoEls: []
|
|
@@ -142,6 +144,14 @@ DataTable.select.init = function (dt) {
|
|
|
142
144
|
if (opts.headerCheckbox !== undefined) {
|
|
143
145
|
headerCheckbox = opts.headerCheckbox;
|
|
144
146
|
}
|
|
147
|
+
|
|
148
|
+
if (opts.selectable !== undefined) {
|
|
149
|
+
selectable = opts.selectable;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (opts.keys !== undefined) {
|
|
153
|
+
keys = opts.keys;
|
|
154
|
+
}
|
|
145
155
|
}
|
|
146
156
|
|
|
147
157
|
dt.select.selector(selector);
|
|
@@ -150,6 +160,8 @@ DataTable.select.init = function (dt) {
|
|
|
150
160
|
dt.select.blurable(blurable);
|
|
151
161
|
dt.select.toggleable(toggleable);
|
|
152
162
|
dt.select.info(info);
|
|
163
|
+
dt.select.keys(keys);
|
|
164
|
+
dt.select.selectable(selectable);
|
|
153
165
|
ctx._select.className = className;
|
|
154
166
|
|
|
155
167
|
// If the init options haven't enabled select, but there is a selectable
|
|
@@ -159,11 +171,9 @@ DataTable.select.init = function (dt) {
|
|
|
159
171
|
}
|
|
160
172
|
|
|
161
173
|
// Insert a checkbox into the header if needed - might need to wait
|
|
162
|
-
// for init complete
|
|
174
|
+
// for init complete
|
|
163
175
|
if (headerCheckbox || headerCheckbox === 'select-page' || headerCheckbox === 'select-all') {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
dt.on('init', function () {
|
|
176
|
+
dt.ready(function () {
|
|
167
177
|
initCheckboxHeader(dt, headerCheckbox);
|
|
168
178
|
});
|
|
169
179
|
}
|
|
@@ -530,9 +540,17 @@ function info(api, node) {
|
|
|
530
540
|
return;
|
|
531
541
|
}
|
|
532
542
|
|
|
533
|
-
var
|
|
534
|
-
var
|
|
535
|
-
var
|
|
543
|
+
var ctx = api.settings()[0];
|
|
544
|
+
var rowSetLength = ctx._select_set.length;
|
|
545
|
+
var rows = rowSetLength ? rowSetLength : api.rows({ selected: true }).count();
|
|
546
|
+
var columns = api.columns({ selected: true }).count();
|
|
547
|
+
var cells = api.cells({ selected: true }).count();
|
|
548
|
+
|
|
549
|
+
// If subtractive selection, then we need to take the number of rows and
|
|
550
|
+
// subtract those that have been deselected
|
|
551
|
+
if (ctx._select_mode === 'subtractive') {
|
|
552
|
+
rows = api.page.info().recordsDisplay - rowSetLength;
|
|
553
|
+
}
|
|
536
554
|
|
|
537
555
|
var add = function (el, name, num) {
|
|
538
556
|
el.append(
|
|
@@ -572,7 +590,8 @@ function info(api, node) {
|
|
|
572
590
|
* @param {*} headerCheckbox the header checkbox option
|
|
573
591
|
*/
|
|
574
592
|
function initCheckboxHeader( dt, headerCheckbox ) {
|
|
575
|
-
var
|
|
593
|
+
var dtSettings = dt.settings()[0];
|
|
594
|
+
var dtInternalColumns = dtSettings.aoColumns;
|
|
576
595
|
|
|
577
596
|
// Find any checkbox column(s)
|
|
578
597
|
dt.columns().iterator('column', function (s, idx) {
|
|
@@ -596,33 +615,37 @@ function initCheckboxHeader( dt, headerCheckbox ) {
|
|
|
596
615
|
.on('change', function () {
|
|
597
616
|
if (this.checked) {
|
|
598
617
|
if (headerCheckbox == 'select-page') {
|
|
599
|
-
dt.rows({page: 'current'}).select()
|
|
600
|
-
}
|
|
618
|
+
dt.rows({page: 'current'}).select();
|
|
619
|
+
}
|
|
620
|
+
else {
|
|
601
621
|
dt.rows({search: 'applied'}).select();
|
|
602
622
|
}
|
|
603
623
|
}
|
|
604
624
|
else {
|
|
605
|
-
|
|
625
|
+
if (headerCheckbox == 'select-page') {
|
|
626
|
+
dt.rows({page: 'current', selected: true}).deselect();
|
|
627
|
+
}
|
|
628
|
+
else {
|
|
629
|
+
dt.rows({selected: true}).deselect();
|
|
630
|
+
}
|
|
606
631
|
}
|
|
607
632
|
})
|
|
608
633
|
.on('click', function (e) {
|
|
609
634
|
e.stopPropagation();
|
|
610
635
|
});
|
|
611
|
-
|
|
636
|
+
|
|
612
637
|
// Update the header checkbox's state when the selection in the
|
|
613
638
|
// table changes
|
|
614
639
|
dt.on('draw select deselect', function (e, pass, type) {
|
|
615
640
|
if (type === 'row' || ! type) {
|
|
616
|
-
var
|
|
617
|
-
var search = dt.rows({search: 'applied', selected: true}).count();
|
|
618
|
-
var available = headerCheckbox == 'select-page' ? dt.rows({page: 'current'}).count() : dt.rows({search: 'applied'}).count();
|
|
641
|
+
var nums = headerCheckboxState(dt, headerCheckbox);
|
|
619
642
|
|
|
620
|
-
if (search && search <= count && search === available) {
|
|
643
|
+
if (nums.search && nums.search <= nums.count && nums.search === nums.available) {
|
|
621
644
|
input
|
|
622
645
|
.prop('checked', true)
|
|
623
646
|
.prop('indeterminate', false);
|
|
624
647
|
}
|
|
625
|
-
else if (search === 0 && count === 0) {
|
|
648
|
+
else if (nums.search === 0 && nums.count === 0) {
|
|
626
649
|
input
|
|
627
650
|
.prop('checked', false)
|
|
628
651
|
.prop('indeterminate', false);
|
|
@@ -638,6 +661,188 @@ function initCheckboxHeader( dt, headerCheckbox ) {
|
|
|
638
661
|
});
|
|
639
662
|
}
|
|
640
663
|
|
|
664
|
+
function keysSet(dt) {
|
|
665
|
+
var ctx = dt.settings()[0];
|
|
666
|
+
var flag = ctx._select.keys;
|
|
667
|
+
var namespace = 'dts-keys-' + ctx.sTableId;
|
|
668
|
+
|
|
669
|
+
if (flag) {
|
|
670
|
+
// Need a tabindex of the `tr` elements to make them focusable by the browser
|
|
671
|
+
$(dt.rows({page: 'current'}).nodes()).attr('tabindex', 0);
|
|
672
|
+
|
|
673
|
+
dt.on('draw.' + namespace, function () {
|
|
674
|
+
$(dt.rows({page: 'current'}).nodes()).attr('tabindex', 0);
|
|
675
|
+
});
|
|
676
|
+
|
|
677
|
+
// Listen on document for tab, up and down
|
|
678
|
+
$(document).on('keydown.' + namespace, function (e) {
|
|
679
|
+
var key = e.keyCode;
|
|
680
|
+
var active = document.activeElement;
|
|
681
|
+
|
|
682
|
+
// Can't use e.key as it wasn't widely supported until 2017
|
|
683
|
+
// 9 Tab
|
|
684
|
+
// 13 Return
|
|
685
|
+
// 32 Space
|
|
686
|
+
// 38 ArrowUp
|
|
687
|
+
// 40 ArrowDown
|
|
688
|
+
if (! [9, 13, 32, 38, 40].includes(key)) {
|
|
689
|
+
return;
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
var nodes = dt.rows({page: 'current'}).nodes().toArray();
|
|
693
|
+
var idx = nodes.indexOf(active);
|
|
694
|
+
var preventDefault = true;
|
|
695
|
+
|
|
696
|
+
// Only take an action if a row has focus
|
|
697
|
+
if (idx === -1) {
|
|
698
|
+
return;
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
if (key === 9) {
|
|
702
|
+
// Tab focus change
|
|
703
|
+
if (e.shift === false && idx === nodes.length - 1) {
|
|
704
|
+
keysPageDown(dt);
|
|
705
|
+
}
|
|
706
|
+
else if (e.shift === true && idx === 0) {
|
|
707
|
+
keysPageUp(dt);
|
|
708
|
+
}
|
|
709
|
+
else {
|
|
710
|
+
// Browser will do it for us
|
|
711
|
+
preventDefault = false;
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
else if (key === 13 || key === 32) {
|
|
715
|
+
// Row selection / deselection
|
|
716
|
+
var row = dt.row(active);
|
|
717
|
+
|
|
718
|
+
if (row.selected()) {
|
|
719
|
+
row.deselect();
|
|
720
|
+
}
|
|
721
|
+
else {
|
|
722
|
+
row.select();
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
else if (key === 38) {
|
|
726
|
+
// Move up
|
|
727
|
+
if (idx > 0) {
|
|
728
|
+
nodes[idx-1].focus();
|
|
729
|
+
}
|
|
730
|
+
else {
|
|
731
|
+
keysPageUp(dt);
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
else {
|
|
735
|
+
// Move down
|
|
736
|
+
if (idx < nodes.length -1) {
|
|
737
|
+
nodes[idx+1].focus();
|
|
738
|
+
}
|
|
739
|
+
else {
|
|
740
|
+
keysPageDown(dt);
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
if (preventDefault) {
|
|
745
|
+
e.stopPropagation();
|
|
746
|
+
e.preventDefault();
|
|
747
|
+
}
|
|
748
|
+
});
|
|
749
|
+
}
|
|
750
|
+
else {
|
|
751
|
+
// Stop the rows from being able to gain focus
|
|
752
|
+
$(dt.rows().nodes()).removeAttr('tabindex');
|
|
753
|
+
|
|
754
|
+
// Nuke events
|
|
755
|
+
dt.off('draw.' + namespace);
|
|
756
|
+
$(document).off('keydown.' + namespace);
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
/**
|
|
761
|
+
* Change to the next page and focus on the first row
|
|
762
|
+
*
|
|
763
|
+
* @param {DataTable.Api} dt DataTable instance
|
|
764
|
+
*/
|
|
765
|
+
function keysPageDown(dt) {
|
|
766
|
+
// Is there another page to turn to?
|
|
767
|
+
var info = dt.page.info();
|
|
768
|
+
|
|
769
|
+
if (info.page < info.pages - 1) {
|
|
770
|
+
dt
|
|
771
|
+
.one('draw', function () {
|
|
772
|
+
dt.row(':first-child').node().focus();
|
|
773
|
+
})
|
|
774
|
+
.page('next')
|
|
775
|
+
.draw(false);
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
/**
|
|
780
|
+
* Change to the previous page and focus on the last row
|
|
781
|
+
*
|
|
782
|
+
* @param {DataTable.Api} dt DataTable instance
|
|
783
|
+
*/
|
|
784
|
+
function keysPageUp(dt) {
|
|
785
|
+
// Is there another page to turn to?
|
|
786
|
+
var info = dt.page.info();
|
|
787
|
+
|
|
788
|
+
if (info.page > 0) {
|
|
789
|
+
dt
|
|
790
|
+
.one('draw', function () {
|
|
791
|
+
dt.row(':last-child').node().focus();
|
|
792
|
+
})
|
|
793
|
+
.page('previous')
|
|
794
|
+
.draw(false);
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
/**
|
|
799
|
+
* Determine the counts used to define the header checkbox's state
|
|
800
|
+
*
|
|
801
|
+
* @param {*} dt DT API
|
|
802
|
+
* @param {*} headerCheckbox Configuration for what the header checkbox does
|
|
803
|
+
* @returns Counts object
|
|
804
|
+
*/
|
|
805
|
+
function headerCheckboxState(dt, headerCheckbox) {
|
|
806
|
+
var ctx = dt.settings()[0];
|
|
807
|
+
var selectable = ctx._select.selectable;
|
|
808
|
+
var available = 0;
|
|
809
|
+
var count = headerCheckbox == 'select-page'
|
|
810
|
+
? dt.rows({page: 'current', selected: true}).count()
|
|
811
|
+
: dt.rows({selected: true}).count();
|
|
812
|
+
var search = headerCheckbox == 'select-page'
|
|
813
|
+
? dt.rows({page: 'current', selected: true}).count()
|
|
814
|
+
: dt.rows({search: 'applied', selected: true}).count();
|
|
815
|
+
|
|
816
|
+
if (! selectable) {
|
|
817
|
+
available = headerCheckbox == 'select-page'
|
|
818
|
+
? dt.rows({page: 'current'}).count()
|
|
819
|
+
: dt.rows({search: 'applied'}).count();
|
|
820
|
+
}
|
|
821
|
+
else {
|
|
822
|
+
// Need to count how many rows are actually selectable to know if all selectable
|
|
823
|
+
// rows are selected or not
|
|
824
|
+
var indexes = headerCheckbox == 'select-page'
|
|
825
|
+
? dt.rows({page: 'current'}).indexes()
|
|
826
|
+
: dt.rows({search: 'applied'}).indexes();
|
|
827
|
+
|
|
828
|
+
for (var i=0 ; i<indexes.length ; i++) {
|
|
829
|
+
// For speed I use the internal DataTables object.
|
|
830
|
+
var rowInternal = ctx.aoData[indexes[i]];
|
|
831
|
+
var result = selectable(rowInternal._aData, rowInternal.nTr, indexes[i]);
|
|
832
|
+
|
|
833
|
+
if (result) {
|
|
834
|
+
available++;
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
return {
|
|
840
|
+
available: available,
|
|
841
|
+
count: count,
|
|
842
|
+
search: search
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
|
|
641
846
|
/**
|
|
642
847
|
* Initialisation of a new table. Attach event handlers and callbacks to allow
|
|
643
848
|
* Select to operate correctly.
|
|
@@ -652,6 +857,12 @@ function init(ctx) {
|
|
|
652
857
|
var api = new DataTable.Api(ctx);
|
|
653
858
|
ctx._select_init = true;
|
|
654
859
|
|
|
860
|
+
// When `additive` then `_select_set` contains a list of the row ids that
|
|
861
|
+
// are selected. If `subtractive` then all rows are selected, except those
|
|
862
|
+
// in `_select_set`, which is a list of ids.
|
|
863
|
+
ctx._select_mode = 'additive';
|
|
864
|
+
ctx._select_set = [];
|
|
865
|
+
|
|
655
866
|
// Row callback so that classes can be added to rows and cells if the item
|
|
656
867
|
// was selected before the element was created. This will happen with the
|
|
657
868
|
// `deferRender` option enabled.
|
|
@@ -662,9 +873,16 @@ function init(ctx) {
|
|
|
662
873
|
ctx.aoRowCreatedCallback.push(function (row, data, index) {
|
|
663
874
|
var i, ien;
|
|
664
875
|
var d = ctx.aoData[index];
|
|
876
|
+
var id = api.row(index).id();
|
|
665
877
|
|
|
666
878
|
// Row
|
|
667
|
-
if (
|
|
879
|
+
if (
|
|
880
|
+
d._select_selected ||
|
|
881
|
+
(ctx._select_mode === 'additive' && ctx._select_set.includes(id)) ||
|
|
882
|
+
(ctx._select_mode === 'subtractive' && ! ctx._select_set.includes(id))
|
|
883
|
+
) {
|
|
884
|
+
d._select_selected = true;
|
|
885
|
+
|
|
668
886
|
$(row)
|
|
669
887
|
.addClass(ctx._select.className)
|
|
670
888
|
.find('input.' + checkboxClass(true)).prop('checked', true);
|
|
@@ -683,46 +901,7 @@ function init(ctx) {
|
|
|
683
901
|
}
|
|
684
902
|
);
|
|
685
903
|
|
|
686
|
-
|
|
687
|
-
// if there is an rowId (i.e. a unique value to identify each row with)
|
|
688
|
-
api.on('preXhr.dt.dtSelect', function (e, settings) {
|
|
689
|
-
if (settings !== api.settings()[0]) {
|
|
690
|
-
// Not triggered by our DataTable!
|
|
691
|
-
return;
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
// note that column selection doesn't need to be cached and then
|
|
695
|
-
// reselected, as they are already selected
|
|
696
|
-
var rows = api
|
|
697
|
-
.rows({ selected: true })
|
|
698
|
-
.ids(true)
|
|
699
|
-
.filter(function (d) {
|
|
700
|
-
return d !== undefined;
|
|
701
|
-
});
|
|
702
|
-
|
|
703
|
-
var cells = api
|
|
704
|
-
.cells({ selected: true })
|
|
705
|
-
.eq(0)
|
|
706
|
-
.map(function (cellIdx) {
|
|
707
|
-
var id = api.row(cellIdx.row).id(true);
|
|
708
|
-
return id ? { row: id, column: cellIdx.column } : undefined;
|
|
709
|
-
})
|
|
710
|
-
.filter(function (d) {
|
|
711
|
-
return d !== undefined;
|
|
712
|
-
});
|
|
713
|
-
|
|
714
|
-
// On the next draw, reselect the currently selected items
|
|
715
|
-
api.one('draw.dt.dtSelect', function () {
|
|
716
|
-
api.rows(rows).select();
|
|
717
|
-
|
|
718
|
-
// `cells` is not a cell index selector, so it needs a loop
|
|
719
|
-
if (cells.any()) {
|
|
720
|
-
cells.each(function (id) {
|
|
721
|
-
api.cells(id.row, id.column).select();
|
|
722
|
-
});
|
|
723
|
-
}
|
|
724
|
-
});
|
|
725
|
-
});
|
|
904
|
+
_cumulativeEvents(api);
|
|
726
905
|
|
|
727
906
|
// Update the table information element with selected item summary
|
|
728
907
|
api.on('info.dt', function (e, ctx, node) {
|
|
@@ -895,6 +1074,73 @@ function _safeId(node) {
|
|
|
895
1074
|
return node.id.replace(/[^a-zA-Z0-9\-\_]/g, '-');
|
|
896
1075
|
}
|
|
897
1076
|
|
|
1077
|
+
/**
|
|
1078
|
+
* Set up event handlers for cumulative selection
|
|
1079
|
+
*
|
|
1080
|
+
* @param {*} api DT API instance
|
|
1081
|
+
*/
|
|
1082
|
+
function _cumulativeEvents(api) {
|
|
1083
|
+
// Add event listeners to add / remove from the _select_set
|
|
1084
|
+
api.on('select', function (e, dt, type, indexes) {
|
|
1085
|
+
// Only support for rows at the moment
|
|
1086
|
+
if (type !== 'row') {
|
|
1087
|
+
return;
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
var ctx = api.settings()[0];
|
|
1091
|
+
|
|
1092
|
+
if (ctx._select_mode === 'additive') {
|
|
1093
|
+
// Add row to the selection list if it isn't already there
|
|
1094
|
+
_add(api, ctx._select_set, indexes);
|
|
1095
|
+
}
|
|
1096
|
+
else {
|
|
1097
|
+
// Subtractive - if a row is selected it should not in the list
|
|
1098
|
+
// as in subtractive mode the list gives the rows which are not
|
|
1099
|
+
// selected
|
|
1100
|
+
_remove(api, ctx._select_set, indexes);
|
|
1101
|
+
}
|
|
1102
|
+
});
|
|
1103
|
+
|
|
1104
|
+
api.on('deselect', function (e, dt, type, indexes) {
|
|
1105
|
+
// Only support for rows at the moment
|
|
1106
|
+
if (type !== 'row') {
|
|
1107
|
+
return;
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
var ctx = api.settings()[0];
|
|
1111
|
+
|
|
1112
|
+
if (ctx._select_mode === 'additive') {
|
|
1113
|
+
// List is of those rows selected, so remove it
|
|
1114
|
+
_remove(api, ctx._select_set, indexes);
|
|
1115
|
+
}
|
|
1116
|
+
else {
|
|
1117
|
+
// List is of rows which are deselected, so add it!
|
|
1118
|
+
_add(api, ctx._select_set, indexes);
|
|
1119
|
+
}
|
|
1120
|
+
});
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
function _add(api, arr, indexes) {
|
|
1124
|
+
for (var i=0 ; i<indexes.length ; i++) {
|
|
1125
|
+
var id = api.row(indexes[i]).id();
|
|
1126
|
+
|
|
1127
|
+
if (id && id !== 'undefined' && ! arr.includes(id)) {
|
|
1128
|
+
arr.push(id);
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
function _remove(api, arr, indexes) {
|
|
1134
|
+
for (var i=0 ; i<indexes.length ; i++) {
|
|
1135
|
+
var id = api.row(indexes[i]).id();
|
|
1136
|
+
var idx = arr.indexOf(id);
|
|
1137
|
+
|
|
1138
|
+
if (idx !== -1) {
|
|
1139
|
+
arr.splice(idx, 1);
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
|
|
898
1144
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
899
1145
|
* DataTables selectors
|
|
900
1146
|
*/
|
|
@@ -1022,6 +1268,22 @@ apiRegister('select.items()', function (items) {
|
|
|
1022
1268
|
});
|
|
1023
1269
|
});
|
|
1024
1270
|
|
|
1271
|
+
apiRegister('select.keys()', function (flag) {
|
|
1272
|
+
if (flag === undefined) {
|
|
1273
|
+
return this.context[0]._select.keys;
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
return this.iterator('table', function (ctx) {
|
|
1277
|
+
if (!ctx._select) {
|
|
1278
|
+
DataTable.select.init(new DataTable.Api(ctx));
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1281
|
+
ctx._select.keys = flag;
|
|
1282
|
+
|
|
1283
|
+
keysSet(new DataTable.Api(ctx));
|
|
1284
|
+
});
|
|
1285
|
+
});
|
|
1286
|
+
|
|
1025
1287
|
// Takes effect from the _next_ selection. None disables future selection, but
|
|
1026
1288
|
// does not clear the current selection. Use the `deselect` methods for that
|
|
1027
1289
|
apiRegister('select.style()', function (style) {
|
|
@@ -1043,10 +1305,15 @@ apiRegister('select.style()', function (style) {
|
|
|
1043
1305
|
// Add / remove mouse event handlers. They aren't required when only
|
|
1044
1306
|
// API selection is available
|
|
1045
1307
|
var dt = new DataTable.Api(ctx);
|
|
1046
|
-
disableMouseSelection(dt);
|
|
1047
1308
|
|
|
1048
1309
|
if (style !== 'api') {
|
|
1049
|
-
|
|
1310
|
+
dt.ready(function () {
|
|
1311
|
+
disableMouseSelection(dt);
|
|
1312
|
+
enableMouseSelection(dt);
|
|
1313
|
+
});
|
|
1314
|
+
}
|
|
1315
|
+
else {
|
|
1316
|
+
disableMouseSelection(dt);
|
|
1050
1317
|
}
|
|
1051
1318
|
|
|
1052
1319
|
eventTrigger(new DataTable.Api(ctx), 'selectStyle', [style]);
|
|
@@ -1059,16 +1326,36 @@ apiRegister('select.selector()', function (selector) {
|
|
|
1059
1326
|
}
|
|
1060
1327
|
|
|
1061
1328
|
return this.iterator('table', function (ctx) {
|
|
1062
|
-
|
|
1329
|
+
var dt = new DataTable.Api(ctx);
|
|
1330
|
+
var style = ctx._select.style;
|
|
1331
|
+
|
|
1332
|
+
disableMouseSelection(dt);
|
|
1063
1333
|
|
|
1064
1334
|
ctx._select.selector = selector;
|
|
1065
1335
|
|
|
1066
|
-
if (
|
|
1067
|
-
|
|
1336
|
+
if (style && style !== 'api') {
|
|
1337
|
+
dt.ready(function () {
|
|
1338
|
+
disableMouseSelection(dt);
|
|
1339
|
+
enableMouseSelection(dt);
|
|
1340
|
+
});
|
|
1341
|
+
}
|
|
1342
|
+
else {
|
|
1343
|
+
disableMouseSelection(dt);
|
|
1068
1344
|
}
|
|
1069
1345
|
});
|
|
1070
1346
|
});
|
|
1071
1347
|
|
|
1348
|
+
apiRegister('select.selectable()', function (set) {
|
|
1349
|
+
let ctx = this.context[0];
|
|
1350
|
+
|
|
1351
|
+
if (set) {
|
|
1352
|
+
ctx._select.selectable = set;
|
|
1353
|
+
return this;
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1356
|
+
return ctx._select.selectable;
|
|
1357
|
+
});
|
|
1358
|
+
|
|
1072
1359
|
apiRegister('select.last()', function (set) {
|
|
1073
1360
|
let ctx = this.context[0];
|
|
1074
1361
|
|
|
@@ -1080,8 +1367,50 @@ apiRegister('select.last()', function (set) {
|
|
|
1080
1367
|
return ctx._select_lastCell;
|
|
1081
1368
|
});
|
|
1082
1369
|
|
|
1370
|
+
apiRegister('select.cumulative()', function (mode) {
|
|
1371
|
+
if (mode) {
|
|
1372
|
+
return this.iterator('table', function (ctx) {
|
|
1373
|
+
if (ctx._select_mode === mode) {
|
|
1374
|
+
return;
|
|
1375
|
+
}
|
|
1376
|
+
|
|
1377
|
+
var dt = new DataTable.Api(ctx);
|
|
1378
|
+
|
|
1379
|
+
// Convert from the current mode, to the new
|
|
1380
|
+
if (mode === 'subtractive') {
|
|
1381
|
+
// For subtractive mode we track the row ids which are not selected
|
|
1382
|
+
var unselected = dt.rows({selected: false}).ids().toArray();
|
|
1383
|
+
|
|
1384
|
+
ctx._select_mode = mode;
|
|
1385
|
+
ctx._select_set.length = 0;
|
|
1386
|
+
ctx._select_set.push.apply(ctx._select_set, unselected);
|
|
1387
|
+
}
|
|
1388
|
+
else {
|
|
1389
|
+
// Switching to additive, so selected rows are to be used
|
|
1390
|
+
var selected = dt.rows({selected: true}).ids().toArray();
|
|
1391
|
+
|
|
1392
|
+
ctx._select_mode = mode;
|
|
1393
|
+
ctx._select_set.length = 0;
|
|
1394
|
+
ctx._select_set.push.apply(ctx._select_set, selected);
|
|
1395
|
+
}
|
|
1396
|
+
}).draw(false);
|
|
1397
|
+
}
|
|
1398
|
+
|
|
1399
|
+
let ctx = this.context[0];
|
|
1400
|
+
|
|
1401
|
+
if (ctx && ctx._select_set) {
|
|
1402
|
+
return {
|
|
1403
|
+
mode: ctx._select_mode,
|
|
1404
|
+
rows: ctx._select_set
|
|
1405
|
+
};
|
|
1406
|
+
}
|
|
1407
|
+
|
|
1408
|
+
return null;
|
|
1409
|
+
});
|
|
1410
|
+
|
|
1083
1411
|
apiRegisterPlural('rows().select()', 'row().select()', function (select) {
|
|
1084
1412
|
var api = this;
|
|
1413
|
+
var selectedIndexes = [];
|
|
1085
1414
|
|
|
1086
1415
|
if (select === false) {
|
|
1087
1416
|
return this.deselect();
|
|
@@ -1096,9 +1425,20 @@ apiRegisterPlural('rows().select()', 'row().select()', function (select) {
|
|
|
1096
1425
|
var dtData = ctx.aoData[idx];
|
|
1097
1426
|
var dtColumns = ctx.aoColumns;
|
|
1098
1427
|
|
|
1428
|
+
if (ctx._select.selectable) {
|
|
1429
|
+
var result = ctx._select.selectable(dtData._aData, dtData.nTr, idx);
|
|
1430
|
+
|
|
1431
|
+
if (result === false) {
|
|
1432
|
+
// Not selectable - do nothing
|
|
1433
|
+
return;
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1099
1437
|
$(dtData.nTr).addClass(ctx._select.className);
|
|
1100
1438
|
dtData._select_selected = true;
|
|
1101
1439
|
|
|
1440
|
+
selectedIndexes.push(idx);
|
|
1441
|
+
|
|
1102
1442
|
for (var i=0 ; i<dtColumns.length ; i++) {
|
|
1103
1443
|
var col = dtColumns[i];
|
|
1104
1444
|
|
|
@@ -1123,8 +1463,8 @@ apiRegisterPlural('rows().select()', 'row().select()', function (select) {
|
|
|
1123
1463
|
}
|
|
1124
1464
|
});
|
|
1125
1465
|
|
|
1126
|
-
this.iterator('table', function (
|
|
1127
|
-
eventTrigger(api, 'select', ['row',
|
|
1466
|
+
this.iterator('table', function (ct) {
|
|
1467
|
+
eventTrigger(api, 'select', ['row', selectedIndexes], true);
|
|
1128
1468
|
});
|
|
1129
1469
|
|
|
1130
1470
|
return this;
|
|
@@ -1140,6 +1480,22 @@ apiRegister('row().selected()', function () {
|
|
|
1140
1480
|
return false;
|
|
1141
1481
|
});
|
|
1142
1482
|
|
|
1483
|
+
apiRegister('row().focus()', function () {
|
|
1484
|
+
var ctx = this.context[0];
|
|
1485
|
+
|
|
1486
|
+
if (ctx && this.length && ctx.aoData[this[0]] && ctx.aoData[this[0]].nTr) {
|
|
1487
|
+
ctx.aoData[this[0]].nTr.focus();
|
|
1488
|
+
}
|
|
1489
|
+
});
|
|
1490
|
+
|
|
1491
|
+
apiRegister('row().blur()', function () {
|
|
1492
|
+
var ctx = this.context[0];
|
|
1493
|
+
|
|
1494
|
+
if (ctx && this.length && ctx.aoData[this[0]] && ctx.aoData[this[0]].nTr) {
|
|
1495
|
+
ctx.aoData[this[0]].nTr.blur();
|
|
1496
|
+
}
|
|
1497
|
+
});
|
|
1498
|
+
|
|
1143
1499
|
apiRegisterPlural('columns().select()', 'column().select()', function (select) {
|
|
1144
1500
|
var api = this;
|
|
1145
1501
|
|
|
@@ -1486,6 +1842,8 @@ $.each(['Row', 'Column', 'Cell'], function (i, item) {
|
|
|
1486
1842
|
init: function (dt) {
|
|
1487
1843
|
var that = this;
|
|
1488
1844
|
|
|
1845
|
+
this.active(dt.select.items() === lc);
|
|
1846
|
+
|
|
1489
1847
|
dt.on('selectItems.dt.DT', function (e, ctx, items) {
|
|
1490
1848
|
that.active(items === lc);
|
|
1491
1849
|
});
|
|
@@ -1536,8 +1894,18 @@ DataTable.render.select = function (valueProp, nameProp) {
|
|
|
1536
1894
|
var dtRow = meta.settings.aoData[meta.row];
|
|
1537
1895
|
var selected = dtRow._select_selected;
|
|
1538
1896
|
var ariaLabel = meta.settings.oLanguage.select.aria.rowCheckbox;
|
|
1897
|
+
var selectable = meta.settings._select.selectable;
|
|
1539
1898
|
|
|
1540
1899
|
if (type === 'display') {
|
|
1900
|
+
// Check if the row is selectable before showing the checkbox
|
|
1901
|
+
if (selectable) {
|
|
1902
|
+
var result = selectable(row, dtRow.nTr, meta.row);
|
|
1903
|
+
|
|
1904
|
+
if (result === false) {
|
|
1905
|
+
return '';
|
|
1906
|
+
}
|
|
1907
|
+
}
|
|
1908
|
+
|
|
1541
1909
|
return $('<input>')
|
|
1542
1910
|
.attr({
|
|
1543
1911
|
'aria-label': ariaLabel,
|
|
@@ -1596,11 +1964,10 @@ $.fn.DataTable.select = DataTable.select;
|
|
|
1596
1964
|
* Initialisation
|
|
1597
1965
|
*/
|
|
1598
1966
|
|
|
1599
|
-
// DataTables creation -
|
|
1600
|
-
//
|
|
1601
|
-
//
|
|
1602
|
-
|
|
1603
|
-
$(document).on('preInit.dt.dtSelect', function (e, ctx) {
|
|
1967
|
+
// DataTables creation - we need this to run _before_ data is read in, but
|
|
1968
|
+
// for backwards compat. we also run again on preInit. If it happens twice
|
|
1969
|
+
// it will simply do nothing the second time around.
|
|
1970
|
+
$(document).on('i18n.dt.dtSelect preInit.dt.dtSelect', function (e, ctx) {
|
|
1604
1971
|
if (e.namespace !== 'dt') {
|
|
1605
1972
|
return;
|
|
1606
1973
|
}
|