DataTables / Responsive

Responsive extension for DataTables, providing support for complex tables on all device screen sizes
Other
148 stars 86 forks source link

Responsive datatables inside bootstrap tabs require a forced resize #40

Closed bryanspears closed 9 years ago

bryanspears commented 9 years ago

I have a datatable inside each of a couple tabs. If you click each tab (thereby making sure each datatable has been rendered) then resize the window and click any tab other than the currently selected one the responsive code has a single column visible (minimum size).

Quick work around is $(window).resize() whenever a tab is selected, but there's obviously an issue with how display:none; visibility:hidden; (which is what bootstrap tabs do to the container) affects the resize handling code.

If there is a bug, great, fixing that would be best, but if not maybe expose a method to force a run of the datatable-responsive code?

bryanspears commented 9 years ago

I discovered the docs at https://datatables.net/extensions/responsive/reference/ which reveal recalc and rebuild methods. However, there isn't a responsive property on the object returned by a dataTables() invocation with which I could call the above methods. I have responsive tables working, so that's not the issue.

DataTables commented 9 years ago

However, there isn't a responsive property on the object returned by a dataTables()

No, but there is from $().DataTable() - see FAQs.

It sort of is a bug and sort of isn't... DataTables doesn't know when you make the hidden element visible, so you need to tell it that using the API (above). I have a plan that might allow it to work automatically, but there are issues in IE that might not be resolvable.

Either way, closing this issue.

bryanspears commented 9 years ago

Much appreciated. I wasn't aware the two were different. Kind of odd that there is two different interfaces for datatables.

rebuild/recalc work as intended now. No need for a resize call. Thanks.

DataTables commented 9 years ago

Yes, to some degree I regret that decision. $().dataTable() was the original form and worked like a standard jQuery plug-in (more or less...) in that it returns a jQuery object. Then in v1.10 I introduced a new API and needed a way to provide easy access to it - the standard method of using a capital to indicate a constructor class made sense. I perhaps should have called it dataTableApi or something but was worried about people thinking they needed to call both.

Anyway, it is done - not the best perhaps, but it does work :-)

ruimartinsptl commented 8 years ago

This is my solution:

$(document).ready(function() {
    $('a[data-toggle="tab"]').on( 'shown.bs.tab', function (e) {
        // var target = $(e.target).attr("href"); // activated tab
        // alert (target);
        $($.fn.dataTable.tables( true ) ).css('width', '100%');
        $($.fn.dataTable.tables( true ) ).DataTable().columns.adjust().draw();
    } ); 
});

It works for me, with "autoWidth": false,

In: http://stackoverflow.com/questions/8278981/datatables-on-the-fly-resizing/39157482#39157482

rubielchapal commented 7 years ago

You need to use the obsolete attributes cellspacing="0" width="100%" in the table. Libraries may use them and therefore should be necessary.

DataTables commented 7 years ago

style="width:100%" works perfectly as well as width="100%" - its up to you which you use. It is a good idea to use one of them though since it is exceptionally difficult to get a percentage value from an included stylesheet in Javascript, rather than an absolute pixel value.

Also you shouldn't need to use cellspacing="0" - that should be handled by the CSS.

farizluqman commented 6 years ago

@ruimartinsptl did the great job for this problem

RayDeanTech commented 6 years ago

I too, have dynamically generated DataTables nested in a set of Bootstrap's tabs class="tab-content". Additionally these tabs are part of the collapsible div class="collapse". Setting "autoWidth": false on the DataTable, and then removing the Bootstrap table-responsive class from the table allowed it to be visible, and fill the width of the tab. Just sharing for posterity.

sabari-venkatesh commented 6 years ago

@ruimartinsptl Thanks for the solution. It works for me even when the fixed columns are applied

asephidayat06 commented 6 years ago

window.onresize = function() { table.columns.adjust().responsive.recalc(); }

or window.onresize = function() { $($.fn.dataTable.tables(true)).DataTable() .columns.adjust() .responsive.recalc(); }

for tab

$("a[data-toggle=\"tab\"]").on("shown.bs.tab", function (e) { $($.fn.dataTable.tables(true)).DataTable() .columns.adjust() .responsive.recalc(); });

0xAnakin commented 5 years ago

@asephidayat06 you are a life saver!

g0rk4 commented 5 years ago

I fixed that problem by switching .columns.adjust() and responsive.recalc() methods : $("a[data-toggle="tab"]").on("shown.bs.tab", function (e) { $($.fn.dataTable.tables(true)).DataTable() .responsive.recalc() .columns.adjust(); });

Gorka

lenamtl commented 5 years ago

@g0rk4 I think you have mixt the names...

.columns.adjust(); https://datatables.net/reference/api/columns.adjust()

.responsive.recalc(); https://datatables.net/reference/api/responsive.recalc()

I think those are not existing .responsive.adjust() and .columns.recalc()

g0rk4 commented 5 years ago

@lenamtl, yes, i corrected that mistake.

Thank you

chiqui3d commented 5 years ago

Hello @DataTables , my problem is that it multiply the responsive modals, any solution for how I'm doing?

$(document).ready(function() {
    $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
        const target = $(e.target).data('target');
        const tab    = $(target);
        if(tab.find('table.responsive')){
            tab.find('table.responsive').DataTable().responsive.recalc();
        }
    });
});

Using only the following code, it does nothing.

$(document).ready(function() {
    $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
        $($.fn.dataTable.tables( true ) ).DataTable().responsive.recalc();
        $($.fn.dataTable.tables( true ) ).css('width', '100%');
        $($.fn.dataTable.tables( true ) ).DataTable().columns.adjust().draw();
    });
});
TechMky commented 5 years ago

I fixed that problem by switching .columns.adjust() and responsive.recalc() methods : $("a[data-toggle="tab"]").on("shown.bs.tab", function (e) { $($.fn.dataTable.tables(true)).DataTable() .responsive.recalc() .columns.adjust(); });

Gorka

This insight made my app work as I wanted. For someone looking, I had tabs as well a sidebar in my application. So what was happening was, the table was being created on the first load. Then, whenever the sidebar was collapsed or reopened, I was calling the columns.adjust().responsive.recalc()

Reordering it .responsive.recalc().columns.adjust() solved it.

arcanisgk commented 4 years ago

At the moment i am working in tha same scenario:

Example 1 Not Work

function Handler_RefreshTableInTabs() {
    $(document).on('shown.bs.tab', 'a[data-toggle="tab"]', function(event) {
        $($.fn.dataTable.tables(true)).DataTable().responsive.recalc();
        $($.fn.dataTable.tables(true)).css('width', '100%');
        $($.fn.dataTable.tables(true)).DataTable().columns.adjust().draw();
    });
}

Example 2 Not Work

function Handler_RefreshTableInTabs() {
    $(document).on('shown.bs.tab', 'a[data-toggle="tab"]', function(event) {
        $($.fn.dataTable.tables(true)).DataTable() 
        .responsive.recalc() 
        .columns.adjust();
    });
}

Example 3 Not Work

function Handler_RefreshTableInTabs() {
    $(document).on('shown.bs.tab', 'a[data-toggle="tab"]', function(event) {
        $($.fn.dataTable.tables({ visible: true, api: true })).DataTable() 
        .responsive.recalc() 
        .columns.adjust();
    });
}

LOG JS:

ajax.plug.js?20200413170242:806 Uncaught TypeError: Cannot read property 'recalc' of undefined
    at HTMLAnchorElement.<anonymous> (ajax.plug.js?20200413170242:806)
    at HTMLDocument.dispatch (jquery.min.js?20200413170242:2)
    at HTMLDocument.v.handle (jquery.min.js?20200413170242:2)
    at Object.trigger (jquery.min.js?20200413170242:2)
    at HTMLAnchorElement.<anonymous> (jquery.min.js?20200413170242:2)
    at Function.each (jquery.min.js?20200413170242:2)
    at S.fn.init.each (jquery.min.js?20200413170242:2)
    at S.fn.init.trigger (jquery.min.js?20200413170242:2)
    at l (tab.js:126)
    at i.t._transitionComplete (tab.js:209)
(anonymous) @   ajax.plug.js?20200413170242:806
dispatch    @   jquery.min.js?20200413170242:2
v.handle    @   jquery.min.js?20200413170242:2
trigger @   jquery.min.js?20200413170242:2
(anonymous) @   jquery.min.js?20200413170242:2
each    @   jquery.min.js?20200413170242:2
each    @   jquery.min.js?20200413170242:2
trigger @   jquery.min.js?20200413170242:2
l   @   bootstrap.min.js?20200413170242:6
t._transitionComplete   @   bootstrap.min.js?20200413170242:6
i   @   bootstrap.min.js?20200413170242:6
t._activate @   bootstrap.min.js?20200413170242:6
t.show  @   bootstrap.min.js?20200413170242:6
(anonymous) @   bootstrap.min.js?20200413170242:6
each    @   jquery.min.js?20200413170242:2
each    @   jquery.min.js?20200413170242:2
i._jQueryInterface  @   bootstrap.min.js?20200413170242:6
(anonymous) @   bootstrap.min.js?20200413170242:6
dispatch    @   jquery.min.js?20200413170242:2
v.handle    @   jquery.min.js?20200413170242:2

Display image

How can i fill the tab entirely???