how to always show a fixed number of rows

how to always show a fixed number of rows

visceralistvisceralist Posts: 33Questions: 0Answers: 0
edited February 2014 in DataTables 1.9
Hi Allan

I hope you are well.
listen, I am trying to figure out something with the datatable that I didnt see an API hook for. My table viewport adjusts its height as the window resolution changes. that's all cool.

what I need to figure out is how to always show a fixed number of rows inside the view port; I don't actually care what that fixed number is; it can show whatever it was going to fit in that viewport height anyway. what I am trying to prevent is the scenario where a row at the most bottom is shown partially: half of the row is show and the other half isn't - you'd have to scroll up a little bit to show it fully; I need to figure out so what viewport height changes, it fits n number of rows without partials.

any input on this?
cheers mate, thank you

Replies

  • allanallan Posts: 63,679Questions: 1Answers: 10,498 Site admin
    So you would adjust the height of the rows as the window resizes? So for example if you have a viewport of 500px, and 10 rows, each row is 50px, and if the viewport is 100px each row is 10px? You'd just do it using CSS - there isn't a DataTables API for that. A little bit of jQuery to set the height for the rows should do it I guess :-)

    Allan
  • visceralistvisceralist Posts: 33Questions: 0Answers: 0
    somehow my original comment is gone? :(

    in this demo: https://datatables.net/extras/scroller/

    it's showing what is the top row is by saying Showing x out of whatever. the X corresponds to the ID of the top row and the table is scrolling using the scroll plugin. How can I get my table that is using the same plugin to show the top when scrolling?

    thanks
  • allanallan Posts: 63,679Questions: 1Answers: 10,498 Site admin
    So basically you want to use the Scroller plug-in? Can you not just initialise it with your table as per the Scroller instructions? I don't really understand I'm afraid.

    Allan
  • visceralistvisceralist Posts: 33Questions: 0Answers: 0
    I am using the scroller plugin, yes.

    here's how the code is initialized - sorry, I should have written this earlier per your instructions.

    [code]

    this.myTable.dataTable({
    "sScrollY": "400px",
    "aaData": tableData,
    "sDom": "tiS",
    "bAutoWidth": false,
    "bDeferRender": false,
    "fnDrawCallback": $.proxy(this.bindRowEvents, this),
    "aoColumnDefs": [
    { "sWidth": "1%", "aTargets": [0], "bSortable": false, "sClass": "center" },
    { "sWidth": "8%", "aTargets": [1], "sClass": "center" },
    { "sWidth": "10%", "aTargets": [2] },
    { "sWidth": "12%", "aTargets": [3], "sClass": "location" },
    { "sWidth": "6%", "aTargets": [4], "sClass": "center" },
    { "sWidth": "2%", "aTargets": [5] },
    { "sWidth": "", "aTargets": [6] }
    ],
    "aaSorting": [[2, 'asc']],
    "fnInfoCallback": function (oSettings, iStart, iEnd, iMax, iTotal, sPre) {

    var info = iTotal + (iTotal > 1 ? ' Accounts' : ' Account'),
    infoFiltered = ' (filtered from ' + iMax + ' total accounts)',
    infoEmpty = '0 Accounts';

    oSettings.oLanguage.sInfo = info;
    oSettings.oLanguage.sInfoFiltered = infoFiltered;
    oSettings.oLanguage.sInfoEmpty = infoEmpty;
    }
    });
    [/code]

    I just need to know how to get that top row in the way shown in the scroller demo page
  • visceralistvisceralist Posts: 33Questions: 0Answers: 0
    supposing I used the code that is used in your demo page to initialize my datatable, how could I go about storing that toprow value in a variable somewhere? clearly it knows what the top row is when you are scrolling through it, I just need to grab it from datatables and store it in a variable.

    thanks Allan
  • visceralistvisceralist Posts: 33Questions: 0Answers: 0
    so I've been reading the documentation and I guess what I needed to ask is this access to the iStart and iEnd rows in the visible array at any given point:
    [code]
    * @param {int} iStart Index for the current display starting point in the
    * display array
    * @param {int} iEnd Index for the current display ending point in the
    * display array
    * @param {array int} aiDisplay Index array to translate the visual position
    * to the full data array
    [/code]

    this information is showing as you scroll through the table but I want to store/update them in a variable somewhere where I can say something like 'the current top row in the table is: info for that top in the table' and 'the current bottom row in the table is: info for that bottom in the table.
  • visceralistvisceralist Posts: 33Questions: 0Answers: 0
    Allan

    I have used the default initialization method with scroller:

    [code]
    this.myTable.dataTable({
    "aaData": tableData,
    "sScrollY": "400px",
    "sDom": "tiS",
    "bDeferRender": true,
    "fnDrawCallback": $.proxy(this.bindRowEvents, this),
    "aoColumnDefs": [
    { "sWidth": "1%", "aTargets": [0], "bSortable": false, "sClass": "center" },
    { "sWidth": "8%", "aTargets": [1], "sClass": "center" },
    { "sWidth": "10%", "aTargets": [2] },
    { "sWidth": "12%", "aTargets": [3], "sClass": "location" },
    { "sWidth": "6%", "aTargets": [4], "sClass": "center" },
    { "sWidth": "2%", "aTargets": [5] },
    { "sWidth": "", "aTargets": [6] }
    ],
    "aaSorting": [[2, 'asc']],

    });
    [/code]

    at the bottom it is showing the information about pages: showing x of x out of x... that's good. As I scroll through the table, that information at the bottom of the table increments accordingly. so at this point, I just need to create two global variables where I store the incremented value of x:

    so if tbale loads and it is showing 1 of 12 out of 60
    var _topRow would store the the 1, _bottomRow would store 12 and _total would store the 60. of course as table scrolls up and down, I want the incremented values to be stored in those global variables and not static, initially loaded ones.
  • visceralistvisceralist Posts: 33Questions: 0Answers: 0
    so I managed to get some of the values I needed - here's my function that gets the incremented start and end values and depending on the keycode event, scroll the table either up or down.

    the only one issue I have here is that on page up, it only scrolls up one row at a time. so if sStartwas 59, it will scroll to row 58 on page up. any thoughts?

    [code]
    makeTableScroller = function () {
    offset = 0;
    return function (tableInfo) {
    var tableId = tableInfo.tableId;
    var scrollTop = tableInfo.settings.oScroller.dom.scroller.scrollTop;
    var iStart = tableInfo.settings.oScroller.fnPixelsToRow(scrollTop) + 1;
    var iPossibleEnd = tableInfo.settings.oScroller.fnPixelsToRow(scrollTop + $(tableInfo.settings.oScroller.dom.scroller).height());
    var iTotal = tableInfo.settings.oScroller.s.dt.fnRecordsDisplay();
    var iEnd = iTotal < iPossibleEnd ? iTotal : iPossibleEnd;

    var sStart = tableInfo.settings.oScroller.s.dt.fnFormatNumber( iStart );
    var sEnd = tableInfo.settings.oScroller.s.dt.fnFormatNumber(iEnd);
    var sTotal = tableInfo.settings.oScroller.s.dt.fnFormatNumber(iTotal);

    var viewportHeight = Math.floor($(tableInfo.settings.oScroller.dom.scroller).height());
    var rowHeight = tableInfo.settings.oScroller.s.rowHeight;
    var viewportRows = parseInt(viewportHeight / rowHeight);

    if (tableInfo.event.keyCode === Util.KeyCodes.PageDown) {
    console.log(sStart + ' ' + sEnd);
    tableInfo.settings.oScroller.fnScrollToRow(sEnd);
    tableInfo.settings.oScroller.fnMeasure();

    }
    else if (tableInfo.event.keyCode === Util.KeyCodes.PageUp) {
    tableInfo.settings.oScroller.fnMeasure();
    tableInfo.settings.oScroller.fnScrollToRow(sStart);
    console.log(sStart);

    }
    }
    },

    [/code]

    am i right in thinking that fnMeasure() redraws the table to rows fit properly without partial rows showing?
  • allanallan Posts: 63,679Questions: 1Answers: 10,498 Site admin
    I am totally confused - sorry. I guess my understanding is wrong, but what I thought you were looking for was the table information element to update like it does in Scroller. Is that not the case? Can you explain clearly and simply, for a daftie like me, what it is that you are looking for.

    Allan
  • visceralistvisceralist Posts: 33Questions: 0Answers: 0
    you are no daftie mate, I am the daftie for cheesy explanations :)

    okay, here's the deal. I've got this table (https://www.amazon.com/clouddrive/share?s=8uVpSxTeQmQiAaVykIuyaY)

    notice how at the bottom it is saying showing 1 to 15 but in the viewport it is actually showing 13 s?

    I try to get the number of viewport rows this way and it tells me 15 where I am only displaying 13:
    [code]var viewportRows = Math.floor(viewportHeight / rowHeight);[/code]

    the reason I am trying to get that info right is that I am trying to scroll the table using the keyboard event;
    [code]
    var bottomRow = tableInfo.settings.oScroller.fnPixelsToRow(scrollTop + viewportHeight);
    var rowHeight = tableInfo.settings.oScroller.s.rowHeight;
    [/code]

    above I am trying to get the bottomRow and rowHeight; the bottomRow is the same number as the number of viewportRow and that is off. the reason it is off is bcause the rowHeight is giving me a height of 26 where the actual row height in those rows in the image is 31.

    I am trying to get that information so then I can do this on a pageDown keyboard event:

    [code]
    tableInfo.settings.oScroller.fnScrollToRow(bottomRow);
    [/code]

    now it works in that it scrolls down but it scrolls down to a row that I don't need. if you look at that image I shared, I need it to scroll to the row that is right after that account#0094857. or whatever is at the bottom of the viewport.

    this is why I thought I needed the viewport to always show fully visible rows and not partial ones.

    anyway, I really hope this makes sense cause I am at the end of my wits here :)
  • visceralistvisceralist Posts: 33Questions: 0Answers: 0
    and this is how the table is initialized:
    [code]
    this.myTable.dataTable({
    "sScrollY": "400px",
    "aaData": tableData,
    "sDom": "tiS",
    "bAutoWidth": false,
    "bDeferRender": true,
    "fnDrawCallback": $.proxy(this.bindRowEvents, this),
    "aoColumnDefs": [
    { "sWidth": "1%", "aTargets": [0], "bSortable": false, "sClass": "center" },
    { "sWidth": "8%", "aTargets": [1], "sClass": "center" },
    { "sWidth": "10%", "aTargets": [2] },
    { "sWidth": "12%", "aTargets": [3], "sClass": "location" },
    { "sWidth": "6%", "aTargets": [4], "sClass": "center" },
    { "sWidth": "2%", "aTargets": [5] },
    { "sWidth": "", "aTargets": [6] }
    ],
    "aaSorting": [[2, 'asc']],

    });

    [/code]

    and this is what gets called on the pagedown/up event:

    [code]
    makeTableScroller = function () {
    offset = 0;
    return function (tableInfo) {
    var scrollId = tableInfo.tableId;
    var scrollTop = tableInfo.settings.oScroller.dom.scroller.scrollTop;
    var viewportHeight = Math.floor($(tableInfo.settings.oScroller.dom.scroller).height());
    var rowHeight = tableInfo.settings.oScroller.s.rowHeight;

    var viewportRows = Math.floor(viewportHeight / rowHeight);
    var topRow = tableInfo.settings.oScroller.fnPixelsToRow(scrollTop);
    var bottomRow = tableInfo.settings.oScroller.fnPixelsToRow(scrollTop + viewportHeight);
    var displayStart = tableInfo.settings.oScroller.s.dt._iDisplayStart;

    if (tableInfo.event.keyCode === Util.KeyCodes.PageDown) {
    tableInfo.settings.oScroller.fnScrollToRow(bottomRow);

    }
    else if (tableInfo.event.keyCode === Util.KeyCodes.PageUp) {
    tableInfo.settings.oScroller.fnMeasure();
    tableInfo.settings.oScroller.fnScrollToRow(topRow);
    }
    }
    },
    [/code]
  • tangerinetangerine Posts: 3,365Questions: 39Answers: 395
    I hesitated to poke my nose in here as I don't use Scroller. But I got too curious! I looked at the Scroller examples and they do not accurately synchronize the display with the "Showing x to y" text. That can't be helping, if Scroller is already not quite accurate. Just a thought.
  • allanallan Posts: 63,679Questions: 1Answers: 10,498 Site admin
    @visceralist - Are you able to link me to the page you are using? Scroller should really be doing this for you - showing and updating the information about which rows are displayed. PM me by clicking on my name and then "Send Message" if you can't make the URL public.

    @tangerine - Which examples are out of sync? The ones here seem to work okay for me: http://next.datatables.net/release-datatables/extensions/Scroller/examples/simple.html - do they not for you?

    Allan
  • tangerinetangerine Posts: 3,365Questions: 39Answers: 395
    edited February 2014
    Allan, I really don't want to take up your time with this, but I'm not smart enough to do any significant debugging on the principles of scrolling.
    I'm looking at the first example here:
    http://www.datatables.net/extras/scroller/
    with these results:

    Firefox & Chrome
    Showing 1 to 6 of 2,500 entries
    Actually displayed: 1 to 7

    IE 11
    Doesn't show any table data, just the column headings.

    Cross-browser scrolling comparisons are never going totally in synch. In the cases of Firefox and Chrome, some "random" scrolls sometimes match display to "Showing" text, but not always.
    If there's anything more scientific I could do to help, just ask.
  • allanallan Posts: 63,679Questions: 1Answers: 10,498 Site admin
    > Actually displayed: 1 to 7

    Sort of... Its actually showing 1 to ~6.8 rows! It is rounding the last number down. In fairness, that is probably wrong thinking about it, since the first number is rounded down. It should probably be consistent.

    Interesting that IE11 doesn't work for you - seems to be okay here. Are you getting an JS errors?

    Allan
  • tangerinetangerine Posts: 3,365Questions: 39Answers: 395
    Well, this is my first encounter with the delights of debugging in IE - I'm used to Firefox/Firebug.
    But the console is showing no errors, warnings or messages.
  • allanallan Posts: 63,679Questions: 1Answers: 10,498 Site admin
    Bummer - I'm at a little bit of a loss in that case. If anyone else is reading this on a Windows machine, could you try it and report back as well?
  • visceralistvisceralist Posts: 33Questions: 0Answers: 0
    Allan, mate thanks for the taking the time on this. I am going to see what I can do about linking to the life page. I really gotta get this scrolling wired up to page up and down.

    I will PM later.
    thanks
  • allanallan Posts: 63,679Questions: 1Answers: 10,498 Site admin
    Hi,

    Thanks for the chat last night @visceralist - I totally get what you are trying to do now. Basically you just want the table's scrolling element to hijack the page up and page down keys so it will shift the display.

    I think, to be honest, you were over complicating the issue ;-). All you need to do is scroll the scrolling element - Scroller will take care of the information display for you, since a scroll will trigger a scroll event (which Scroller does its work upon).

    I've put a small demo together here:
    http://live.datatables.net/igIg/1/edit

    Allan
  • tangerinetangerine Posts: 3,365Questions: 39Answers: 395
    Of all the stupid things to overlook...IE had javascript disabled. My apologies.
    It now has the same result as the other two.
  • visceralistvisceralist Posts: 33Questions: 0Answers: 0
    @allan

    thank you for the chat last night as well, and thanks for taking that kind of time. You've captured my issues rather nicely and this exactly what I needed and there's, I should add, no surprise that I over-complicated the matter. do accept my apologies on that - I did say I owe you a pint or two :)

    I have small question that I know the client will (and have in the past) ask:

    In your demo, if you note as you are paging down, with every page down, the top rows align perfectly until it gets to the row containing the name 'Jonas Alexander' and from there, the top rows are not fitting/aligned at the top of the table. In our case, the first td of each row contains a button and the client wants the the rows to always fit at the top each each page down so the text of the button is fully visible. Is there a way to ensure that a row fits at the top fully or no?

    I am okay I guess if there is no way, but thought I ask.

    thank you a world.
    cheers,
  • visceralistvisceralist Posts: 33Questions: 0Answers: 0
    @tangerine,
    thank you for your input on this too.
  • tangerinetangerine Posts: 3,365Questions: 39Answers: 395
    @visceralist - you're welcome. Sorry I wasn't more useful!
  • visceralistvisceralist Posts: 33Questions: 0Answers: 0
    it's quite alright - Alan certainly attended to my deep confusion - next time :)
  • allanallan Posts: 63,679Questions: 1Answers: 10,498 Site admin
    So basically you want to be able to see a whole number of rows, rather than cutting one off part way through? You just need to adjust your scroll container height to be an integer multiple of the row height. You could calculate this for what you assign to sScrollY / scrollY if your table is fully styled before the DataTable initialises, or you can adjust the height like I have in this example: http://live.datatables.net/xiv/1/edit (this shows the bug that tangerine noted about the row numbers being rounded down - I'll fix that soon).

    Allan
This discussion has been closed.