Multi select with Ctrl+Click and Shift+Click
Multi select with Ctrl+Click and Shift+Click
stwi
Posts: 10Questions: 0Answers: 0
Hi,
For my app I need a DataTable where multiple line selection is done via Ctrl+Click instead of the standard way implemented currently by TableTools.
With some fiddling around I came up with the following code, where you must Ctrl-Click to add a line to the multiple selection. Normal single click will select only the one line that you clicked on (like eg. Windows explorer does it).
[code]oTableTools: {
"sRowSelect": "multi",
"fnPreRowSelect": function(e, nodes) {
if (e) {
mySelectList = myDeselectList = null;
if (!e.ctrlKey) {
myDeselectList = this.fnGetSelected();
mySelectList = nodes;
}
}
return true;
},
"fnRowSelected": function(nodes) {
if (myDeselectList) {
var nodeList = myDeselectList;
myDeselectList = null;
this.fnDeselect(nodeList);
}
},
"fnRowDeselected": function(nodes) {
if (myDeselectList) {
var nodeList = myDeselectList;
myDeselectList = null;
this.fnDeselect(nodeList);
}
if (mySelectList) {
var nodeList = mySelectList;
mySelectList = null;
this.fnSelect (nodeList);
}
},
},[/code]
I hope its a good solution and helps someone.
I still need a solution for proper "Shift-Click" behaviour, but I expect this to be considerable more complex, as it involves determining the table lines in between the last clicked position and the current clicked position. My table uses "bDeferRender: true" so I can not perform DOM based searches for 'tr' elements. If anyone knows a good solution then by all means post it here.
Regards,
Stephan
For my app I need a DataTable where multiple line selection is done via Ctrl+Click instead of the standard way implemented currently by TableTools.
With some fiddling around I came up with the following code, where you must Ctrl-Click to add a line to the multiple selection. Normal single click will select only the one line that you clicked on (like eg. Windows explorer does it).
[code]oTableTools: {
"sRowSelect": "multi",
"fnPreRowSelect": function(e, nodes) {
if (e) {
mySelectList = myDeselectList = null;
if (!e.ctrlKey) {
myDeselectList = this.fnGetSelected();
mySelectList = nodes;
}
}
return true;
},
"fnRowSelected": function(nodes) {
if (myDeselectList) {
var nodeList = myDeselectList;
myDeselectList = null;
this.fnDeselect(nodeList);
}
},
"fnRowDeselected": function(nodes) {
if (myDeselectList) {
var nodeList = myDeselectList;
myDeselectList = null;
this.fnDeselect(nodeList);
}
if (mySelectList) {
var nodeList = mySelectList;
mySelectList = null;
this.fnSelect (nodeList);
}
},
},[/code]
I hope its a good solution and helps someone.
I still need a solution for proper "Shift-Click" behaviour, but I expect this to be considerable more complex, as it involves determining the table lines in between the last clicked position and the current clicked position. My table uses "bDeferRender: true" so I can not perform DOM based searches for 'tr' elements. If anyone knows a good solution then by all means post it here.
Regards,
Stephan
This discussion has been closed.
Replies
Shift click select is something I want to add in TableTools v3 (which in fairness is a good way out with the number of things to do on DataTables first growing :-) ).
Allan
Well, here it is: a working implementation of Shift+Click (and also Ctrl+Click) select using only the DataTables API :-)
It might not (yet) be perfect, but I've done several test and it looks quite good and stable. My code mimics the Shift+Click and Ctrl+Click behaviour of Windows file explorer ... as closely as possible.
Within your table initialisation options place this block for "TableTools" initialisation:
[code]oTableTools: {
"sRowSelect": "multi",
"fnPreRowSelect": function(e, nodes, isSelect) {
if (e) {
mySelectList = myDeselectList = null;
if (e.shiftKey && nodes.length == 1) {
myDeselectList = this.fnGetSelected();
mySelectList = myGetRangeOfRows(cgTableObject, myLastSelection, nodes[0]);
} else {
myLastSelection = nodes[0];
if (!e.ctrlKey) {
myDeselectList = this.fnGetSelected();
if (!isSelect) {
mySelectList = nodes;
}
}
}
}
return true;
},
"fnRowSelected": mySelectEventHandler,
"fnRowDeselected": mySelectEventHandler,
},
[/code]
Within your JAVASCRIPT code place these two functions:
[code]function mySelectEventHandler(nodes) {
if (myDeselectList) {
var nodeList = myDeselectList;
myDeselectList = null;
this.fnDeselect(nodeList);
}
if (mySelectList) {
var nodeList = mySelectList;
mySelectList = null;
this.fnSelect (nodeList);
}
}
function myGetRangeOfRows(oDataTable, fromNode, toNode) {
var
fromPos = oDataTable.fnGetPosition(fromNode),
toPos = oDataTable.fnGetPosition(toNode);
oSettings = oDataTable.fnSettings(),
fromIndex = $.inArray(fromPos, oSettings.aiDisplay),
toIndex = $.inArray(toPos, oSettings.aiDisplay),
result = [];
if (fromIndex >= 0 && toIndex >= 0 && toIndex != fromIndex) {
for (var i=Math.min(fromIndex,toIndex); i < Math.max(fromIndex,toIndex); i++) {
var dataIndex = oSettings.aiDisplay[i];
result.push(oSettings.aoData[dataIndex].nTr);
}
}
return result.length>0?result:null;
}
[/code]
The code works independant of sorting and filtering and is independant of whether the data comes from a converted HTML table or from JSON data array. My application uses JSON data array, so thats what I tested it with. I do not have the possibility to test against an AJAX data source, so I can not make any guaranties for that. It might be nice if someone else could test this.
Some notes on the code:
* sadly at this point I do not have a full standalone piece of sample code for you, so you'll have to do some (minor) copy/pasting and renaming yourself
* at one point you will see "cgTableObject". This is the object where I store the reference to my actual DataTable => rename it to your table object (or use jQuery),
* dont forget to declare the "mySelectList" etc. variables somewhere, maybe even rename them to something nicer,
* "mySelectEventHandler" has become a separate function because I use it twice in absolutely identical form
* "myGetRangeOfRows" can be condensed down to a smaller form, but thats code cleanup for later, the present form isgeared towards being debug friendly
Regards,
Stephan