Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sorting hierarchical data, misc suggestions #618

Open
Noino opened this issue May 20, 2014 · 4 comments
Open

Sorting hierarchical data, misc suggestions #618

Noino opened this issue May 20, 2014 · 4 comments

Comments

@Noino
Copy link

Noino commented May 20, 2014

Hi.

I was looking for a way to sort hierarchical data, kind of like cssChildRow, but a step further where rows have children, and those children can have children and so on ad infinitum.

Currently, I'm hacking away with a custom textSorter and parser, but this is by no means pretty. I've got one column i want to sort with, which contains a integer value. I want all rows to be sorted by this column, but i also want the parent child relationships to remain. Currently I'm writing a data-tablesort_parentid="" in to every child <tr>, linking it to its parent, and building a sortable value in the form of an array in my custom parser.

$.tablesorter.addParser({ 
    id: 'array_sortValue', 
    is: false,
    format: function(s, table, cell, cellIndex) { 
        var r = $(cell).closest('tr'),
            a = [];
        do {
            a.unshift(r.children(':nth-child('+ (cellIndex+1) +')').html());
        } while( (r = $('#'+r.data('tablesort_parentid'))).length );
        return a;
    }, 
    type: 'text' 
});

And sorting it with a custom sorter, starting from the most significant sort value at 0, and working onward from there, returning as soon as there's a difference.

textSorter: {
    3: function(a, b, direction, column, table) {
        for(var i=0,l=a.length; i<l; i++) {
            if (i in b) {
                if (parseInt(a[i]) === parseInt(b[i])) {
                    continue;
                }
                return parseInt(a[i]) < parseInt(b[i]) ? -1 : 1;
            } else {
                return 1;
            }
        }
        return b.length > l ? -1 : 0;
    }
}, 

I recognize that this approach fails to yield accurate results if two or more parents have the same sort value, but this is the best i could come up with short of modifying the library itself.

Anyway, enough of my use-case and ugly half functioning hacks. What i really came here for was to write up a few suggestions/feature requests that i consider useful or otherwise simply making things clearer/easier.

a) Rework sort function extension to match that of the parser. Took me an hour to find out that you can't add your own sorting type (which i expected to find), but you have to override text (for something that in this case really isn't text).

b) Please add "native" support (that actually works 100%) for hierarchys

c) Not really part of my initial problem, but i would do appreciate it when library's don't add useless markup, specifically referring to them div's in my thead>tr. ( found it: $.tablesorter.restoreHeaders, not the most elegant solution tho to have to call this on the next line after initializing)

@Mottie
Copy link
Owner

Mottie commented May 20, 2014

Hi @Noino!

There is a fork of this project (not up-to-date), that allows for hierarchical sorting of child rows (see #410). I do plan on integrating it into this plugin eventually, but I haven't had the time to work on it.

Any of the changes made to this repository since v2.16.0 (widgets & pager) probably won't work with that fork, so make sure to get an earlier version of any desired extras.

@Mottie
Copy link
Owner

Mottie commented May 20, 2014

Can you elaborate on what you mean by reworking the sort function extension to match a parser?

As for the markup in the headers, yes the tablesorter-header-inner div is extra markup, but it is necessary for the positioning of icons (when the headerTemplate includes an icon) and the resizable widget to absolutely position the resizable handle in the header. For some reason Firefox will not allow a table cell element to have a position: relative property.

@Noino
Copy link
Author

Noino commented May 21, 2014

Thanks for info @Mottie , i'll check that fork out.

What i mean is, that instead of replacing (i assume this is what happens, may be just a questionable choice of word) the textSorter for a column, you would simply add a custom sorter to then utilize that sorter, and then initialize your tables:

$.tablesorter.addSorter({
    type: 'array', 
    sorter: function(a,b){}
});
$.tablesorter.addParser({
    id: 'json_array', 
    is: function(s){
        return Object.prototype.toString.call( JSON.parse(s) ) === '[object Array]';
    },
    format: function(s){ return JSON.parse(s); }, 
    type:'array'
});
$("table").tablesorter();

I feel this would make much more sense when creating your own, and would also be a cleaner way to replace any existing sorter, say if you wanted to make a localized text sorter. At the very least, you would not have to know beforehand that any given column needs to be sorted using a custom function, but you could rely completely on the parser to detect it.

@Mottie
Copy link
Owner

Mottie commented May 21, 2014

Cool, I really do like that idea!

I'm not sure when I'll find the time to implement it... it's already on my to-do list :)

@Mottie Mottie modified the milestone: Abelt Jan 20, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants