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

Already on GitHub? Sign in to your account

Add support to sort by columns #50

Closed
piranna opened this Issue Jan 5, 2013 · 8 comments

Comments

Projects
None yet
4 participants

piranna commented Jan 5, 2013

Add support so rows could be sorted clicking on the columns, maybe with the help of a user-defined sorting function (in the same way the sort() function works) on each sort-capable column. This would require that internally the plugin generates a tree structure storing the hierarchy of the rows but also this tree structure would be used so rows could be added randomly so the requeriment of rows being inserted in order would be deprecated.

Owner

ludo commented Feb 3, 2013

Thanks for submitting this. I don't think it would make sense to implement sorting functionality in this plugin, other plugins are much more capable of doing this. Also, I think it would be better to remove the tree when sorting on a different column as the tree structure would make no sense anymore.

@ludo ludo closed this Feb 3, 2013

piranna commented Feb 3, 2013

Would you be able to give some advices about this other plugins I would use?

piranna commented Feb 4, 2013

I was thinking in something like GTK TreeTable, where the "model" (the data) is an independent attribute that launch an event when gets modified and the TreeTable gets updated automatically. Maybe TreeTable would have (or receive) a tree structure with the parent-child relationship, and whem modifying it (maybe as simple as call a setter with the new tree structure) TreeTable would re-sort the rows according to this new tree structure.

I do think this would be useful functionality. I was using something called dynatree that supported a sortChildren method, and which worked pretty well for me. Unfortunately, it worked exclusively with hierarchical lists, and doesn't support the table layout that I need. I am going to need to spend some time implementing sorting one way or another. When I get it working I'll post a comment on how I did it.

piranna commented May 25, 2013

Good to know about it, thanks! :-)
El 24/05/2013 15:29, "Steve Donie" notifications@github.com escribió:

I do think this would be useful functionality. I was using something
called dynatree that supported a sortChildren method, and which worked
pretty well for me. Unfortunately, it worked exclusively with hierarchical
lists, and doesn't support the table layout that I need. I am going to need
to spend some time implementing sorting one way or another. When I get it
working I'll post a comment on how I did it.


Reply to this email directly or view it on GitHubhttps://github.com/ludo/jquery-treetable/issues/50#issuecomment-18404759
.

I got the sorting by column working for me. The way my HTML is structured I have data attributes on the rows that are used for the actual sorting. The column index is only used to keep track of whether the column is sorted ascending or descending. My data is structured such that I always have a single root node, and then I can have n children of that root node, each of which can have their own children. I typically only have 2 or 3 levels, but sometimes as many as 4 or 5. The treetable id and parent id look like "0" for the root node, "0::1", "0::2" for the first level children, and "0::1::1". "0::1::2" for the second level children.

The sorting is done recursively. For each parent row, sort the children, then detach them from the DOM and re-attach them after the parent row. Then look at each child row and if it has children, sort them as well.

Here is a snippet of what the html looks like:

<table id="tree" class="treetable">
    <thead>
        <tr>
            <th>
                <img id="expandAll" src="/Content/Images/expand-all.gif" alt="expand all" title="expand all">
                <img id="collapseAll" src="/Content/Images/collapse-all.gif" alt="collapse all" title="collapse all">
                <a href="javascript:sortTreeByName()">Name</a>
            </th>
            <th><a href="javascript:sortTreeByCO2()">CO2</a></th>
            <th><a href="javascript:sortTreeByCH4()">CH4</a></th>
            <th><a href="javascript:sortTreeByN2O()">N2O</a></th>
            <th><a href="javascript:sortTreeByTotal()">Total CO2e</a></th>
        </tr>
    </thead>

<tbody>
    <tr data-tt-id="0" data-name="2012" data-co2="1695287.23014" data-ch4="2574080.18030" data-n2o="1479.77833" data-total="4270847.21908" class="expanded" style="">
        <td><span class="indenter" style="padding-left: 0px;"><a href="#" title="Collapse">&nbsp;</a></span>2012-YR</td>
        <td class="nodeValue">1,695,287</td>
        <td class="nodeValue">2,574,080</td>
        <td class="nodeValue">1,480</td>
        <td class="nodeValue">4,270,847</td>
    </tr>
    <tr data-tt-id="0::3" data-tt-parent-id="0" data-name="Denver" data-co2="800152.60712" data-ch4="825566.94529" data-n2o="535.08098" data-total="1626254.64305" style="display: table-row;" class="collapsed">
        <td><span class="indenter" style="padding-left: 19px;"><a href="#" title="Expand">&nbsp;</a></span>Denver</td>
        <td class="nodeValue">800,153</td>
        <td class="nodeValue">825,567</td>
        <td class="nodeValue">535</td>
        <td class="nodeValue">1,626,255</td>
    </tr>
    <tr data-tt-id="0::3::11" data-tt-parent-id="0::3" data-name="Pneumatic Devices" data-co2="1359.02913" data-ch4="608953.24362" data-n2o="0.00000" data-total="610312.27642" style="display: none;">
        <td><span class="indenter"></span>Pneumatic Devices</td>
        <td class="nodeValue">1,359</td>
        <td class="nodeValue">608,953</td>
        <td class="nodeValue">0</td>
        <td class="nodeValue">610,312</td>
    </tr>

etc...

I ended up choosing a jquery plugin called tinysort for doing the sorting - http://tinysort.sjeiti.com/

The way the sorting is done looks like this:

function sortTable(columnIndex, dataName) {
    isAscending[columnIndex] = isAscending[columnIndex] == 'desc' ? 'asc' : 'desc';
    var root = $('#tree>tbody>tr[data-tt-id="0"]')[0];
    sortChildrenOfParent(root, columnIndex, dataName);
}

function sortChildrenOfParent(parentRow, columnIndex, dataName) {
    var parentRowAsJquery = $(parentRow);
    var id = parentRowAsJquery.attr('data-tt-id');
    var children = $('#tree>tbody>tr[data-tt-parent-id="' + id + '"]');
    children.tsort({ data: dataName, order: isAscending[columnIndex] });
    children.detach();
    parentRowAsJquery.after(children);
    for (var i = 0; i < children.length; i++) {
        var item = children[i];
        var itemAsJquery = $(item);
        var itemId = itemAsJquery.attr('data-tt-id');
        var childrenOfItem = $('#tree>tbody>tr[data-tt-parent-id="' + itemId + '"]');
        if (childrenOfItem.length > 0) {
            sortChildrenOfParent(item, columnIndex, dataName);
        }
    }
}

piranna commented May 28, 2013

Good job! :-) Only point is, data attributes are not recomended to use with
duplicated data that can be achieved directly from the HTML content, and on
the treetable table, it makes more sense because we are sorting from them,
too. Would you be able to take a look on it? Seems to be easy to replicate
the way you did it, maybe we can get it to integrated inside treetable
code... :-)

2013/5/28 Steve Donie notifications@github.com

I got the sorting by column working for me. The way my HTML is structured
I have data attributes on the rows that are used for the actual sorting.
The column index is only used to keep track of whether the column is sorted
ascending or descending. My data is structured such that I always have a
single root node, and then I can have n children of that root node,
each of which can have their own children. I typically only have 2 or 3
levels, but sometimes as many as 4 or 5. The treetable id and parent id
look like "0" for the root node, "0::1", "0::2" for the first level
children, and "0::1::1". "0::1::2" for the second level children.

The sorting is done recursively. For each parent row, sort the children,
then detach them from the DOM and re-attach them after the parent row. Then
look at each child row and if it has children, sort them as well.

Here is a snippet of what the html looks like:

etc...

I ended up choosing a jquery plugin called tinysort for doing the sorting

The way the sorting is done looks like this:

function sortTable(columnIndex, dataName) {
isAscending[columnIndex] = isAscending[columnIndex] == 'desc' ? 'asc' : 'desc';
var root = $('#tree>tbody>tr[data-tt-id="0"]')[0];
sortChildrenOfParent(root, columnIndex, dataName);}
function sortChildrenOfParent(parentRow, columnIndex, dataName) {
var parentRowAsJquery = $(parentRow);
var id = parentRowAsJquery.attr('data-tt-id');
var children = $('#tree>tbody>tr[data-tt-parent-id="' + id + '"]');
children.tsort({ data: dataName, order: isAscending[columnIndex] });
children.detach();
parentRowAsJquery.after(children);
for (var i = 0; i < children.length; i++) {
var item = children[i];
var itemAsJquery = $(item);
var itemId = itemAsJquery.attr('data-tt-id');
var childrenOfItem = $('#tree>tbody>tr[data-tt-parent-id="' + itemId + '"]');
if (childrenOfItem.length > 0) {
sortChildrenOfParent(item, columnIndex, dataName);
}
}}


Reply to this email directly or view it on GitHubhttps://github.com/ludo/jquery-treetable/issues/50#issuecomment-18565631
.

"Si quieres viajar alrededor del mundo y ser invitado a hablar en un monton
de sitios diferentes, simplemente escribe un sistema operativo Unix."
– Linus Tordvals, creador del sistema operativo Linux

expand all collapse all Name CO2 CH4 N2O Total CO2e
 2012-YR 1,695,287 2,574,080 1,480 4,270,847
 Denver 800,153 825,567 535 1,626,255
Pneumatic Devices 1,359 608,953 0 610,312

Since there is no sort() algorithm, it would be nice at least if there were a way to insert a node at a certain location. "loadBranch" always appends a new node as the last item. Since we don't have a way to invoke a sort, I would like to use a kind of insertion sort to make sure the nodes are displayed in the desired order, or maybe at least the option with move() to move a node within the same parent where the 2nd argument is the node to insert this one ahead of.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment