Animate open/close of dynamic hidden table rows?

Animate open/close of dynamic hidden table rows?

manentiamanentia Posts: 14Questions: 0Answers: 0
edited July 2010 in General
I saw the post from last year regarding the difficulties of animating table rows:
http://datatables.net/forums/comments.php?DiscussionID=408

I was able to follow the official example (and a few other posts) for showing hidden content loaded dynamically... but I'm stuck trying to get the new row to appear a little more nicely (and I've included the minimum source below as another working example to easily get dynamic content).

Has anybody been able to animate the incoming row? Thanks!

[code]
var oTable;

/* Formating function for row details */
function fnFormatDetails(nTr) {
var iIndex = oTable.fnGetPosition(nTr);
var aData = oTable.fnGetData(nTr);
$.ajax({
type: "POST",
url: "data.asp",
cache: false,
data: 'id=' + aData[1],
success: function (msg) {
oTable.fnOpen(nTr, msg, 'details');
}
});
}

$(document).ready(function () {

$('td img', oTable.fnGetNodes()).each(function () {
$(this).click(function () {
var nTr = this.parentNode.parentNode;
if (this.src.match('details_close')) {
/* This row is already open - close it */
this.src = "details_open.png";
oTable.fnClose(nTr);
}
else {
/* Open this row */
this.src = "details_close.png";
oTable.fnOpen(nTr, fnFormatDetails(nTr), 'details');
}
});
});
});
[/code]

Replies

  • andresraiesteandresraieste Posts: 3Questions: 0Answers: 0
    Well, I tried doing it like this (modified the fnOpen in jquery.datatables.js), but the animation is incorrect:

    [code]
    this.fnOpen = function (nTr, sHtml, sClass) {
    /* Find settings from table node */
    var oSettings = _fnSettingsFromNode(this[_oExt.iApiIndex]);

    /* the old open one if there is one */
    this.fnClose(nTr);

    var nNewRow = document.createElement("tr");
    var nNewCell = document.createElement("td");
    nNewRow.appendChild(nNewCell);
    nNewCell.className = sClass;
    nNewCell.colSpan = _fnVisbleColumns(oSettings);
    nNewCell.innerHTML = sHtml;

    nNewRow.style.display = 'none'; // <----- Set the row invisible at first

    /* If the nTr isn't on the page at the moment - then we don't insert at the moment */
    var nTrs = $('tr', oSettings.nTBody);
    if ($.inArray(nTr, nTrs) != -1) {
    $(nNewRow).insertAfter(nTr);
    $(nNewRow).show('fast'); // <-------------------- Show the added row
    }

    oSettings.aoOpenRows.push({
    "nTr": nNewRow,
    "nParent": nTr
    });

    return nNewRow;
    };
    [/code]

    If someone has a solution, please do share.
  • allanallan Posts: 63,783Questions: 1Answers: 10,511 Site admin
    Hi guys,

    I've done this before and have been meaning to get around to rewriting it as open source (since the examples I've done before are closed course), but not yet got around to it I'm afraid! On the plus side it is most certainly possible!

    What I did was not to animate the height of the TR or TD elements, but rather try sticking a DIV into the TD in the 'opened' row (remember to removing the padding of the opened row / cell via CSS!) and then animate that slide down - that should do the trick!

    Regards,
    Allan
  • NiallNiall Posts: 4Questions: 0Answers: 0
    Hi all,

    I did this, as Allan suggested, by inserting a div and using the jQuery.slideDown and slideUp functions.
    I modified the fnOpen and fnClose functions as follows
    [code]
    /*
    * Function: fnOpen
    * Purpose: Open a display row (append a row after the row in question)
    * Returns: node:nNewRow - the row opened
    * Inputs: node:nTr - the table row to 'open'
    * string|node|jQuery:mHtml - the HTML to put into the row
    * string:sClass - class to give the new TD cell
    */
    this.fnOpen = function (nTr, mHtml, sClass, fnCallBack) {

    /* Find settings from table node */
    var oSettings = _fnSettingsFromNode(this[_oExt.iApiIndex]);

    /* the old open one if there is one */
    this.fnClose(nTr);

    var nNewRow = document.createElement("tr");
    var nNewCell = document.createElement("td");
    nNewRow.appendChild(nNewCell);
    nNewCell.className = sClass;
    nNewCell.colSpan = _fnVisbleColumns(oSettings);

    var nNewDiv = document.createElement("div"); // add DIV inside the table cell
    nNewDiv.className = "container";
    nNewCell.appendChild(nNewDiv);

    if (typeof mHtml.jquery != 'undefined' || typeof mHtml == "object") {
    nNewDiv.appendChild(mHtml);
    }
    else {
    nNewDiv.innerHTML = mHtml;
    }

    /* If the nTr isn't on the page at the moment - then we don't insert at the moment */
    var nTrs = $('tr', oSettings.nTBody);
    if ($.inArray(nTr, nTrs) != -1) {
    $(nNewRow).insertAfter(nTr);
    }

    oSettings.aoOpenRows.push({
    "nTr": nNewRow,
    "nParent": nTr
    });

    $(nNewDiv).slideDown("fast"); // slide down the DIV

    return nNewRow;
    };

    /*
    * Function: fnClose
    * Purpose: Close a display row
    * Returns: int: 0 (success) or 1 (failed)
    * Inputs: node:nTr - the table row to 'close'
    */
    this.fnClose = function (nTr) {
    /* Find settings from table node */
    var oSettings = _fnSettingsFromNode(this[_oExt.iApiIndex]);

    for (var i = 0; i < oSettings.aoOpenRows.length; i++) {
    if (oSettings.aoOpenRows[i].nParent == nTr) {
    var tr = oSettings.aoOpenRows[i].nTr;
    var div = tr.firstChild.firstChild;
    $(div).slideUp("fast", function () { // move removal of TR to slideUp callback
    var nTrParent = tr.parentNode;
    if (nTrParent) {
    /* Remove it if it is currently on display */
    nTrParent.removeChild(tr);
    }
    });

    oSettings.aoOpenRows.splice(i, 1);

    return 0;
    }
    }

    return 1;
    };
    [/code]

    The class of "container" is added for CSS, which needs a display:none rule.
    [code].container {display:none;}[/code]
  • glawrieglawrie Posts: 18Questions: 3Answers: 0
    I've tried to get this to work on a test-page that I'm developing. I've put the new definitions for fnOpen and fnClose within in tags on the page in question, after the link to the DataTables source. But for some reason I cannot get the script on the page to pick up the new definitions - the page created has no "container" div within the 'expanded' rows.

    The test page is here: http://v6dev.2gc.org/resources-weblinks-table0617

    Grateful for any guidance that can be given on what I'm doing wrong...
  • allanallan Posts: 63,783Questions: 1Answers: 10,511 Site admin
    @glawrie: The two functions from Niall above need to be put into the DataTables source - they are replacements for the fnOpen and fnClose that are in the DataTables core - rather than being plug-in functions which can just be included.

    Generally you probably won't want to alter the DataTables source (although of course there is nothing stopping you if you fancy it! :-) ) - I'd suggest that you probably want to use the regular fnOpen/fnClose and just put a 'div' as the only child element of the 'details' cell, and then put your content into that div and animate that div as required.

    Regards,
    Allan
  • glawrieglawrie Posts: 18Questions: 3Answers: 0
    OK - got it working: huzzah! See the working example here.

    http://www.2gc.co.uk/resources-weblinks

    But the slideup / slidedown functionality is simply not working: I've copied the code for this just as it is in the example, but even when the slide is set to "slow", no evidence that the slide is working.

    I'm sure it is because I've done something daft. Would value any guidance about what I should be doing to get this part to work...

    Thanks in advance for any help avail!
This discussion has been closed.