Browser showing white space for table data that is hidden

Browser showing white space for table data that is hidden

kprohaszkakprohaszka Posts: 36Questions: 7Answers: 0

Hi all,

I am encountering a strange issue where sometimes the web browser will display a vertical scrollbar and extra white space for all the table data that is hidden via pagination. This happens in Google Chrome and Firefox and appears to be random. I suspect it is related to maybe how the JavaScript is loaded in the browser; if I resize the browser window, it resolves, but if I refresh the page, it goes back to the extra long scroll bar and unnecessary white space.

I can't share the page itself because it's locked behind a login, but I will share a screenshot highlighting the issue and my code.

    
#if(!$_PropertyTool.isEmpty($block))     #*as long as the block is not empty*#

    ##alphabet bar code goes here
    
## Dropdown department filter
    <div class="dropdown-container" style="text-align: left; margin-bottom: 20px;">
        <label for="department-filter" class="visually-hidden">Filter by Department</label>
        <select id="department-filter" aria-label="Filter by department">
            <option value="">Show All Departments</option>
        </select>
    </div>
    <div style="overflow-x: auto;" tabindex="0" >
    <table id="directory-table" class="display" style="width:100%">
        <caption id="empdir">Employee Directory</caption>
        <thead>
        <tr>
            <th scope="col">Photo</th><th scope="col">First Name</th><th scope="col">Last Name</th><th scope="col">Title</th><th scope="col">Department</th><th scope="col">Email</th><th scope="col">Phone</th><th scope="col">Location</th>
        </tr>
               
        </thead>
        <tbody>
        #foreach ($item in $_XPathTool.selectNodes($block, "//directory"))
            #set($nmcid = "")
            #set($lastname = "")
            #set($firstname = "")
            #set($phone = "")
            #set($email = "")
            #set($department = "")
            #set($title = "")
            #set($location = "")
            #set($ee_image = "")
        
            #set($nmcid = $item.getChild("nmcid").text)
            #set($firstname = $item.getChild("first").text)
            #set($lastname = $item.getChild("last").text)
            #set($phone = $item.getChild("phone").text)
            #set($email = $item.getChild("email").text)
            #set($department = $item.getChild("department").text)
            #set($title = $item.getChild("title").text)
            #set($location = $item.getChild("location").text)
            ## #set($ee_image = $item.getChild("photo").value)
 
 ## Check if the image exists based on employee ID.
            #set($imagePath = "/images/employees/${nmcid}.jpg")  
            
            ## Check if the image file exists at the specified location
            #if($_.locateFile("$imagePath", "Employee Site"))
                #set($ee_image = $imagePath)
            #else
                #set($ee_image = "/images/employees/blank_profile.jpg")  ## Specify a temporary image if not found.
            #end
 
            ## HIDDEN COLUMN Data
            #set($employeeType = "")
            #set($employeeType = $item.getChild("type").text)
       
            <tr>
                ## <td><div style="width: 60px; height: 80px; overflow: hidden;">
                ##     <img src="$ee_image" alt="$firstname $lastname headshot" style="width: 100%; object-fit: none;"/>
                ## </div></td>
                <td tabIndex="0"><div style="width: 60px; height: 80px;overflow: hidden;"><img src="$ee_image" alt="$firstname $lastname headshot" style="width: 100%; height: auto; object-fit: contain;"/></div></td>
                <td tabIndex="0">$_EscapeTool.xml($firstname)</td>
                <td tabIndex="0">$_EscapeTool.xml($lastname)</td>
                <td tabIndex="0">$_EscapeTool.xml($title)</td>
                <td tabIndex="0">$_EscapeTool.xml($department)</td>
                <td tabIndex="0">$_EscapeTool.xml($email)</td>
                <td tabIndex="0">$phone</td>
                <td tabIndex="0">$_EscapeTool.xml($location)</td>
            </tr>
        #end ##end foreach loop
        </tbody>
            <tfoot>
        </tfoot>
    </table></div>
#end
<script>
$(document).ready(function () {
    // Initialize DataTable
    var table = $('#directory-table').DataTable({
        layout: {
            top2Start: "info",
            top2End: "search",
            topStart: {
                pageLength: {
                    menu: [10, 25, 50, { label: 'All', value: -1 }]
                }
            },
            topEnd: "paging"
        },
        language: {
            search: 'Search all columns: '
        },
        order: [[2, 'asc']], // Default order by last name (2nd column)
        orderCellsTop: true,
        scrollX: true,
        // paging: true,  // Enable pagination
        // pageLength: 10, // Default page length
        initComplete: function () {
            this.api().columns([4]).every(function () {
                var column = this;
                var select = $('#department-filter'); // Reference the dropdown above the table
                select.on('change', function () {
                    var val = $.fn.dataTable.util.escapeRegex($(this).val());
                    column.search(val ? '^' + val + '$' : '', true, false).draw();  // Apply department filter
                });

                column.data().unique().sort().each(function (d, j) {
                    select.append('<option value="' + d + '">' + d + '</option>');
                });
            });
        }
    }); //end initialization function
    $('#directory-table').on('page.dt', function () {
        $('html, body').animate({
            scrollTop: $('#directory-table').offset().top -100
        }, 500); // Duration of scroll in ms (adjust as needed)
    }); //end scroll to top handler
       // Alphabet button click handler
    $('.alphabet-button').on('click', function() {
        var letter = $(this).data('letter');
        
        // Ensure we have a valid 'letter' before processing
        if (letter) {
            letter = letter.toLowerCase();
            table.column(2).search('^' + letter, true, false).draw(); // Filter by last name starting with selected letter
            $('.alphabet-button').removeClass('active'); // Remove active state from all buttons
            $(this).addClass('active'); // Set the clicked button as active
        }
    }); //end alphabet-button handler
    
    // "Show All" button click handler (clears all filters)
    $('#show-all').on('click', function() {
        // Clear global and column-specific DataTable searches
        table.search('').columns().search('').draw();
    
        // Reset department dropdown
        $('#department-filter').val('');
    
        // Remove 'active' class from any selected alphabet button
        $('.alphabet-button').removeClass('active');
    }); //end show-all handler

// KEYBOARD AND TAB NAVIGATION
//<![CDATA[
document.addEventListener("keydown", function(event) {
    var currentCell = document.activeElement;

    // Make sure the current focus is a table cell
    if (!currentCell || currentCell.tagName.toLowerCase() !== "td") return;

    var currentRow = currentCell.parentElement;
    var table = document.getElementById("directory-table");

    // Stop if table or row isn't found
    if (!currentRow || !table) return;

    var rowIndex = currentRow.rowIndex;
    var cellIndex = currentCell.cellIndex;
    var rowCount = table.rows.length;
    var colCount = currentRow.cells.length;

    var nextCell = null;

    if (event.code === "ArrowLeft") {
        if (cellIndex > 0) {
            nextCell = currentRow.cells[cellIndex - 1];
        }
    } else if (event.code === "ArrowRight") {
        if (cellIndex < colCount - 1) {
            nextCell = currentRow.cells[cellIndex + 1];
        }
    } else if (event.code === "ArrowUp") {
        if (rowIndex > 1) { // skip header row
            var aboveRow = table.rows[rowIndex - 1];
            if (aboveRow && aboveRow.cells.length > cellIndex) {
                nextCell = aboveRow.cells[cellIndex];
            }
        }
    } else if (event.code === "ArrowDown") {
        if (rowIndex < rowCount - 1) {
            var belowRow = table.rows[rowIndex + 1];
            if (belowRow && belowRow.cells.length > cellIndex) {
                nextCell = belowRow.cells[cellIndex];
            }
        }
    } else if (event.code === "Escape") {
        currentCell.blur(); // Remove focus
    }

    if (nextCell) {
        nextCell.focus();
        event.preventDefault();
    }
});
//]]>
}); //end document ready function
</script>


This question has an accepted answers - jump to answer

Answers

  • kthorngrenkthorngren Posts: 21,947Questions: 26Answers: 5,068

    Styling issues are difficult to troubleshoot without being able to see the problem in a running test case. I copied most of your code into this test case just to see the behavior:
    https://live.datatables.net/kodojiji/1/edit

    It doesn't replicate the issue. I would start by inspecting the white space to see what it belongs to. I suspect it's an element isn't dynamically resizing. If you still need help please update my test case or provide a link to a test case replicating the issue.
    https://datatables.net/manual/tech-notes/10#How-to-provide-a-test-case

    I assume you whited out the single row showing in the screenshot.

    Kevin

  • kprohaszkakprohaszka Posts: 36Questions: 7Answers: 0

    Hi Kevin,

    I don't have the issue viewing the page in my CMS, just when the page is published. I did white out the one row of data for privacy purposes, but it does highlight how the browser is interpreting it. When I inspect the code, it shows that the main container that holds the center column data (including the table) is getting a min-height added that is presumably equal to the full table data.

  • kthorngrenkthorngren Posts: 21,947Questions: 26Answers: 5,068
    edited May 8

    Datatables doesn't apply styling on containing div elements. It only knows about and styles the div elements it creates. The inline style applied to that div is outside the control of Datatables.

    What does the eq-col-ht class do?

    Please provide a test case replicating the issue so we can help debug.

    Kevin

  • kthorngrenkthorngren Posts: 21,947Questions: 26Answers: 5,068
    Answer ✓

    I updated my test case to include Bootstrap 5 (looks like you are using BS) and an example of the div you highlighted.
    https://live.datatables.net/wuwobori/1

    That div shrinks as the number of table rows displayed is reduced:

    There is no style attribute added to that div. It's something specific to your environment.

    Kevin

  • kthorngrenkthorngren Posts: 21,947Questions: 26Answers: 5,068

    As a side note, likely not causing this issue, but it doesn't look like you are using the Datatables Bootstrap style integration files for the version of BS being used. Use the Download Builder to get the appropriate files. Also you can use the Bootstrap table style classes to style the Datatable for things like stripping. See the HTML tab of this example.

    Kevin

  • kprohaszkakprohaszka Posts: 36Questions: 7Answers: 0

    Thanks Kevin, I will have to dig deeper and see what's causing the issue. And thanks for the note on bootstrap, I will work on adding that in correctly.

Sign In or Register to comment.