material-components / material-components-web

Modular and customizable Material Design UI components for the web
https://material.io/develop/web
MIT License
17.14k stars 2.15k forks source link

Add column sorting to Data Table component #5095

Open fiznool opened 5 years ago

fiznool commented 5 years ago

Feature Request

Add column sorting to the Data Table component.

Proposed solution

The Material spec describes the ability to sort a data table column. This isn't currently present in the MDC Web implementation. It would be great if the Data Table component could support this out of the box.

Alternatives considered

If this feature is needed, the only option is to implement it within the application codebase.

Additional context

Spec screenshots

components-datatables-interaction9

components-datatables-interaction7

abhiomkar commented 4 years ago

Thanks for creating this issue. I'm going to use this issue to track all the things related to MDC Data Table sorting feature.

macwier commented 4 years ago

I can see that there is sorting in the version 7 and it seems to be working pretty good. One question: Can I somehow set the sorting programatically? I can make the HTML to show the arrow in given direction, but once I click it, it just 'resets' and I can't really see any 'sort(column, direction) method. So far, the only way I can get initiall descending sort on a column is to programatically click twice on the header. Would be great if the MDCDataTable exposed some API to interact with this.

alestiago commented 3 years ago

Is there any updates to this? Is there a minimum working code example?

funkysoldier commented 3 years ago

Find this issue, but don't find the answer so I wrote this implementation for single sorting without frameworks (using some jQuery). After create table apply this event processing for all sortable columns:

let headers = document.querySelectorAll('.mdc-data-tableheader-cell--with-sort'); // add events for headers clicking headers.forEach((header) => header.addEventListener('click', (e) => { // find header you need because event can fired on different child elements let th = $(e.target).closest('th'); // if it's already sorted change dirrection if ( th.hasClass('mdc-data-tableheader-cell--sorted') ) th.toggleClass('mdc-data-tableheader-cell--sorted-descending'); // clean previously sorted info and arrows $('.mdc-data-table th').removeClass('mdc-data-tableheader-cell--sorted'); // add ony one header to sort th.addClass('mdc-data-tableheader-cell--sorted'); // check if need descending sorting let desc = th.hasClass('mdc-data-tableheader-cell--sorted-descending'); // do sorting sortTable(th.attr('data-column-id'), desc); }));

And a sorting function to compare elements in data array:

function sortResources(column, desc) { dataArray.sort((a, b) => { if (!desc) return a[column].localeCompare(b[column]); else return b[column].localeCompare(a[column]); }); // than update table (without thead section) }

Hope I can help someone! Good luck!