# sortable - a tiny, vanilla JS table sorter Makes any table with **class="sortable"**, er, sortable. That is the user can click on a table header and change the sorting of the table rows. Just include the JavaScript and it will work. No function calls needed, all is done with an **eventListener**. (the CSS is not strictly needed, but makes it ~pretty and user friendly) - [sortable - a tiny, vanilla JS table sorter](#sortable---a-tiny-vanilla-js-table-sorter) - [Factoids](#factoids) - [...with a little help from my friends](#with-a-little-help-from-my-friends) - [Demo](#demo) - [A basic example](#a-basic-example) - [Non-sortable field](#non-sortable-field) - [...using `class` and `css`](#using-class-and-css) - [...using `css` only](#using-css-only) - [Indicators/arrows on the left side](#indicatorsarrows-on-the-left-side) - [Note about css/scss](#note-about-cssscss) - [Sort on value other than the one shown](#sort-on-value-other-than-the-one-shown) - [Alternative sorting](#alternative-sorting) - [Specify which column should be sorted](#specify-which-column-should-be-sorted) - [Ascending sort](#ascending-sort) - [Sort on load](#sort-on-load) ## Factoids - **954 bytes** minified. (545 bytes gzipped) Still under 1k! 🥳 - Works with **JavaScript generated tables**. (since we are using an eventListener) - **Lightning fast**. _Huge_ tables will make it slow and may freeze the browser, especially for mobiles, so you know... - Requires **thead** and **tbody**. - **cross browser**, ie9+ (I think, there have been a _whole_ bunch of changes since I last tested it on ie9 🤷) - ~~eventListeners attached to the rows _WILL_ be removed~~ - eventListeners are no longer removed! 😊 - NOT tested with React, Angular, Vue, etc. - Works with [Svelte](https://svelte.dev/)! ### ...with a little help from my friends - `` let's you [sort ascending](#ascending-sort) by default. Thanks [ Nikita Dunajevs](https://github.com/dunajevs)! - `data-sort-alt` in `tbody` > `td` allows for [alternative sorting](#alternative-sorting) while holding `shift` or `alt`. Thanks [wodny](https://github.com/wodny)! - `data-sort-col` in `thead` > `th` allows you to [specify which column should be sorted](#specify-which-column-should-be-sorted), in case you are using `colspan`, for instance. Thanks [Nick Kocharhook](https://github.com/nk9)! - **Nested elements** inside `th` now works. Thanks [mxve](https://github.com/mxve)! - [Sort on load](#sort-on-load) example. Thanks [Christian Petersson](https://github.com/Issen007) and [Abit Salihu](https://github.com/abitsalihu)! - Thanks to [chatcoda](https://github.com/chatcoda) for the `` / `` sorting bug fix! - If you have more than one ``, they will all be sorted. (Multiple ``s are not "allowed".) Thanks [GazHay](https://github.com/gazhay)! ## Demo You can find a simple demo on ## A basic example ```html
0
Role Name
Genius Rick
Sidekick Morty
``` _(The `span` is just there to prove that elements inside `th` works)_ ## Non-sortable field ### ...using `class` and `css` If you wish to disable sorting for a specific field, the easiest way is to add a class to it, like so: ```html Role Name ``` and then use css to block clicks. like so: ```css .sortable th.no-sort { pointer-events: none; } ``` ### ...using `css` only This is a bit trickier, but it doesn't require any changes to the html, so I guess it could be worth it in some cases. ```css /* the first column in every sortable table should not be sortable*/ .sortable th:nth-child(1) { pointer-events: none; } /* the seventh column in the second .sortable table should not be sortable*/ .sortable:nth-of-type(2) th:nth-child(7) { pointer-events: none; } ``` ## Indicators/arrows on the left side If you have text that is aligned on the right side, you may want to have the arrows on the left side. This is solved by adding a class to the css and using `::before` instead of `::after`. (You can of course use a pure css solution, without class names - just like with the [non-sortable field](#non-sortable-field) - but _that_ I will leave for you to figure out.) ```css .sortable th.indicator-left::after { content: ''; } .sortable th.indicator-left::before { margin-right: 3px; content: 'â–¸'; } /* etc. */ ``` > _Full example: [CSS](https://github.com/tofsjonas/sortable/blob/main/sortable-base.css), [SCSS](https://github.com/tofsjonas/sortable/blob/main/sortable-base.scss)_ ## Note about css/scss The `css/scss` in this repo was only ever meant as an example. It was never intended to be actually _used_. That said, if you're feeling lazy, here are two stylesheets you can use: ```html ``` ## Sort on value other than the one shown Using the `data-sort` attribute in `tbody` > `td` you can have one visible value and one sortable value. This is useful in case you have for instance sizes like kb, Mb, GB, etc. ```html
Movie Name Size Release date
Zack Snyder's Justice League 900MB 03/18/2021
The Sound of Music 1.5GB 12/09/1965
``` ## Alternative sorting If you click on a table header while holding **shift** or **alt** an alternative `data-sort-alt` attribute will override `data-sort`. ```html
Movie Name Size Release date
Something A B C
Something else D E F
``` ## Specify which column should be sorted Using the `data-sort-col` attribute in `thead` > `th`, you can sort on a different column than the one that was clicked. For instance if you want to have colspans. Like so: ```html Category Show Overall On Our Dates First Sold Out   Comedy Show 1 18/25 72% 3/4 75% 2022-07-30 ... ``` ## Ascending sort By adding `asc` to `table`, the default sorting direction will be **ascending** instead of descending ```html ... ...
``` ## Sort on load If you wish to sort a table on load, I would recommend doing something like this: ```html ...
Movie Name Size Release date
``` Combine this with `` to reverse the sort order. Or do `el.click()` twice! [![jsdelivr](https://data.jsdelivr.com/v1/package/gh/tofsjonas/sortable/badge)](https://www.jsdelivr.com/package/gh/tofsjonas/sortable)