Create custom cell content using callback

Create custom cell content using callback

santjagosantjago Posts: 5Questions: 0Answers: 0
edited December 2013 in DataTables 1.9
I've a problem generating custom contents for some cells when making fnUpdate.

Here's table definition:
[code]
defaultsTable = $('table.defaults-table').dataTable({
"bProcessing": true,
"bLengthChange": false,
"iDisplayLength": 10,
"sAjaxSource": "{{ url_for('.json_get_data', aid=0) }}",
"sAjaxDataProp": "data",
"aoColumns": [
{"mData": "country", "fnCreatedCell": buttonCell},
{"mData": "operators", "fnCreatedCell": buttonCell},
{"mData": "platform", "fnCreatedCell": valueCell},
{"mData": "type", "fnCreatedCell": valueCell},
{"mData": "amount", "fnCreatedCell": createCell},
{"mData": "id", "fnCreatedCell": actionCell}
]
});

function createCell(nTd, sData, oData, iRow, iCol) {
$(nTd).addClass('align-center');
}
function valueCell(nTd, sData, oData, iRow, iCol) {
createCell(nTd, sData, oData, iRow, iCol);
$(nTd).text(sData.name);
}

function actionCell(nTd, sData, oData, iRow, iCol) {
createCell(nTd, sData, oData, iRow, iCol);
var removeUrlTpl = '{{ url_for('.json_delete_rate', rid=".RID.") }}';
var removeAction = $('');
removeAction.text('Delete');
removeAction.click(function() { removeRow($(this).parent().parent()); });

//var editUrlTpl = '{{ url_for('.json_edit_rate', rid=".RID.") }}';
var editAction = $('');
editAction.text('Edit');
editAction.click(function() { editRow($(this).parent().parent()); });

editAction.appendTo($(nTd).empty());
removeAction.appendTo($(nTd));
}

function buttonCell(nTd, sData, oData, iRow, iCol) {
createCell(nTd, sData, oData, iRow, iCol);
var button = $('');
var toolTip = [];
for (var i = 0; i < sData.length; i++) {
toolTip[toolTip.length] = sData[i].name + (sData[i].hasOwnProperty('code') ? ' (' + sData[i].code + ')' : '');
}
button.data('content', toolTip);
button.html('See tooltip');
button.popover();
button.appendTo($(nTd).empty());
}

[/code]

So, this code works perfectly on table first render. But when I need to update a table row (and guess the right way is to call fnUpdate) the table contents of the given row messes up.

I've also tried to update the code to use "mRender" property of columns definitions (so createCell is called in fnCreatedCell and all other funcs are bound to mRender. That only works when mRender bound function returns textual data. As soon as mRender.call() returns jQuery object the result is also a mess.

So what's the proper way to use custom cell contents on both first render and row/cell update?

I've read already some discussions on fnCreatedCell problems, someone made an advice to call fnCreatedCell manually with no sample though.

Replies

  • allanallan Posts: 63,208Questions: 1Answers: 10,415 Site admin
    fnCreatedCell only runs when the cell is first created - not when its content is updated. If you update the cell content, then it is assumed that you have a reference to the cell and thus can run the same functions to format the data on that cell again - perhaps in a wrapper function.

    That how it currently works at least.

    I've been thinking about how to resolve this, and haven't yet come up with a good solution - fnCreatedCell should run only when the sell is created (as per the name), but perhaps there should be a `cellModified` option as well, which would run for both updated and for created...

    Allan
  • santjagosantjago Posts: 5Questions: 0Answers: 0
    Well, I'm not updating each cell individually. I just get new data structure via AJAX and then call [code]
    table.fnUpdate(data.data, i, undefined, true);
    [/code]
    where 'i' is row index in overall dataset. Could you provide some example on how do I retreive particular row, iterate through it's cells and retrieve particular cell definitions such as 'mData', 'fnCreatedCell', etc.? I'm troubled finding a method to retrieve aoColumns definition for particular column at runtime.
  • allanallan Posts: 63,208Questions: 1Answers: 10,415 Site admin
    I think `fnGetNodes( i );` should do it. That will give you the `tr` element for the row, from which you can use standard jQuery on it to iterate over the cells.

    Allan
  • santjagosantjago Posts: 5Questions: 0Answers: 0
    edited December 2013
    But how do I retrieve mData mapping having an exact cell as an object. Right now I have:
    [code]
    var cell = $(someCell);
    var rowData = data.data;
    var row = cell.parent();
    var table = dataTable(...);
    [/code]

    Making manual once-again data property-to-cell map over this iteration is not a good idea, I guess.
  • allanallan Posts: 63,208Questions: 1Answers: 10,415 Site admin
    edited December 2013
    fnGetData for the cell will return the data set by mData .

    Allan
  • santjagosantjago Posts: 5Questions: 0Answers: 0
    That's not what I mean. In my case some cells are mapped to buttonCell(), some to valueCell() and so on. How do I get that mapping having retrieved a cell?
  • santjagosantjago Posts: 5Questions: 0Answers: 0
    Oh... Finally found the way:
    [code]
    table.fnUpdate(data.data, i);
    var row = table.fnGetNodes(i);
    $(row).find('td').each(function(index) {
    table.fnSettings().aoColumns[index].fnCreatedCell($(this), table.fnGetData($(this).get(0)), data.data);
    });
    [/code]

    Also have to mention: This is somehow unclear that one must use jQuery.get() prior to passing objects to fn* methods of dataTables. You could have done this work transparently and safe-to-use in dataTables.
  • allanallan Posts: 63,208Questions: 1Answers: 10,415 Site admin
    Yup - not disagreeing with you at all! The new API in DataTables 1.10 will accept jQuery objects as well :-). In fact, the new API is massively better than the on fn* methods... (imho of course!)

    Allan
This discussion has been closed.