Associate an arbitrary data object with a row.
Associate an arbitrary data object with a row.
Hi,
I am defining a table with an 'edit/actions' column, that is to say that no data is actually displayed in this column except for buttons to 'Delete', 'Download' (just specific examples from my use case). The table is populated via AJAX.
The markup is quite simple and generic:
[code]
Name
Date
Size
Actions
[/code]
I am customizing this 'actions' column like so in aoColumnDefs:
[code]
// 'actions' column should be rendered differently
{ bSortable: false,
fnRender: function ( obj ) {
var b = "Delete";
b += "Download";
b += "Restore";
return b;
}, aTargets: [4] }
[/code]
I have also defined fnRowCallback to perform special processing on these button elements before each row is displayed:
[code]
// custom process each element before displaying it
fnRowCallback: function (nRow, aData, iDisplayIndex, iDisplayIndexFull) {
$('.delete_button', nRow).button({
text: false,
icons: { primary: 'ui-icon-trash' }
})
.click(function () {
// XXX need to actually delete the row from the DB. But I can't access the identifier.
$('#snapshots').dataTable().fnDeleteRow(nRow);
});
$('.download_button', nRow).button({
text: false,
icons: { primary: 'ui-icon-disk' }
}).click(function () {
// XXX the correct href should be "files/XYZ" where XYZ is some identifier in the meta data.
location.href = 'files/';
});
return nRow;
}
[/code]
In the above snippet, all I am doing is converting the button elements into jquery-ui's button widgets and attaching click handlers. Both the click handlers need to know which row they are acting on by virtue of knowing the database id or some other data not displayed in the table.
For completeness, I am also including my fnServerData definition:
[code]
// request data from the server and process it
fnServerData: function (sSource, aoData, fnCallback) {
$.getJSON(sSource, aoData, function (data) {
// mutate the dictionary into a 2D array as expected
// by the widget.
var data_pp = [];
$.each(data, function(i, item) {
// the last element is never displayed because of a custom fnRender definition for that column.
data_pp.push([item.name, item.date, item.size, '']);
});
fnCallback({ 'aaData': data_pp});
});
},
[/code]
The question is, how can I associate an arbitrary data object (say, dictionary) with each row which is NOT necessarily attached to a column (hidden or otherwise)?
I have searched the forums for quite a while. The work around that I found is to define a hidden column and associate
the data object with that column. Problem with that approach is in fnRowCallback, aData[0] is a string '[object Object]' and not really the object that I stored in the aaData array.
I hope this makes sense and that somebody has a clever idea to solve my problem.
I am defining a table with an 'edit/actions' column, that is to say that no data is actually displayed in this column except for buttons to 'Delete', 'Download' (just specific examples from my use case). The table is populated via AJAX.
The markup is quite simple and generic:
[code]
Name
Date
Size
Actions
[/code]
I am customizing this 'actions' column like so in aoColumnDefs:
[code]
// 'actions' column should be rendered differently
{ bSortable: false,
fnRender: function ( obj ) {
var b = "Delete";
b += "Download";
b += "Restore";
return b;
}, aTargets: [4] }
[/code]
I have also defined fnRowCallback to perform special processing on these button elements before each row is displayed:
[code]
// custom process each element before displaying it
fnRowCallback: function (nRow, aData, iDisplayIndex, iDisplayIndexFull) {
$('.delete_button', nRow).button({
text: false,
icons: { primary: 'ui-icon-trash' }
})
.click(function () {
// XXX need to actually delete the row from the DB. But I can't access the identifier.
$('#snapshots').dataTable().fnDeleteRow(nRow);
});
$('.download_button', nRow).button({
text: false,
icons: { primary: 'ui-icon-disk' }
}).click(function () {
// XXX the correct href should be "files/XYZ" where XYZ is some identifier in the meta data.
location.href = 'files/';
});
return nRow;
}
[/code]
In the above snippet, all I am doing is converting the button elements into jquery-ui's button widgets and attaching click handlers. Both the click handlers need to know which row they are acting on by virtue of knowing the database id or some other data not displayed in the table.
For completeness, I am also including my fnServerData definition:
[code]
// request data from the server and process it
fnServerData: function (sSource, aoData, fnCallback) {
$.getJSON(sSource, aoData, function (data) {
// mutate the dictionary into a 2D array as expected
// by the widget.
var data_pp = [];
$.each(data, function(i, item) {
// the last element is never displayed because of a custom fnRender definition for that column.
data_pp.push([item.name, item.date, item.size, '']);
});
fnCallback({ 'aaData': data_pp});
});
},
[/code]
The question is, how can I associate an arbitrary data object (say, dictionary) with each row which is NOT necessarily attached to a column (hidden or otherwise)?
I have searched the forums for quite a while. The work around that I found is to define a hidden column and associate
the data object with that column. Problem with that approach is in fnRowCallback, aData[0] is a string '[object Object]' and not really the object that I stored in the aaData array.
I hope this makes sense and that somebody has a clever idea to solve my problem.
This discussion has been closed.
Replies
I created a global array object to store that extra data for example:
[code]
var extraDataObj = []:
[/code]
Then i created an object with all the info i needed for example:
[code]
myRowObj = {
data1:"value1",
data2:"value2",
data3:"value3",
data4:"value4",
}
extraDataObj.push(myRowObj);
[/code]
But, additional to my extra data i needed to relate to that row, i created a uuid/guid to use as reference to it (there are a number of options for this... maybe you can make an ajax call to some server-side script that returns that UUID or use a pseudo-uuid created on pure JS like this one:
[code]
function guidGenerator() {
var S4 = function() {
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
};
return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
}
[/code]
Then you can create the number and use it in your object AND in your addition for the datatable, so in fully it would be something like this:
[code]
var myUUID = guidGenerator();
myRowObj = {
dataId:myUUID,
data1:"value1",
data2:"value2",
data3:"value3",
data4:"value4",
}
extraDataObj.push(myRowObj);
[/code]
Then in the same function, add the info to the datatable in a hidden column:
[code]
var rowsArr = new Array();
rowsArr.push([myUUID,"value1","value2","value3","value4"]);
myTable.fnAddData(rowsArr):
[/code]
Having that done, i can compare the UUID from my datatable row object with the UUID in my "extra info" Array (in this case extraDataObj), to help yourself you may add extra functionality to the Array prototype to find it:
[code]
Array.prototype.find = function(searchStr) {
var returnArray = false;
for (i=0; i
[code]
// Create a table with two columns.
var table = $('#someId').dataTable({
aoColumns: [
{mDataProp: 'colOne'},
{mDataProp: 'colTwo'}
]
});
// Add data to the table. Datatables wont do anything with the
// extraStuff because it doesn't have a column to put it in but
// it still stores it internally.
table.fnAddData([
{colOne: 'A', colTwo: 'B', extraStuff: {someProperty: 'somevalue'}},
{colOne: 'C', colTwo: 'D', extraStuff: {someProperty: 'someOtherValue'}}
]);
// Get the data used to generate the 2nd row (indexes start at 0).
// You can also look up data using the tr element.
// The api docs describe fnGetData.
var extraData = table.fnGetData(1).extraStuff;
// Logs "someOtherValue".
console.log(extraData.someProperty);
[/code]
I haven't tested that particular piece of code, but I am using this approach in an application I'm writing at the moment and it's working fine. As I understand it extraStuff could be anything from an object to a function to an array.
Allan