plumdog / flask_table

Because writing HTML is fiddly and all of your tables are basically the same

Home Page:http://flask-table.readthedocs.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Creating a sortable table with toggling of the sort direction column

avagut opened this issue · comments

I have gone through the examples and I have successfully created a sortable table which is working brilliantly. I did not manage to see any options for allowing the sorting of a column to be toggled, ie if sort direction is asc after first clicking of the header, a second clicking the header results in the sort direction reversing to desc.
Please advise if this already is available or if it is to added at some point in the future.

Hi!

First off, I think that this is a area where the docs are a bit lacking. I will add some more explanation to the section in the README which doesn't really mention this at present.

Toggling of sortable columns is supported (though it is fairly basic - you can only sort by one column).

Some example code:

from flask_table import Table, Col


class MyTable(Table):
    allow_sort = True
    name = Col('Name')

    def sort_url(self, col_id, reverse=False):
        url = 'myurl/'
        if reverse:
            url = '{}?reverse=true'.format(url)
        return url
            
print '# No sort_by'
print MyTable([dict(name='name1')]).__html__()
print '-'*4
print "# sort_by='name'"
print MyTable([dict(name='name1')], sort_by='name').__html__()
print '-'*4
print "# sort_by='name', sort_reverse=True"
print MyTable([dict(name='name1')], sort_by='name', sort_reverse=True).__html__()

which outputs:

# No sort_by
<table>
<thead><tr><th><a href="myurl/">Name</a></th></tr></thead>
<tbody>
<tr><td>name1</td></tr>
</tbody>
</table>
----
# sort_by='name'
<table>
<thead><tr><th><a href="myurl/?reverse=true">↓Name</a></th></tr></thead>
<tbody>
<tr><td>name1</td></tr>
</tbody>
</table>
----
# sort_by='name', sort_reverse=True
<table>
<thead><tr><th><a href="myurl/">↑Name</a></th></tr></thead>
<tbody>
<tr><td>name1</td></tr>
</tbody>
</table>

Some important things to notice: first that in this example here I'm not actually doing anything to do with a) deciding how to sort based on a url or b) actually ordering the items - I'm just configuring what the <th>s should show. Second is that when you allow a table to be sortable, you must implement the sort_url method that should construct a url using the name of column and the sort boolean that the heading will link to - it is up to your view code to do the right thing when someone clicks that link - the only place where flask_table will help you out for this bit is that once your view has got the column and direction from the url, you should pass them (as sort_by=... and sort_reverse=...) when constructing the table. This is how the table can decide how to present the <th>s.

For a more full example, see sortable.py, and in particular that line where we create the table. It might be useful to make a copy of that example file and try experimenting with bits of it.

I hope that clears up some of how this works. Let me know if not though.

Hi,
Thank you very much, I hadn't grokked the separation between what the sort url function was doing and what my "datasource function" needs to do separately. I used the below and its working well.
Many thanks for this wonderful library.

def build_users_list(sort, reverse):
"""Build up a user list and display the data sorted
sorted by direction.
"""
if sort is None:
sort = 'user_name'
reverse = 'asc'
if reverse:
reverse = 'desc'
else:
reverse = 'asc'
totalsort = str(str(sort) + ' ' + str(reverse))
users_list = models.User.query.order_by(totalsort).all()
return users_list