Can't figure out why sScrollY corrupts the Columns's size and alignement

Can't figure out why sScrollY corrupts the Columns's size and alignement

ciaobenciaoben Posts: 21Questions: 0Answers: 0
edited January 2014 in DataTables 1.9
I need to use sScrollX and ScrollY property for my datatables. But simply adding one of this property cause a lot of problems with size and alignemnt of the columns.

Here is a simple re-production of my table. In reality i use an Ajax call to fill my table. but i replied some data for this example:

http://live.datatables.net/Ikis/1/edit

Here is a pic of my real page:

https://www.evernote.com/shard/s44/sh/5a7c2a79-d265-4461-965b-9a65625cdf6d/855d7875b0c9e960cc533e82c5717622

Can someone explain me this behavior ?
«1

Replies

  • allanallan Posts: 63,498Questions: 1Answers: 10,470 Site admin
    Looks like you are initialising the table when it is hidden. That means that the elements have no height or width, so it isn't possible for DataTables to currently align the columns. Use fnAdjustColumnSizing when the table is made visible to resolve.

    Allan
  • ciaobenciaoben Posts: 21Questions: 0Answers: 0
    edited February 2014
    Hi, alan. I'm sorry but i can't make it work with fnAdjustColumnSizing(). I tried to bind the resize of the page with it, or even firing it with a button. Nothing happens!

    Even if you try to use it in my live.Datatables, it doesn't work. Can you please me show an example in my fiddle?
  • ciaobenciaoben Posts: 21Questions: 0Answers: 0
    Here another simple example...

    http://live.datatables.net/iQeZ/1/edit
  • allanallan Posts: 63,498Questions: 1Answers: 10,470 Site admin
    On the console:

    > Uncaught ReferenceError: oTable is not defined

    Probably isn't going to help. Fixed: http://live.datatables.net/iQeZ/2/edit

    It seems to work either way for me.

    Allan
  • ciaobenciaoben Posts: 21Questions: 0Answers: 0
    Yes i noticed but it's not that the problem. Help me understand.... i 'm filling the datatable with a custom ajax call who return me an array of data, here is a snippet of the ajax initialisation code:

    [code]
    "sAjaxSource":"/async_popula/" ,
    "sAjaxDataProp":"dati.0"
    [/code]

    then, i'm giving the appropriate value to each column:

    [code]
    "aoColumns": [
    { "mData": "codice"
    },
    { "mData": "descrizione"
    },
    { "mData": "flag_banca"
    }
    [/code]


    Tell me if i'm wrong... the problem here is that dataTable calculate the size of the visibile header when the data are not load yet, right?!

    If it is the problem, how do you suggest to use fnAdjust? or any other solution?
  • allanallan Posts: 63,498Questions: 1Answers: 10,470 Site admin
    You are correct - thank you for explaining the issue - I didn't understand before.

    DataTables 1.9- does not wait for the data to be loaded. DataTables 1.10 does.

    With 1.9- you can use:

    [code]
    fnInitComplete: function () {
    this.fnAdjustColumnSizing();
    }
    [/code]

    to adjust column sizing once the data has been loaded. This doesn't have anything to do with corruption of the header - that is something else.

    Allan
  • ciaobenciaoben Posts: 21Questions: 0Answers: 0
    edited February 2014
    thank you, but while i was waiting for your answer i tried a differente solution to avoiding the problem:


    I write the ajax request in order to write the table body on the html page. After that, i've made a :

    [code]

    $('#clickme').on('click', function(){

    datatabla();
    });
    [/code]
    which on click fires the dataTable() initialisation:


    [code]
    function datatabla(){
    var table=$('#datatable_pagamento').dataTable( {

    "sScrollY":200
    });
    [/code]


    This should give no problems, because the dataTable function is the simpliest of the dataTable() usage. But i don't know why, this is the result:


    https://www.evernote.com/shard/s44/sh/4f20780b-5ecb-4894-abaf-45b99dde4bfc/6305c0148ecf8b3d3b4e11df91132db7/res/23cfb05b-3bcb-4430-b1b4-34cf02e786be/resource.jpg?resizeSmall&width=832

    i try to add the Adjust, but literally NOTHING happens.

    I'm not using any other library, the page of the screenshot have no style (except a border: solid 1px black) and no other js library embed beside datatable.


    i'm losing my mind
  • allanallan Posts: 63,498Questions: 1Answers: 10,470 Site admin
    I get:

    > Access denied.

    when clicking on your evernote link.

    I really need a link to a page showing the problem to be able to help. I'm just guessing at the moment and the live site links above appear to work as expected unless I'm missing something.

    Allan
  • ciaobenciaoben Posts: 21Questions: 0Answers: 0
    Hi, sorry but it was a page on production so i tried to replicate the problem on a open page. Here is a link:


    http://acs-web.it/test/esperimenti.php


    i left out the ajax call, but the problem is the same. I'll wait for your opinion :)
  • allanallan Posts: 63,498Questions: 1Answers: 10,470 Site admin
    Brilliant - thanks for this. For some reason Safari was displaying it correctly, but Chrome not.

    Can you try with DataTables 1.10 a dev version of which is on the downloads page ( http://datatables.net/download ). I believe the issue is fixed there (I've just tried downloading your page and it works okay - or at least it would when Ajax loading with object data).

    Allan
  • ciaobenciaoben Posts: 21Questions: 0Answers: 0
    edited February 2014
    i tried on my production page and it is still the same.. do you prefer i update also the test page i gave you?


    Edit: i confirm to you that on chrome doesn't work, while on firefox works properly... how can i do?
  • allanallan Posts: 63,498Questions: 1Answers: 10,470 Site admin
    Yes, please update.
  • ciaobenciaoben Posts: 21Questions: 0Answers: 0
    ok, done it. On my safari it doesn't work either, like on chrome. On firefox instead work quite well. It starts giving me problems when the widnow width is around 1100 px.


    Here the link again with datatable 1.10: http://acs-web.it/test/esperimenti.php
  • allanallan Posts: 63,498Questions: 1Answers: 10,470 Site admin
    > border-collapse: collapse;

    You have `border-collapse: collapse` set in this example. If you remove that it should work. Border collapse is simply impossible to deal with due to the way the browser layout algorithm works.

    The header table contains different information than the body table, so even although the widths are applied exactly the same (which you will be able to see in the inspector) they are shown with different widths. Removing the collapse property will fix that.

    Allan
  • ciaobenciaoben Posts: 21Questions: 0Answers: 0
    edited February 2014
    it's not that the problem... try to eliminate it from chrome DEV Toold and click the button... it doesn't work anyway. In 10 minute i'll be on the pc and delete it, but i can say you for sure that it's not that the problem!
  • ciaobenciaoben Posts: 21Questions: 0Answers: 0
    edited February 2014
    While eating lunch i was reading the code from the DataTable.js that should adjust the cloned header width, and the problem is probably in sWidthOrig (line 3857). With 2 same sized windows on Chrome and Firefox the width are set with 2 completely different values... how is thta possibile?


    anyway, i updated the link, no border-collapse now, you can refresh the page and try (i've also cleaned up the js file, know you can read it easily)
  • allanallan Posts: 63,498Questions: 1Answers: 10,470 Site admin
    Simply adding `cellspacing="0"` to your HTML table allows it to work as expected. Or use `border-spacing: 0;` in your CSS.

    This is the latest DataTables stylesheet which you might find useful: https://github.com/DataTables/DataTables/blob/master/media/css/jquery.dataTables.css
  • ciaobenciaoben Posts: 21Questions: 0Answers: 0
    I don't know if you have tried it after adding [code]cellspacing="0"[/code], but on my chrome doesn't change anything. i'm testing on a 1280 width monitor and the alignement and the width of the header doesn't go well.


    Here is a new link with the new css, and the cellspacing: http://acs-web.it/test/esperimenti.php
  • allanallan Posts: 63,498Questions: 1Answers: 10,470 Site admin
    I did try it and it worked fine.

    You appear to have added additional CSS to your example `box-sizing: content-box;` for example.
  • ciaobenciaoben Posts: 21Questions: 0Answers: 0
    Excuse me, but the only style file that is linked with that page is the newcss.css that is the datatable style you linked me from github. In fact, the box-sizing: content-box is from you css file, on the line n° 211.


    Can you make a page with my code but corrected in your way?? so i could see the effective differences and if there are mistake in my code.
  • allanallan Posts: 63,498Questions: 1Answers: 10,470 Site admin
    Apologies for my misunderstanding.

    I've just spent the last hour and a half trying to figure out what is going wrong here, and its a bit of a nightmare. Basically, DataTables is calculating the column widths correctly, and then also applying them correctly to both the header and body tables. However - because there is different padding and different font-weight on the header and the body tags, the browser will realign the layout, completely ignoring the sizes set by DataTables.

    I've come up with three workarounds thus far:

    - Use the same padding and font-weight on both:
    http://datatables.net/clients/ciaoben/acs-web.it-border-font/test/esperimenti.php.html

    - Use white-space: nowrap:
    http://datatables.net/clients/ciaoben/acs-web.it-nowrap/test/esperimenti.php.html

    - Use `contentPadding` to add extra space into the calculated cell widths:
    http://datatables.net/clients/ciaoben/acs-web.it-contentPadding/test/esperimenti.php.html

    I'd obviously rather we didn't need a workaround - but I'm struggling at the moment to see how to fix it properly in the core. This needs more work unfortunately, and I rather suspect its going to take a good deal of time to get right.

    Allan
  • allanallan Posts: 63,498Questions: 1Answers: 10,470 Site admin
    Just been experimenting some more with a proper fix - and I think I might actually have it... The problem is that the scrolling body doesn't have the same content in its header cells as the actual header - thus different sizing rules apply.

    So the fix (I guess it seems obvious now) is to have that same content in the body's header cells, but wrapped in a div which is height:0. Test case showing this "real" fix: http://datatables.net/clients/ciaoben/acs-web.it-fixed/test/esperimenti.php.html

    Unfortunately 1.10.0-beta.1 hit today :-(. So it won't be in that. But I will commit this in tomorrow for the next beta unless I can think of some reason why it wouldn't work (it will slow performance down a little, but not too much I think).

    Allan
  • ciaobenciaoben Posts: 21Questions: 0Answers: 0
    edited February 2014
    thank you for the effort..the column's width are a little inaccurate again... but it's way better... now the problem seems to be when i use


    [code]"sAjaxSource":[/code]


    Because this will make calculate the width before the data are effectively there, right?

    i've tried and the columns are wrongly calculate again.. i also tried to use a click button with fnAdjustColumnSizing(); but nothing happens.


    here the code for the js with ajax load:

    [code]
    $(document).ready( function () {

    var table=$('#datatable_pagamento').dataTable( {
    "bSort":false,
    "sScrollY":300,
    "sScrollX":true,
    scrollCollapse: true,
    fnInitComplete: function () {
    this.fnAdjustColumnSizing();
    },
    "bServerSide": true,
    "sAjaxSource": "/async_datatable_pagamenti/",
    "fnServerParams": function (aoData) {
    aoData.push({
    "name": "id_login",
    "value": $("#h_id_login").val()
    });
    },
    columnDefs: [
    { targets: "_all", contentPadding: "mmmmm" }
    ]
    } );

    table.fnAdjustColumnSizing();


    [/code]

    but fnAdjustColumnSizing seems to have no effects... any suggestion?
  • ciaobenciaoben Posts: 21Questions: 0Answers: 0
    ok, found something that seems to be a solution by myself, simply adding some "mmm" to the :

    [code]
    olumnDefs: [
    { targets: "_all", contentPadding: "mmmmm" }
    ]
    [/code]

    and the columns seem to be better sized and alignement.

    Just to understand, what does exactly that property do?
  • allanallan Posts: 63,498Questions: 1Answers: 10,470 Site admin
    With 1.10 is should actually be the adjust column sizing is called automatically when using a JSON data source - there is no need for the fnInitComplete there. It is having no effect because, I guess, it is wrong already.

    Can you link me to an updated test page showing that please?

    Thanks,
    Allan
  • ciaobenciaoben Posts: 21Questions: 0Answers: 0
    edited February 2014
    i won't be in the office all day long, so i can't update the test page. I'll try to show you the problem with 2 screenshot, if you can't understand, tomorrow morning i'll update the test page.

    http://i.imgur.com/StqmbPe.png

    here you can see how the columns are not aligned at all.

    But when i click on a element like pagination number, or the menu of how many items will be showed, all goes in its place, and became perfect:


    http://i.imgur.com/EZUx88U.png

    The code is the same i've showed you on the previous post. Except fot fnInitComplete that i 've removed, as you suggested.
  • allanallan Posts: 63,498Questions: 1Answers: 10,470 Site admin
    That's very odd! Yes, if you would be able to update the example I'd very much appreciate that.

    I've just committed the fix that I suggested last night, but obviously there is still a bit more work to be done here...

    Allan
  • ciaobenciaoben Posts: 21Questions: 0Answers: 0
    Ok , so tomorrow in the morning i'll update the test page and let you know!
  • ciaobenciaoben Posts: 21Questions: 0Answers: 0
    Hi alan, tonight i figured out what's the cause of the problem. And it was in my code! Basically, that example table is on a page with multiple datatables, with some functions which hide the unused tables, and show every time the table you need.

    So it's obvious that the problem in the calculus it's hide()'s fault. In fact, moving the hide function in fnInitComplete make the magic happen :D


    i really, really thank you for your precious help and for having correct the bug!


    I would like to ask for a little advice, tell me if it's better to open another forum's post:

    Like i said before, i've a lot of datatables and i'm rewriting all properties and function a lot of times! There is a way to write some basic datatable config and extend with the particular needs every time i make a new one?


    Basically have a basic Datatable configuration and then extend it for every special case.
  • allanallan Posts: 63,498Questions: 1Answers: 10,470 Site admin
    Hi,

    Good to hear that this is working for you now :-).

    The fix that I've put in will be in 1.10.0 final and beta.2 - I'm planning to drop beta.2 early next week.

    > There is a way to write some basic datatable config and extend with the particular needs every time i make a new one?

    jQuery's $.extend method come into play here. What I would suggest doing is modifying DataTables defaults with something like:

    [code]
    $.extend( true, $.fn.dataTable.defaults, {
    paging: true,
    ordering: false
    // etc
    } );
    [/code]

    Then you can just initialise the table, and pass in extra override options if you want.

    Allan
This discussion has been closed.