Search code examples
datatablesbootstrap-5datatables-1.10

Datatable Column Mis-Alignment


Stack: Bootstrap 5, JQuery, Datatables

The issue: I have a page that uses Bootstrap navtabs. In one tab is a chart, and in another tab is a table created using Datatables. When the table tab has focus, the table styling is fine, even when the data changes. However, whenever another tab has focus and the data changes, the columns in the table cease to be aligned correctly. I think part of the issue is that some of the column titles are dynamic, with dynamic content demarcated by spans.

The data is controlled by a series of select menus, so whenever one of the select menus changes a series of processes is triggered, which includes updated the dynamic content and also refreshing the datatable.

I am not applying any custom classes or additional styling to the table. It looks like the issue is the datatable object trying to calculate col widths properly

Here's an example of the column headers not aligning properly: enter image description here

Has anyone encountered this before, or have any ideas for how to fix this problem?

HTML:

            <!-- Container for dynamic datatables -->
            <div class="col-sm-12">
                <div class="table-responsive">
                    <table id="datatable" class="table table-striped table-hover table-bordered table-sm" aria-label="Graduation Rates by Year" style="width:100%">
                        <thead>
                            <th>Cohort Year</th>
                            <th>Ethnicity</th>
                            <th>Pell Status</th>
                            <th>1st Gen. Status</th>
                            <th>Gender</th>
                            <th>Student Sub-Group: Count Enrolled</th>
                            <th>Student Sub-Group: Count Graduating within <span class="outcomeYear">6</span>-years
                            </th>
                            <th><span class="campus-system">Campus</span>-wide <span class="outcomeYear">6</span>-Year
                                <span class="outcomeTypeAbbr">Grad.</span> Rate
                            </th>
                            <th>Student Sub-Group: <span class="outcomeYear"></span>-Year <span class="outcomeTypeAbbr">Grad.</span> Rate</th>
                            <th>Gap (Difference from <span class="campus-system">Campus</span> Grad Rate)</th>
                        </thead>
                        <tbody></tbody>
                    </table>
                </div>
            </div>

JQuery:

//Initialize datatable
table = $('#datatable').DataTable({
    cache: false,
    scrollCollapse: false,
    paging: true,
    scrollX: true,
    pagingType: 'simple_numbers',
    lengthMenu: [[10, 25, 50, 100, -1], [10, 25, 50, 100, 'All']],
    searching: false,
    info: false,
    processing: true,
    serverSide: true,
    stateSave: true,
    ajax: {
        url: apiURL + '/table-data/',
        data: function (d) {
            d.campus = $campus.val();
            d.studentType = $studentType.val();
            d.cohort = $cohort.val();
            d.outcomeType = outcomeType;
            d.outcomeYear = outcomeYear;
            d.outcomeTypeAbbr = outcomeTypeAbbr;
            d.maxCohort = maxCohort;
        }
    }
});

JQuery for data change:

/* I have tried moving the dynamic text updates to before the table reload, and also using drawCallback to do these steps upon table draw. Neither changes anything. */

//Reload datatable
table.ajax.reload();

//Update dynamic text
$('.campus').html($campus.val());
$('.studentType').html($studentType.val());
$('.outcomeType').html(outcomeType);
$('.outcomeTypeAbbr').html(outcomeTypeAbbr);
$('.outcomeYear').html(outcomeYear);
$('.campus-system').html(cTxt);

Solution

  • This answer is actually from user andrewJames. He gave a possible solution in the comments that worked, but is declining to make it the solution.

    The reason the column headers were misaligned when the data loaded while the focus was on another tab is that DataTables needs a visible viewport to calculate column widths. andrewJames's suggestion, which I tried with success was to add a table redraw to the tab on an oblick event.

    Bootstrap's version of an onlick event for a navtab is actually the "shown.bs.tab" event. Here is my implementation of the solution:

    /**
     * When a tab is clicked.
     */
    $(document).on('shown.bs.tab', '.dashboard-nav-link', function(e){
         if(e.target.id == 'datatables_tab')
              table.draw('page');
    });