BookStack icon indicating copy to clipboard operation
BookStack copied to clipboard

Table auto-sort

Open FMCUSystemAdmins opened this issue 6 years ago • 28 comments

Apologies if this has been submitted already, but I didn't see anything out there. We use quite a bit of tables in our documentation and have a need for them to be alphabetically sorted based on a particular column (in our case, the first column). We would like to request an auto-sort feature for tables that would sort them alphabetically based on a chosen column.

This would ease the management of tables that have quite a bit of rows as well as any future additions to the table.

FMCUSystemAdmins avatar Jul 02 '19 16:07 FMCUSystemAdmins

Thanks for the suggestion @FMCUSystemAdmins, I can see how this would be useful. Just to confirm, Do you desire this feature primarily as an editor of a table or as a viewer of a table?

ssddanbrown avatar Jul 03 '19 18:07 ssddanbrown

We’re finding a need for it from the editor standpoint.

FMCUSystemAdmins avatar Jul 03 '19 21:07 FMCUSystemAdmins

I've added +1 for this as a feature.

essdeeay avatar Feb 05 '20 22:02 essdeeay

Eventually a different table plugin would make sense. Something like a filter, sort, searchable table would be overpowered. But sorting in edit mode is also a great addition.

Mr-Sloth avatar Feb 12 '21 07:02 Mr-Sloth

I'd like to +1 this request. I would also like viewers of the page to be able to sort tables by any column by clicking on the column heading.

C493 avatar Aug 23 '21 19:08 C493

+1 for this request Mainly for viewers to sort tables on any desired column

gschirinzi avatar Sep 21 '21 11:09 gschirinzi

Even just having client-side table sorting when viewing a page would be very useful, as a starting point.

Montg0mery avatar Mar 25 '22 13:03 Montg0mery

For those who want sorting at least in the view.

As you can just copy the sorted Table and overwrite the current Content you can at least do some basic Formating with it without relying on something like 'LibreOffice-Calc'.

Custom HTML Head Entry

<!-- https://datatables.net -->
<script src="/localjs/jquery-3.6.0.min.js"></script>
<link rel="stylesheet" type="text/css" href="/localjs/datatables.min.css"/>
<script type="text/javascript" src="/localjs/datatables.min.js"></script>
<script>
$(document).ready(function() {
  $("[id^=bkmrk-sorted-table], table.sorted").DataTable({
    "language": {
       "url": "/localjs/de_de.json"
    },
    "order": []			
  })
})
</script>

I use this nginx-snippet, so i don't have to rely on external Sources.

location /localjs {
  autoindex on;
  alias /var/www/html/localjs/;
}

The autoindex can be left out naturally. image

crpb avatar Mar 25 '22 18:03 crpb

Could you share the content of that file :-)?

robert-andreas avatar Apr 11 '22 08:04 robert-andreas

Could be that someone did a few modifications in the office. I'm not all versed in Javascript :-). https://gist.github.com/crpb/705dbebe326573e6a36c12c415207d59

crpb avatar Apr 11 '22 11:04 crpb

Here's my no-library take for in-WYSIWYG-editor table sorting. Allows sorting via double clicking column headers. Supports inverse sort on re-sort of same column. Lightly tested on v22.11, Might have side-affects. Just needs to be added to the "Custom HTML Head Content" customization setting:

<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>

ssddanbrown avatar Dec 13 '22 19:12 ssddanbrown

Does anyone have the solution from @crpb working? I've obtained the jquery and datatable files from datatables.net. I've got an alias in Apache for a /localjs path. I've added the header script provided to BookStack. The browser console reports: uncaught sortable: el must be an htmlelement

I assume based on the header script I needed to add a table ID of bkmrk-sorted-table but that didn't help either.

Coros avatar Jul 18 '23 19:07 Coros

@Coros that datatables-hack broke here with the release in may and nobody "cried" enough to make it working again since then :P. I think it was v23.05 - maybe this helps to determine where it got mangled.

I currently implemented https://github.com/BookStackApp/BookStack/issues/1518#issuecomment-1349568398 which worked since then without any issues but of course it is "something different".

crpb avatar Jul 19 '23 17:07 crpb

@crpb Thanks for the update. I would really like the tables to be sorted by the user/viewer. We're migrating away from Confluence and have some rather large tables that help to have on demand sorting. I implemented the WYSIWIG editor change but it didn't seem to sort properly. It only reversed the order rather than sorting by alpha/num. I'll give it another try.

edit: I had a couple blank rows in the table and I think that caused problems. After removing those, it does sort properly in the editor.

Coros avatar Jul 20 '23 13:07 Coros

Here's my no-library take for in-WYSIWYG-editor table sorting. Allows sorting via double clicking column headers. Supports inverse sort on re-sort of same column. Lightly tested on v22.11, Might have side-affects. Just needs to be added to the "Custom HTML Head Content" customization setting...

@ssddanbrown: Not bad, but this allows sorting only for editors. It would be great if viewers can sort the tables, too.

TineUser avatar Jul 25 '23 09:07 TineUser

@ssddanbrown I'm so amped by your table sort hack above that I had to make this post. Thanks for this. I'll also take this opportunity to 👍 a feature to do this out of the box. I'd prioritize the feature for those with editor permissions (I'm biased), but also see the value for viewers.

A big 💯 for your work on Bookstack, too!!!

mlbarrow avatar Sep 03 '23 17:09 mlbarrow