possible to keep dataTable height static (even when filtering)?

possible to keep dataTable height static (even when filtering)?

orange_roughyorange_roughy Posts: 19Questions: 0Answers: 0
edited February 2011 in General
Hi,

Is it possible to keep the dataTable height the same even when filtering/searching? The default behavior is for the table to shrink in height to match the number of filtered rows.

thank you,
orange roughy

Replies

  • mstrandmstrand Posts: 24Questions: 0Answers: 0
    Are you using vertical scrolling? If so, see the bScrollCollapse option here:

    http://www.datatables.net/usage/options

    Setting this to false will prevent the table from shrinking when using vertical scrolling.
  • allanallan Posts: 63,540Questions: 1Answers: 10,476 Site admin
    It's CSS thing - you can either set a height on the table, or put a DIV wrapper around the table using sDom and set an explicit height on that.

    Allan
  • GregPGregP Posts: 500Questions: 10Answers: 0
    edited March 2011
    CSS is funny, though:

    If you set height on the 'containing' div, the table footer will jump up and down with the height of the table. If you set height on the table itself, when there aren't enough rows to fill it, they will stretch to fit.

    I was trying to experiment with sScrollY and bScrollCollapse, but the whole div keeps growing in width each time my table is updated (polling intervals of 3 seconds). Those functions may work with a "one-time grab" of data, but for my polling scenario something seems to be broken. A width value is being incremented instead of reset and then incremented is my best guess.

    Any other ideas, or should I just settle for the footer moving up and down?

    The ideal for me would be the ability to specify the number of rows (10), and for DataTables to render out a bunch of empty rows if there's not a full 10 available. But with sScrollY enabled and the collapse set to false (default), that's a close runner-up. If the width didn't keep incrementing!

    Using jQuery UI as well, if that makes a difference.

    Greg
  • allanallan Posts: 63,540Questions: 1Answers: 10,476 Site admin
    Hmmm - I wonder what would cause the width to increase. Have you got a wrapper around the table with a fixed width? If not - do adding one make a difference? Also are you setting the height on div.dataTables_scrollBody? It should be possible to fix it with that and bScrollCollapse set to false.

    What you could do to have 10 rows always is have an fnDrawCallback function which will simply count the number of TR elements in the TBODY, if there is less than 10 add as many as needed (with the odd/even classes).

    Allan
  • GregPGregP Posts: 500Questions: 10Answers: 0
    edited March 2011
    Hey Allan,

    Not sure about the width problem. I could probably recreate the scenario if you like. Should've taken a Jing capture. ;-) There is a wrapper with a fixed width, yes.

    I actually hadn't seen that you had replied to this thread, so I was intending to come here to update you with the "idea" of just adding blank rows with fnDrawCallback. ;-) I must be getting better at DataTables, because I come back here and that's one of your very own suggestions. :D

    I'll post back the code snippet for anyone who wants it (once it's polished a bit), but suffice it to say that you do need to make sure there's a static height being set either in CSS or as a td attribute; also, you'll need to either add as many TDs as needed or figure out how wide the colspan needs to be (in my case, the colspan works best) or most browsers will just collapse the TR because it has no content.
  • allanallan Posts: 63,540Questions: 1Answers: 10,476 Site admin
    Sounds like it will be a useful code snippet that. I'm wonder where I can sort putting things like that on the site... Too much code to organise :-)

    For the colspan - there is an internal function called _fnVisbleColumns which you could use (this.oApi._fnVisbleColumns() in fnDrawCallback) to give you the required colspan (it is what fnOpen uses for exactly that kind of thing).

    Allan
  • GregPGregP Posts: 500Questions: 10Answers: 0
    edited March 2011
    I dunno why, but that doesn't work. When I do exactly what you say (I even tried _fnVisibleColumns() in case the above had a typo but as I'm sure you know, it did not!) I am being thrown an error:

    oS is undefined (line 5185):
    for ( var i=0 ; i
  • allanallan Posts: 63,540Questions: 1Answers: 10,476 Site admin
    Well it's an internal private function, and is liable to change (although very unlikely in 1.7.x1), so using it is no "worse" that doing the DOM method. I think you need to pass the settings object into it:

    [code]
    this.oApi._fnVisbleColumns( oSettings );
    [/code]
    which I'm guessing you aren't at the moment?

    Annoying about the typo - sorry about that :-). Definitely a private function!

    Allan
  • GregPGregP Posts: 500Questions: 10Answers: 0
    As mentioned in a similar thread, I am indeed not passing the oSettings object into it. What a rookie. ;-) I'll give this a try.
  • GregPGregP Posts: 500Questions: 10Answers: 0
    Seems to work; remembering of course that you need to pass it into the function in the first place:

    [code]
    "fnDrawCallback" : function(oSettings) {
    var numcolumns = this.oApi._fnVisbleColumns(oSettings);
    myappAddRows(this, numcolumns);
    }
    [/code]
  • GregPGregP Posts: 500Questions: 10Answers: 0
    Now the last remaining issue is the highlighted column (ie. the ones with sorting_1, sorting_2, etc.). Going to look into the API to see if there's an available way to add the relevant classes with built-in data or functionality.

    It's easy enough to do by querying and manipulating the DOM: get an array of TDs from within a 'proper' (non-placeholder) jQuery row object, and find the position of the TD with the class in question (sorting_1). If sorting_1 is found at array[3], then I just need to replicate this for the placeholder rows.

    But I suspect there's a more efficient way of doing it if I dig a little. ;-)

    Greg
  • allanallan Posts: 63,540Questions: 1Answers: 10,476 Site admin
    There is an internal function called _fnSortingClasses which does the sorting classes - however, it will only work on the rows that DataTables knows about (given that it calls _fnGetTdNodes). As such, I don't think it will do quite what you are looking for :-(. I think either a DOM match will be needed - or possibly even better you could clone the last TR in the table, remove the text in the TDs and then clone that for every row you need to insert...

    Looking forward to seeing it working (I was thinking at work today how something like this would be useful for what I was working on... ;-) ).

    Regards,
    Allan
  • GregPGregP Posts: 500Questions: 10Answers: 0
    edited March 2011
    Well, here's my somewhat bulky function. It could be more svelte, but I tried to make it reusable so that you can pass it any number of rows. Most of the bulk comes from maintaining odd/even row striping, and sorting_1 classes on TD elements.

    [code]
    /* fcmcAddrows is a utility function called from within fnDrawCallback
    * obj is the jQuery table object, numberColumns is result of _fnVisbleColumns,
    * and targetRows is the total number of visible rows we need.
    */

    function fcmcAddRows(obj, numberColumns, targetRows) {
    var tableRows = obj.find('tbody tr'); // grab the existing data rows
    var numberNeeded = targetRows - tableRows.length; // how many blank rows are needed to fill up to targetRows
    var lastRow = tableRows.last(); // cache the last data row
    var lastRowCells = lastRow.children('td'); // how many visible columns are there?
    var cellString;
    var highlightColumn;
    var rowClass;

    // The first row to be added actually ends up being the last row of the table.
    // Check to see if it should be odd or even.
    if (targetRows%2) {
    rowClass= "odd";
    } else {
    rowClass = "even"; //
    }

    // We only sort on 1 column, so let's find it based on its classname
    lastRowCells.each(function(index) {
    if ($(this).hasClass('sorting_1')) {
    highlightColumn = index;
    }
    });

    /* Iterate through the number of blank rows needed, building a string that will
    * be used for the HTML of each row. Another iterator inside creates the desired
    * number of columns, adding the sorting class to the appropriate TD.
    */
    for (i=0;i
  • allanallan Posts: 63,540Questions: 1Answers: 10,476 Site admin
    Very nice - thanks! Bookmarked so I can check it out properly in a bit.

    I don't think this will leak memory - the most common cause for a leak in Javascript is probably not unassigning event handlers - and you don't have any on your rows here, so all fine. The memory tools in Chrome are absolutely superb - might be worth checking them out

    Allan
  • GregPGregP Posts: 500Questions: 10Answers: 0
    Thanks for the advice. I've never used Chrome's memory tools... are those part of the Developer's Tools pane?
  • allanallan Posts: 63,540Questions: 1Answers: 10,476 Site admin
    Yup - under the 'profiles' tab - select the 'heap snapshot' options. It will show you a live graph of the amount of committed memory.

    Allan
  • GregPGregP Posts: 500Questions: 10Answers: 0
    Well, it's certainly going up; and I can see that more objects are created with each poll. This is what I already figured. What I can't figure out is how to identify which objects are still alive that should be dead. ;-) Sorting by size, the thing tells me I have {closure} taking up X amount of memory. Expand that to get another {closure} taking up X, expand that to see {closure} taking up X, etc etc. I eventually gave up on expanding it. Ditto for trying to expand "Objects" etc.

    Not that I'm asking you to teach me how to use the memory tools. ;-) I'm sure there are online resources for that!

    I'll get to the bottom of this somehow!

    Greg
  • allanallan Posts: 63,540Questions: 1Answers: 10,476 Site admin
    Does it not go up and then come back down after a little while (like 10 seconds or so). The V8 garbage collector only runs every now and then, rather then sweeping up instantly.

    Allan
  • GregPGregP Posts: 500Questions: 10Answers: 0
    edited March 2011
    Nope. Just goes up and up.

    Or more accurately: yes, there is SOME garbage that gets collected periodically, and then you see a drop. But the overall trend is that it does go up in general. It would probably take less than 48 hours to completely use up my available resources. Which isn't bad for a page that you're going to consume and close, but we anticipate our clients keeping the page open more often than not.

    Completely unrelated side-note: was trying out our application on a number of Android and iOS devices today... all is working perfickly. ;-)
  • allanallan Posts: 63,540Questions: 1Answers: 10,476 Site admin
    Good to hear - about iOS and Android that is! :-).

    Try using the profiling tools in Chrome - it should show where the memory is going (new TD elements whatever). It can be a little tricky to follow, but I'm sure you'll get into the swing of it!

    Allan
  • devksdevks Posts: 10Questions: 0Answers: 0
    edited May 2011
    Hi Allan and GregP

    I am using greg's function fcmcAddRows to initialize my table with 10 empty rows. It draws the table perfectly and the row are styled with alternating colors. However I see "Showing 1 to 10 of 10 entries" in the info of the table. Is there a way to fix this. Essentially it should disregard the empty rows and show "No data available in table".

    I modified the function slightly. Instead of adding the row after the last row I am adding it to the table.

    var table = obj.find('tbody');
    table.append(''+cellString+'');

    Thanks !
  • allanallan Posts: 63,540Questions: 1Answers: 10,476 Site admin
    When are you calling fcmcAddRows? It should be in fnDrawCallback after the table has drawn.

    Allan
  • devksdevks Posts: 10Questions: 0Answers: 0
    Yes I am calling it from the fnDrawCallback. Below is my code.

    $('#example').dataTable({
    "sDom": 'R<"H"lfr>t<"F"ip>',
    "iFixedColumns":1,
    "bJQueryUI": true,
    "sPaginationType": "full_numbers",
    "aaSorting": [[2,'desc']],
    "bAutoWidth": false,
    //"bStateSave": true,
    "fnDrawCallback": fcmcAddRows(this, 10, 10)


    });

    Thanks
  • allanallan Posts: 63,540Questions: 1Answers: 10,476 Site admin
    Try this:

    [code]
    "fnDrawCallback": function () {
    fcmcAddRows(this, 10, 10);
    }
    [/code]
    As you had it it was calling the function on initialisation - not at the draw callback time (would have thought that would result in a JS error being thrown actually).

    Allan
  • devksdevks Posts: 10Questions: 0Answers: 0
    Hi Allan,

    This works fine.

    Thanks a lot !
  • tsheptshep Posts: 2Questions: 0Answers: 0
    edited July 2011
    Very cool.. datatables is very very awesome. I like how I can just go mysql_fetch_array and label the columns and display out of a sql database in just a few lines of code.

    However.. The jumping up and down of the table from filtering and pagination was a bit jarring so I found this thread. It mostly works, except on the 'page' with padding the column widths are different when they have mixed filled rows and empty rows from pages with all data rows.

    The empty padding rows extended horizontally past the rows with data in them them.

    Any tips? Great work guys.
  • tsheptshep Posts: 2Questions: 0Answers: 0
    My bad.. fcmcAddRows takes num rows and num columns. It seems to me that this should be populated from the drop down and the number of columns in the table. I fixed one line

    for (j=0;j
  • raveeshmehtaraveeshmehta Posts: 2Questions: 0Answers: 0
    Thanks GregP

    Your code was really helpful to us in building empty rows in our grid
  • manisabrimanisabri Posts: 1Questions: 0Answers: 0
    Hi
    I'm using Datatables 1.9.1 .
    Short stroy , this function is not working .
    long story:
    Line 1423 and Line 1433 in jquery.datatables.js remove the rows added by fcmcAddRows.
    My table is using server side processing. Any ideas?

    Regards
    Mani
This discussion has been closed.