Modifying cell content before showing

Modifying cell content before showing

marlarmarlar Posts: 11Questions: 0Answers: 0
edited March 2009 in General
Hi,

I have an editable table with some very long urls that break the layout. Instead I want it to show up truncated with an ellipsis, but retaining the original content in the data array. So when people edit the cells, they will see the full urls, but as soon as the save the content, it will again show up truncated.

This could be done easily if there was callback function that were called for each cell before they were rendered.

Is that possible? Or do you alternatively have other ideas?

I should note that doing it by css alone is not possible in a cross-browser solution.

Thanks btw for this fantastic plugin!

Martin

Replies

  • zygimantaszygimantas Posts: 33Questions: 0Answers: 0
    Well, you can override fnRender() function to copy the text to cell title attribute and truncate text in cell. To make it pretty, you can also dynamically add a class to td element and style it (i.e with ellipsis in the background).
    Attach 'click' event to all cells who has title attribute and switch data inside title attribute and cell content.

    Bonus: you will get tooltip with full content on mouse over.
  • allanallan Posts: 57,236Questions: 1Answers: 9,113 Site admin
    Hi Martin,

    There isn't a callback function for every cell, however, there is a callback function for each row which will probably do the trick quite nicely for you: http://datatables.net/usage#fnRowCallback . However you need to watch that DataTables doesn't modify the data inside the cell (unless specifically asked) so you might need to take account of this function beening called several times on the same cell.

    In 1.4.0 the fnRender() function would probably have done the trick for you. However, in 1.4.1 I've changed the internal storage to store the rendered data, as well as putting it on screen (it makes sense for sorting, filtering etc). Ironic that you post this question on the same day that 1.4.1 is released!

    It will be a great day when this can be done cross platform in CSS only... :-)

    Regards,
    Allan
  • marlarmarlar Posts: 11Questions: 0Answers: 0
    Hi Allan,

    I have tried what you suggest, but I can't see how I can change the value displayed without changing the data. If for example inside the callback I have a simple line like :

    $('td:eq(1)', nRow).html('123');

    I see of course a column of "123". But when I click on one of the cells, I also get 123 in the editor. I need to keep the original data values.

    You address the problem somewhat by saying "However you need to watch that DataTables doesn't modify the data inside the cell" but I don't know how I do accomplish that and still change the displayed value!

    Regards,
    Martin
  • marlarmarlar Posts: 11Questions: 0Answers: 0
    edited March 2009
    Hmm, now at least I know what is going on:

    jEditable works on the html content of the DOM, not the data array. So even if the data array still contains the original value, jEditable works on the displayed "123".

    The point it then to somehow supply the correct data value to jEditable instead of the DOM value.

    Any idea how this can be done?
  • allanallan Posts: 57,236Questions: 1Answers: 9,113 Site admin
    Hi Martin,

    I see the problem... The issue is that jEditable gets it's data by simply doing $(this).html() (or at least something very similar). From looking at the jEditable code it would appear that you can use the 'data' parameter in it's initialisation object (either as a string (number etc) or as a callback function). By using this, and accessing the internal data held by DataTables, I believe what you are looking for can be done (also in combination with fnRowCallback() as we talked about before...).

    Hope this helps.
    Regards,
    Allan
  • marlarmarlar Posts: 11Questions: 0Answers: 0
    Yes, I am on the track now :-)

    Will return with more info later.
  • marlarmarlar Posts: 11Questions: 0Answers: 0
    edited March 2009
    Ok, this seems to do it!

    [code]
    var oTable;

    function ellipsis(text, n) {
    if(text.length>n)
    return text.substring(0,n)+"...";
    else
    return text;
    }

    $(document).ready(function() {
    $('#example tbody td:not(:first-child)').editable( function( sValue ) {
    var aPos = oTable.fnGetPosition( this );
    var aData = oTable.fnGetData( aPos[0] );
    aData[ aPos[1] ] = sValue;
    return ellipsis(sValue,20);
    }, { data: function(value, settings) {
    var aPos = oTable.fnGetPosition( this );
    var aData = oTable.fnGetData( aPos[0] );
    return aData[aPos[2]];
    }
    ,"onblur": 'submit' } );

    oTable = $('#example').dataTable( {
    "fnRowCallback": function( nRow, aData, iDisplayIndex ) {
    var $cell=$('td:eq(1)', nRow);
    $cell.text(ellipsis($cell.text(),20));
    return nRow;
    }
    } );
    } );
    [/code]
  • marlarmarlar Posts: 11Questions: 0Answers: 0
    edited March 2009
    Well, the layout got garbled, but I hope other users will see the point.

    The key is the data callback that returns the data value to jEditable before it showing up. And also the update callback where it is important to adjust the returned value using ellipsis(). Otherwise the full content will show up after editing.

    Thanks for your help!
  • allanallan Posts: 57,236Questions: 1Answers: 9,113 Site admin
    I've added syntax highlighting for your post. I've not really advertised that in the forum yet because it is rather flaky... (doesn't work in Safari for example!). Still trying to nail it down.

    Code looks great! Very useful indeed.

    Allan
This discussion has been closed.