Trouble initializing Scroller

Trouble initializing Scroller

airandfingersairandfingers Posts: 30Questions: 0Answers: 0
edited October 2011 in General
I get this error when I try to initialize Scroller on any of my DataTables:

Uncaught TypeError: Cannot call method 'appendChild' of undefined
Scroller._fnConstructScroller.js:296
ScrollerScroller.js:179
$.fn.dataTableExt.aoFeatures.push.fnInitScroller.js:712
_fnAddOptionsHtmljquery.dataTables.js:3760
_fnInitialisejquery.dataTables.js:2365
$.fn.dataTablejquery.dataTables.js:7436
e.extend.eachjquery-1.6.4.min.js:2
e.fn.e.eachjquery-1.6.4.min.js:2
$.fn.dataTablejquery.dataTables.js:6923
(anonymous function)status.js:285
f.extend._Deferred.e.resolveWithjquery-1.6.4.min.js:2
wjquery-1.6.4.min.js:4
f.support.ajax.f.ajaxTransport.send.d

My initialization settings are as follows:
'bUseRendered': false,
'sDom':'<"table_wrapper"ftSilp>'
I also tried lowering iDisplayLength to make a scroll-bar necessary on the table in question, but I got the same error.

I believe I've successfully duplicated this problem at http://live.datatables.net/uxadaw/2/edit

Thanks,
Aaron

Replies

  • allanallan Posts: 63,535Questions: 1Answers: 10,475 Site admin
    Hi Aaron,

    Thanks very much for setting up the demo page - that's really useful!

    The issue that you are encountering here is that Scroller expects scrolling to be enabled in DataTables, but your initialisation doesn't currently have that:

    [code]
    $('#my_jquery_table').dataTable(
    {
    'bUseRendered': false,
    'sDom':'<"table_wrapper"ftSilp>'
    });
    [/code]

    Scroller is only useful when you have DataTables scrolling enabled ( http://datatables.net/ref#scroll ). I should perhaps add a check in to give a warning message when scrolling isn't enabled, but to get it going all you need to do is add "sScrollY": "300px" like this: http://live.datatables.net/uxadaw/6/edit

    Regards,
    Allan
  • airandfingersairandfingers Posts: 30Questions: 0Answers: 0
    edited October 2011
    Glad the JSBin helps. It helps me, too, by forcing me to make my questions specific and explicit.

    The problems I'm having now are:
    1) The display at the bottom of the table sometimes shows incorrect information, especially when you navigate to the bottom of the table or when there are fewer rows than the sScrollY value could fit at once:

    EDIT: Found out that this is fixed by setting bScrollCollapse to true. ignore this question!
    2) When there are fewer rows than the sScrollY value could fit at once, the other DataTables elements - ilp, in the example below, appear below the theoretical bottom of the table, such that there's potentially a lot of white space between the bottom row and these other elements.
    Is there another, less explicit way to set the height of a table? I love the way that DataTables acts by default, but this explicit sScrollY value seems to be screwing me up.

    http://live.datatables.net/uxadaw/9/edit#javascript,html,live

    3) I can't seem to demonstrate this in JSBin (see the above link for my failed attempt at adding data using fnAddData, though I'm using this function successfully in my actual code), but when I initialize my DataTables with no data in them then add data using fnAddData, the column widths don't update. I looked through the reference and it looks like bAutoWidth is the setting in question, but I haven't changed this setting, and it defaults to true.

    See a screenshot of one of my tables, showing all three of the issues I'm talking about:
    http://tinypic.com/r/vrbqk1/7

    settings I'm initializing with:
    [code]
    'sPaginationType': 'full_numbers',
    'bJqueryUI': true,
    'sDom': '<"table_wrapper"ftSilp>',
    'sScrollY': '300px'
    'aaSorting': [ [0,'asc'], [1, 'asc'] ],
    'aoColumnDefs': [/*some rendering stuff and 'bUseRendered': false*/]
    [/code]

    Any tips for fixing any of these issues, or general suggestions for settings and/or styles to improve my table?
    I'm probably going to disable pagination for all tables except those that have many (several thousands) rows, but on the tables with pagination, I'd like the controls to look nicer. Here's what I'm getting, using more or less the settings above:

    http://tinypic.com/view.php?pic=25fuoa9&s=7

    What I'd like, if possible: well-spaced pagination buttons, with as many numbered page buttons as will fit across the width of the table (not counting the space taken up by the other pagination buttons).

    Anyway, thanks for your quick responses, and I hope to hear from you again soon! You mentioned that you're going away on your honeymoon next week.. congratulations! Did you just get married, or maybe you're getting married this weekend? Either way, congrats, and don't let my many questions spoil your vacation. I'll try to flush out as many questions as I can before you're gone, and you can deal with them at your convenience.
  • airandfingersairandfingers Posts: 30Questions: 0Answers: 0
    UPDATE: In looking through the reference for bScrollInfinite, I learned what bScrollCollapse does, and I now see that that option fixes my second question. So, please ignore that question.
  • allanallan Posts: 63,535Questions: 1Answers: 10,475 Site admin
    > 1) The display at the bottom of the table sometimes shows incorrect information

    This is a bug in Scroller 1.0.0 unfortunately. If you use Scroller 1.0.1.dev, which is available on the download page here: http://datatables.net/download/ , that will fix the issue.

    > 3) the column widths don't update

    If you call fnAdjustColumnSizing ( http://datatables.net/api#fnAdjustColumnSizing ) whenever you want to add new data to the table, that will run the DataTables automatic width calculation algorithm again and should adjust the columns as needed.

    > What I'd like, if possible: well-spaced pagination buttons

    I'd suggest including the media/css/demo_jui.css file which is included in the DataTables distribution, or looking in it for ideas of how to get the elements to look like what you want them to. Its just a class of adding a little padding and perhaps a float to the element :-)

    Regards,
    Allan
  • airandfingersairandfingers Posts: 30Questions: 0Answers: 0
    1) Thanks, the new version of Scroller works great and fixes that issue.

    CSS formatting) Thanks, that CSS file fixed my styles up nicely. I especially like the pagination controls - very slick.

    Remaining Scroller issues:
    fnAdjustColumnSizing doesn't appear to work when my tables are hidden, as they usually are when I'm updating them (I'm using jQuery UI tabs, and usually my tables are in ui-tabs-hide divs, which are given the property display:none)
    Is this the expected behavior for fnAdjustColumnSizing? Is there any alternative?
    The workaround I was developing was binding to the UI Tabs select event, finding all DataTables in this div and calling fnAdjustColumnSizing() on them; however, I can't seem to use DataTables methods by programmatically selecting the right node and trying to call methods on it.
    See http://live.datatables.net/uxadaw/12/edit for how I'm trying to select the table (though this might not be the best example - my commented fnAddData line above it also doesn't work, something for which I'd still like an explanation, if possible).

    2) bScrollCollapse doesn't seem to be working correctly for all but one of my tables, and that table is the only one that's not styled display:none, as described above.
    Does display:none break some parts of DataTables? If so, I could change display:none to positioning the divs way off-screen.
  • airandfingersairandfingers Posts: 30Questions: 0Answers: 0
    Bump?
    Sorry to bug you, Allan - I know you're on your honeymoon and all, but I'd really, really appreciate a response to this question before Monday (before Friday, if possible).

    I know that this is potentially a doozy of a question, so I'll try tonight to demonstrate this in JSBin.

    My backup plan is to hard-code calls to fnDraw() when a table's tab is selected (using jQuery UI Tabs' select event). Calling fnDraw() through Google Chrome's JavaScript console (once the tab in question is selected) works, so I'm confident that this workaround will work for me.
    I'd like to dynamically detect DataTables within the selected tab's div, but, as described above, I've been having problems doing so. Still, worst comes to worst, I won't do without - I'll just hard-code.

    I'll post again when I've got a working demo of this issue in JSBin (or once I've been thoroughly frustrated in attempted to recreate the issue in JSBin).
  • airandfingersairandfingers Posts: 30Questions: 0Answers: 0
    Minor update: I've gotten my workaround to work, binding the Tabs select event to redrawing every DataTable. I had to insert a 1-ms delay in the handler, for some reason - maybe the select event gets fired _before_ the relevant div is made visible.

    Anyway, my tables look and act fine now, so there's no rush on this issue. I'll post if I have any other trouble.
  • allanallan Posts: 63,535Questions: 1Answers: 10,475 Site admin
    edited October 2011
    Hi,

    Really sorry for the delay in getting back to you. Got very limited mobile signal where I am at the moment. Will be back home soon though :-).

    > fnAdjustColumnSizing doesn't appear to work when my tables are hidden

    This is correct. Basically when an element is display:none the browser doesn't calculate height/width for the element (since it doesn't have any) thus this function rather falls flat on its face. To have it do something useful you have to make the table visible. This can be done in a numbe of ways - 1. Make it visibility:hidden, 2. Stick it in a container div whIch has height:1px, or 3. Move it out of the visible area. Having said that, what you should be able to do is just call the resizing function when the table is made visible, and that will be fast enough to redraw score the user sees the old table.

    > I'd like to dynamically detect DataTables within the selected tab's div, but, as described above, I've been having problems doing so

    What you can do is something like: var t = $('table.display', tab).dataTable() (assuming your tables have a class of display and tab is the node that contains the table. Then call the API methods on that. If you have multiple tables from that selector you can loop over t for t.length calling the Api methods. To have DataTables work with a ta ls which is not index 0 in the selector above you need to set the iAipIndex ($.fn.dataTableExt.iApiIndex) parameter to the index you want (ie the loop number).

    Hope this helps!

    Regards,
    Allan
  • airandfingersairandfingers Posts: 30Questions: 0Answers: 0
    Hm, when I first saw this post I tried changing display:none to visibility:hidden, and it didn't seem to fix any of the problems I was having. Well, my call-fnDraw-on-every-table-upon-any-tab-change code appears to be working, so I'm going to leave this for now.

    I've been accessing DataTables objects as you described above, so thanks for that tip. It's especially useful for selecting and acting on a DataTable in the debugger console.


    On a slightly-related note, what's the best way to re-render the visible rows/cells (i.e. replace their values with that returned by a current call to fnRender())?
    I'm formatting timestamps as "X minutes/hours/days ago," and I need to update these values at least every minute to keep them accurate. I had assumed that fnDraw() would work, but it doesn't seem to.

    Thanks again,
    Aaron
  • allanallan Posts: 63,535Questions: 1Answers: 10,475 Site admin
    fnRender will intentionally run only once for the life time of a cell's information - i.e. it will run when you add the row (fnAddData) or when you update a cell (fnUpdate). If you need to update information in a cell you need to use fnUpdate ( http://datatables.net/ref#fnUpdate ) rather than directly manipulating the HTML (using innerHTML or $().html()) since DataTables doesn't know about these changes.

    Regards,
    Allan
  • airandfingersairandfingers Posts: 30Questions: 0Answers: 0
    edited November 2011
    Hm, I guess I could set a handler to call fnUpdate on every time-type cell (maybe only _displayed_ time-type cells) once every minute - at least I wouldn't be re-rendering my entire tables.

    Still, you understand why I want to rerender cells, right? The value in each cell isn't actually changing - only the rendered value is changing, as a result of my rendering function, which displays the time difference between the cell value and $.now(). So, fnUpdate with an unchanged value should work since it forces re-rendering, but really what would make sense for me is a fnRerender (or something to that effect).

    Not that I expect you to create that function for me ^^. I'm just surprised the need hasn't arisen yet - so many of the capabilities of DataTables are so dynamic, I'd be surprised if someone else hadn't encountered a similar problem and overcome it somehow..

    Thanks,
    Aaron
  • allanallan Posts: 63,535Questions: 1Answers: 10,475 Site admin
    Ah I see! I'm somewhat surprised that this hasn't come up before as well! Actually I'm vaguely surprised that I've not needed this myself before...

    Anyway - a rerender call is easily enough to wrap up into a plug-in API call: http://live.datatables.net/okahuf/edit#javascript,html :-)

    You'll be able to see that the call will just update a single cell - you give it a row and the column index - for example:

    [code]
    oTable.fnReRender( $('#example tbody tr:eq(0)')[0], 0 );
    [/code]

    So if you want to to all rows, you can either loop this call, or the API function can be modified to do the loop over oSettings.aoData.

    Hope this helps!
    Allan
This discussion has been closed.