Filter and sorting on columns within a table #5385

Open
opened 2026-02-05 10:01:39 +03:00 by OVERLORD · 4 comments
Owner

Originally created by @danielsmith879 on GitHub (Jul 31, 2025).

Describe the feature you'd like

Would be useful to be able to filter and sort columns within a table on a page, I often find myself exporting a table to excel, sorting it or filtering it to just paste it back into a page. Would be useful feature if added.

Describe the benefits this would bring to existing BookStack users

Would save the export to excel to do basic data manipulation within tables.

Can the goal of this request already be achieved via other means?

Not directly within bookstack.

Have you searched for an existing open/closed issue?

  • I have searched for existing issues and none cover my fundamental request

How long have you been using BookStack?

1 to 5 years

Additional context

No response

Originally created by @danielsmith879 on GitHub (Jul 31, 2025). ### Describe the feature you'd like Would be useful to be able to filter and sort columns within a table on a page, I often find myself exporting a table to excel, sorting it or filtering it to just paste it back into a page. Would be useful feature if added. ### Describe the benefits this would bring to existing BookStack users Would save the export to excel to do basic data manipulation within tables. ### Can the goal of this request already be achieved via other means? Not directly within bookstack. ### Have you searched for an existing open/closed issue? - [x] I have searched for existing issues and none cover my fundamental request ### How long have you been using BookStack? 1 to 5 years ### Additional context _No response_
OVERLORD added the 🔨 Feature Request label 2026-02-05 10:01:39 +03:00
Author
Owner

@virtadpt commented on GitHub (Jul 31, 2025):

That would be helpful for a few things I have in my wiki, too.

@virtadpt commented on GitHub (Jul 31, 2025): That would be helpful for a few things I have in my wiki, too.
Author
Owner

@ssddanbrown commented on GitHub (Jul 31, 2025):

Thanks for the request @danielsmith879, this is somewhat related to #1518.

@ssddanbrown commented on GitHub (Jul 31, 2025): Thanks for the request @danielsmith879, this is somewhat related to #1518.
Author
Owner

@DonniDoc commented on GitHub (Aug 8, 2025):

Yes, filtering would be great in tables. I can help with sorting.

Settings -> Customization. Place the following script in the custom HTML header content. Then, in edit mode, double-click the table headers and they will be sorted. It's very simple sorting, but it works.

<script>

    // Hook into the WYSIWYG editor setup event and add our logic once loaded
    window.addEventListener('editor-tinymce::setup', event => {
        const editor = event.detail.editor;
        setupTableSort(editor);
    });

    // Setup the required event handler, listening for double-click on table cells.
    function setupTableSort(editor) {
        editor.on('dblclick', event => {
             const target = event.target;
             const parentHeader = target.closest('table tr:first-child td, table tr:first-child th');
             if (parentHeader) {
                 // Sort out table within a transaction so this can be undone in the editor if required.
                 editor.undoManager.transact(() => {
                     sortTable(parentHeader, editor);
                 });
             }
        });
    }

    // Sort the parent table of the given header cell that was clicked.
    function sortTable(headerCell) {
        const table = headerCell.closest('table');
        // Exit if the table has a header row but the clicked cell was not part of that header
        if (table.querySelector('thead') && headerCell.closest('thead') === null) {
            return;
        }

        const headerRow = headerCell.parentNode;
        const headerIndex = [...headerRow.children].indexOf(headerCell);
        const tbody = table.querySelector('tbody');
        const rowsToSort = [...table.querySelectorAll('tbody tr')].filter(tr => tr !== headerRow);
        const invert = headerCell.dataset.sorted === 'true';

        // Sort the rows, detecting numeric values if possible.
        rowsToSort.sort((a, b) => {
            const aContent = a.children[headerIndex].textContent.toLowerCase();
            const bContent = b.children[headerIndex].textContent.toLowerCase();
            const numericA = Number(aContent);
            const numericB = Number(bContent);

            if (!Number.isNaN(numericA) && !Number.isNaN(numericB)) {
                return invert ? numericA - numericB : numericB - numericA;
            }

            return aContent === bContent ? 0 : (aContent < bContent ? (invert ? 1 : -1) : (invert ? -1 : 1));
        });

        // Re-append the rows in order
        for (const row of rowsToSort) {
            tbody.appendChild(row);
        }

        // Update the sorted status for later possible inversion of sort.
        headerCell.dataset.sorted = invert ? 'false' : 'true';
    }
</script>
@DonniDoc commented on GitHub (Aug 8, 2025): Yes, filtering would be great in tables. I can help with sorting. Settings -> Customization. Place the following script in the custom HTML header content. Then, in edit mode, double-click the table headers and they will be sorted. It's very simple sorting, but it works. ``` <script> // Hook into the WYSIWYG editor setup event and add our logic once loaded window.addEventListener('editor-tinymce::setup', event => { const editor = event.detail.editor; setupTableSort(editor); }); // Setup the required event handler, listening for double-click on table cells. function setupTableSort(editor) { editor.on('dblclick', event => { const target = event.target; const parentHeader = target.closest('table tr:first-child td, table tr:first-child th'); if (parentHeader) { // Sort out table within a transaction so this can be undone in the editor if required. editor.undoManager.transact(() => { sortTable(parentHeader, editor); }); } }); } // Sort the parent table of the given header cell that was clicked. function sortTable(headerCell) { const table = headerCell.closest('table'); // Exit if the table has a header row but the clicked cell was not part of that header if (table.querySelector('thead') && headerCell.closest('thead') === null) { return; } const headerRow = headerCell.parentNode; const headerIndex = [...headerRow.children].indexOf(headerCell); const tbody = table.querySelector('tbody'); const rowsToSort = [...table.querySelectorAll('tbody tr')].filter(tr => tr !== headerRow); const invert = headerCell.dataset.sorted === 'true'; // Sort the rows, detecting numeric values if possible. rowsToSort.sort((a, b) => { const aContent = a.children[headerIndex].textContent.toLowerCase(); const bContent = b.children[headerIndex].textContent.toLowerCase(); const numericA = Number(aContent); const numericB = Number(bContent); if (!Number.isNaN(numericA) && !Number.isNaN(numericB)) { return invert ? numericA - numericB : numericB - numericA; } return aContent === bContent ? 0 : (aContent < bContent ? (invert ? 1 : -1) : (invert ? -1 : 1)); }); // Re-append the rows in order for (const row of rowsToSort) { tbody.appendChild(row); } // Update the sorted status for later possible inversion of sort. headerCell.dataset.sorted = invert ? 'false' : 'true'; } </script> ```
Author
Owner

@RonarPS commented on GitHub (Sep 18, 2025):

Filtering a list woould be a really nice feature. Is there a plan to implement such useful feature?
thx

@RonarPS commented on GitHub (Sep 18, 2025): Filtering a list woould be a really nice feature. Is there a plan to implement such useful feature? thx
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/BookStack#5385