Issue with tab navigation in headers with fixedColumns

Issue with tab navigation in headers with fixedColumns

chocchoc Posts: 95Questions: 11Answers: 8
edited November 4 in Free community support

Link to test case: https://datatables.net/extensions/fixedcolumns/examples/integration/select-checkbox.html

Description of problem: When using the Tab key to navigate through the table headers, it works fine towards the right side, but when using SHIFT+Tab, it is not possible to go completely to the very left side, but instead jump to the fixed columns. Furthermore, it is possible to go behind the fixed columns, as can be seen in the following screenshot from https://datatables.net/extensions/fixedcolumns/examples/initialisation/two_columns.html:

To reproduce, use the Tab key to first scroll to the right until the fixedColumn is displayed and then press Shift + Tab to go back.

Note the scroll bar here. It no longer scrolls when it is approaching to the left near the fixedColumns.

It should be handled (to scroll to the left automatically) when there are fixedColumns on the left so that it is not blocked by them.

The same goes for the fixedColumns at right: https://datatables.net/extensions/fixedcolumns/examples/initialisation/left_right_columns.html

Related source code that controls the scroll of header focus: https://github.com/DataTables/DataTablesSrc/blob/460081b587e82374ae2c1785d97a56667ca18499/js/core/core.scrolling.js#L126-L135

Replies

  • chocchoc Posts: 95Questions: 11Answers: 8
    edited November 4

    I have fixed it in my side.
    Below is my fix, hope it helps!

    P.S. I only use fixedColumn in the first column (start), so the logic to check if it is blocked is simpler. This means that I only check if the header is blocked by the first column. But I think the logic here is the same for the end fixedColumn.

    P.S. I use TAB to focus on the button inside th, so I adjust the focus list event for the button. That's why I notice this issue, because by default it listens to the focus of th, so my table doesn't scroll when I focus on the button inside th, which motivates me to fix the issue.

    The fix also detects whether the header on the right-hand side is partially visible and scrolls the table to make it fully visible when the header is focussed.

    $(scrollHead).on('focus', 'th > div > button', function (event) {
        const fixedColumnsWidth = $(scrollHead).find('th').first().outerWidth(true); // TODO I only consider the first column
        const scrollHeadWidth = $(scrollHead).width();
    
        const button = $(event.target);
        const th = button.closest('th');
    
        const headerOffset = th.position().left;
        const scrollLeft = scrollHead.scrollLeft;
    
        if (scrollLeft + fixedColumnsWidth > headerOffset && headerOffset > 0) {
            // Tab key to scroll to the left, but blocked by fixedColumn
            const targetScrollLeft = headerOffset - fixedColumnsWidth;
            $(scrollHead).animate(
                {scrollLeft: targetScrollLeft},
                {
                    duration: 200,
                    step: function (now) {
                        scrollBody.scrollLeft = now;
                    }
                }
            );
        } else if (headerOffset + th.outerWidth() > scrollLeft + scrollHeadWidth) {
            // Tab key to scroll to the right, but blocked by the boundary (could be fixedColumn end, but need to be modified)
            const targetScrollLeft = headerOffset + th.outerWidth(true) - scrollHeadWidth;
            $(scrollHead).animate(
                {scrollLeft: targetScrollLeft},
                {
                    duration: 200,
                    step: function (now) {
                        scrollBody.scrollLeft = now;
                    }
                }
            );
        } else {
            scrollBody.scrollLeft = scrollLeft;
        }
    
    
        // TODO I ignore footer issue as I don't use it
        if (footer) {
            scrollBody.scrollLeft = scrollLeft;
        }
    });
    

    The result:

    One problem is that sometimes not only one column width is scrolled when navigating to the right when the column is exactly at the border.

    As you can see in the gif above, it sometimes scrolls beyond one column width. But when navigating back to the left side, it seems to be fine (when approaching to left border: the fixedColumn), one column shift at a time.

    I'm not sure if this is native behavior or floating point error or maybe my logic is wrong.

  • allanallan Posts: 63,489Questions: 1Answers: 10,470 Site admin
    edited November 4

    Good call - I hadn't considered the focus event for tabbing through column headers with FixedColumns. I've added an issue to my trackers to get it sorted when I'm next working on FixedColumns.

    Allan

Sign In or Register to comment.