Resize Table once and only once on Tabs switch

Resize Table once and only once on Tabs switch

MadBoyEvoMadBoyEvo Posts: 119Questions: 38Answers: 0

Link to test case:

https://codepen.io/MadBoyEvo/pen/dyppRyx

Description of problem:
I use DataTables with Tabs where a lot of Tables aren't visible at first sight.

I've been using following code on tab switch and it works great.

if ($.fn.DataTable.isDataTable("#" + table.id)) {
    try {
        $("#" + table.id).DataTable().columns.adjust().responsive.recalc();
        console.log('Fitting table with id ' + table.id);
    } catch (e) {
        console.log('Failed to fit table with id ' + table.id);
    }
} else {
    console.log('Skipping fitting table id ' + table.id);
}

However it's a problem because it resize tables on each tab every single time the tab switch happens. What is more if I have nested tabs it will resize tables on tabs that have content that is not yet visible because the tab hasn't been pressed yet.

What more is that with very large number of tables on each tab switching tabs take a lot of time because it basically resizes them over and over and over again.

So I this idea that I would track whichever table was resized at least once, save it and whenever I see it again, I'll just skip it.

    console.log("resize table started " + dataTablesInitializationTracker[table.id] + ' ' + table.id);
    if (dataTablesInitializationTracker[table.id] !== 'initialized') {
        if ($.fn.DataTable.isDataTable("#" + table.id))
            try {
                $("#" + table.id).DataTable().columns.adjust().responsive.recalc();
                console.log("Fitting table with id " + table.id)
                var tempTable = $("#" + table.id).DataTable();
                var tableContainer = $(tempTable.table().container());
                console.log(tempTable);
                //console.log(table);
                //console.log(tableContainer);
                //console.log(tempTable.visible);
                dataTablesInitializationTracker[table.id] = 'initialized';
            }
            catch (e) {
                console.log("Failed to fit table with id " + table.id)
            }
        else
            console.log("Skipping fitting table id " + table.id)
    } else {
        console.log("Already initialized table id " + table.id)
    }

This is part of function: resizeTable(table).

The idea works correctly with everything except for nested tabs or generally tabs that are not yet visible but were already refreshed.

How would I be able to check if table is visible to trigger that save? I don't think it makes sense to initialize any table until it's visible on the screen. If it's nested in tab, or placed on tab that's not yet activated it makes no sense to initialize it and causing user to wait.

In code on codepen it starts on line 2797. The issue is mostly visible within 1st tab. If you switch to 2nd tab, go back to 1st tab you will notice the nested tab that's currently open will be properly displayed. If you click on 2nd nested tab it will show DataTable that is not really initialized (even tho it's marked as one).

Any easy way to go around it?

This question has an accepted answers - jump to answer

Answers

  • kthorngrenkthorngren Posts: 21,173Questions: 26Answers: 4,923

    When clicking on Test 1 this code:

                        try {
                            var table = document.getElementById(id).querySelectorAll("table.dataTables");
                            table.forEach(resizeTable)
                        }
    

    finds all the child elements - 2 tables in this case:

    Maybe use querySelector() to get only the first selector??

    Kevin

  • MadBoyEvoMadBoyEvo Posts: 119Questions: 38Answers: 0

    It can be 2 tables, 5 tables, 50 tables. It's just an example to illustrate. It's all generated dynamically with PowerShell. I need to know how to get information on whether that table as I check foreach(resizeTable) is visible at that moment or not. If it's not visible I will skip the process. So that foreach is correct, but later on, I need to check visibility - and it's what I am missing - how can I tell if DataTable is visible to the user or not.

    RIght now I am searching with query selector for every table on current Tab. What I actually need, every table on the current tab that is visible (not part of another tab, or otherwise hidden instance.

  • kthorngrenkthorngren Posts: 21,173Questions: 26Answers: 4,923

    AFAIK Datatables doesn't have an API for the visibility of the table. Maybe this SO thread will give you some ideas of how to check for the table element being visible.

    What I actually need, every table on the current tab that is visible (not part of another tab, or otherwise hidden instance.

    That will be a solution provided by Javascript or jQuery methods not Datatables.

    Kevin

  • MadBoyEvoMadBoyEvo Posts: 119Questions: 38Answers: 0

    From what I see I the style doesn't change for a table that is "hidden" from the user view on the non-active tab. It's the same style for both tables meaning it's impossible to use style.visibility.

  • kthorngrenkthorngren Posts: 21,173Questions: 26Answers: 4,923
    edited December 2020 Answer ✓

    Yep. I guess thats the case. Was just providing that link as an example as I didn't dig into your code to see how you are handling tabs.

    Looking at your test case again it looks like your code uses the class name active for the visible tab. Maybe you can key off that. However it does look like the code doesn't keep up with the nested tabs. When Test 1 is active the nested tab class is also set active. When I click on Test 2 the nested tab from Test 1 still has the active class.

    There is not a way for Datatables to know if its being displayed or not. Its something you will need to handle based on your specific solution of using tabs.

    Kevin

  • MadBoyEvoMadBoyEvo Posts: 119Questions: 38Answers: 0

    Thank you

This discussion has been closed.