Click-Sort-Handler

Click-Sort-Handler

Jens GutzeitJens Gutzeit Posts: 22Questions: 0Answers: 0
edited December 2009 in General
Hello Allan (and others),

I'm in the process of adding some more icons to the THs to do some things here and there, what would be the best way to move the click event from the TH to a sub-span-element?

Jens

Replies

  • allanallan Posts: 63,695Questions: 1Answers: 10,500 Site admin
    Hi Jens,

    The easiest way to do what you are looking for would be to modify the selector for the 'click' event in the DataTables javascript file. Line 2347 (in the function _fnDrawHead) in 1.5.6 is the place for this. However, you might not what to modify the core file - at which point it becomes a bit trickier... If you just want single column sorting, then you could easily detach my click event and add your own to the TD which will call fnSort(). But if you want to keep multi-column sorting you would probably need to replicate the shift click logic.

    An alternative method, without modifying the core, might be to take advantage of the event bubbling that Javascript uses. You could add your own event handler to the THs which will cancel the propagation of the event, unless the original target was the span. That might be the cleanest solution - if a little convoluted...

    One other thing while I'm here... :-) Thanks very much for your post the in "How are you using" thread - great to hear about your experiences! There was one thing in particular that caught my eye:

    "DataTables is business ready (well, with a few small edges here and there)"

    I was wondering if you could elaborate on what the small edges are, so I can smooth them out?

    Many thanks,
    Allan
  • Jens GutzeitJens Gutzeit Posts: 22Questions: 0Answers: 0
    edited December 2009
    Hello Allan,

    thanks for your quick answer, I'll try the event-trick, first.
    I looked at the code around the click() line, I guess I'll also need to modify the usage of "this" a bit to get the correct column id, right?
    BTW: Will this be configurable some time in the future? It would be very cool if one could just put an element with a special class inside the th, that would automaticaly used for the sort-event if existent.

    Oh and the small edges: Nothing dramatic, first its the documentation, I think a "getting started" guide would be very great with information about "putting data in the table" and "getting data from the server", the second one with an in-depth documentation about the parameters passed to the server, there are quite a lot of them. Currently one has to look in API, then under examples ... it's a problem of most opensource projects, I admit.
    The other edge is the concept of using an integer-indexed array for the data, I think a associative array would be more natural, since it's basicaly the same thing we are used to when pulling data from our DB. This would make the parameters passed to the server easier to use, too. You might want to have a look at JQGrid. I don't like it because of other reasons, performance being one of them, but the column configuration is very natural with a key, and a second key that is passed to the server for sorting, very usefull. Currently I convert my datasets from "named properties" (like an associative array, or in grails/hibernate/gorm from my domain-class-object) to an integer-array, and doing the very same backwards when feeding the parameters into the database-criteriaBuilder, doesn't look very clean on the server-side.

    Jens
  • allanallan Posts: 63,695Questions: 1Answers: 10,500 Site admin
    Hi Jens,

    Quite right - you'll need to modify the line "if ( oSettings.aoColumns[i].nTh == this )" to be something like "if ( oSettings.aoColumns[i].nTh == this.parentNode )" as well, and then that will hopefully do it.

    This isn't a request that I've come across before, so I'm not sure if implementing it quite like this would be appropriate, but perhaps an API function which will (optionally) remove the event handler on the TH element, and then attach it to whatever other element you want would be more successful here. It would provide more flexibility, with the downside being that it would occur after the DataTable initialisation - although so fast no one would ever know.

    About your idea for a getting started guide - it's an interesting idea. I did have something along those lines in mind originally when writing the documentation, but wasn't sure hot much more to put in it than what I ended up with. For client-side initialisation, all you need is a table and then call $({selector}).dataTable().

    Of course it's considerably more complex when using server-side processing, but there is the server-side processing usage page which details the various parameters which need to be passed around: http://datatables.net/usage/server-side . I'm hoping to get a "library" of server-side scripts together in various different languages which people can use as a basis template, much as is done with my PHP one at the moment.

    Regarding the associative array for the JSON return, I had also considered this as an option but didn't implement it for a couple of different reasons: firstly I though that it was easier to simply return (output) a 2D array, and it would also take up less bandwidth, instead of repeating redundant information.

    having said that, DataTables does provide an alternative mechanism which is very similar to what you are looking for in an associative array. Using the sName parameter ( http://datatables.net/usage/columns#sName ) for each column will cause DataTables to send the column name to the server, which can then be processed for sorting/filtering etc, and also to return the columns "out of sequence" with what is displayed on the client-side: http://datatables.net/examples/server_side/column_ordering.html

    Would using sName fit in for you and help clean up the server-side?

    Thanks for the feedback,
    Allan
  • Jens GutzeitJens Gutzeit Posts: 22Questions: 0Answers: 0
    Hello Allan,

    sName looks great! You're right with the bandwith, I have not thought about this before, but it's true, especially with the long-column-keys we use here.

    Will do the event-handling stuff tomorow, I'll let you know how it works and perhaps write a small guide in here for others.

    > but perhaps an API function which will (optionally) remove the event
    > handler on the TH element, and then attach it to whatever other element you want would be
    > more successful here. It would provide more flexibility

    Indeed, that sounds to be a better way. Someone might want to put sorting in a (context)-menu or s.th. like that.
  • Jens GutzeitJens Gutzeit Posts: 22Questions: 0Answers: 0
    Had forgotten this one.
    In case someone has the same need, it was actually very easy to do by using the event-bubbling as allan said. Just set up an event-handler .click(fn), *before* datatables is called, then check event.target in there and call event.stopImmediatePropagation() if it's not referencing your sort-handler. This way, nothing else must be changed.

    For me, this looks like this:

    [code]
    dTableJQObj.find('thead th').click(function(event) {
    if (!$(event.target).hasClass('sorthandle')) {
    event.stopImmediatePropagation()
    }
    });
    [/code]

    I now have a small icon right to the label (with the "sorthandle" class set), dblclicking the label opens up a rename dialog, clicking the icon will do the sort :)
  • allanallan Posts: 63,695Questions: 1Answers: 10,500 Site admin
    Hi Jens,

    Thanks for this update. You might be interested to know that I've added a new core API function to DataTables in the 1.6 beta called fnSortListener which attaches the core sort listener to any element you want. This listener will take care of all the logic that is needed for 'shift' clicking etc.

    [code]
    /*
    * Function: fnSortListener
    * Purpose: Attach a sort listener to an element for a given column
    * Returns: -
    * Inputs: node:nNode - the element to attach the sort listener to
    * int:iColumn - the column that a click on this node will sort on
    * function:fnCallback - callback function when sort is run - optional
    */
    [/code]
    In combination with using an 'unbind' on the TH element it's now quite easy to customise the sorting handler :-). Thanks for the suggestion for this - I like this improvement in 1.6.

    Regards,
    Allan
  • Jens GutzeitJens Gutzeit Posts: 22Questions: 0Answers: 0
    Hello Allan,

    that's nice to hear. Another little edge I observed, I hope that is easy to fix. The paginate buttons should have some class to reflect if clicking them in the current state has effect, example: "go to first page" when one is already on there. From a usability point of view, one want to grey it out or do s.th. else with it to visualize that.

    Best regards,
    Jens
  • allanallan Posts: 63,695Questions: 1Answers: 10,500 Site admin
    Hi Jens,

    The pagination is slightly different for the different methods:

    1. Two button paging has a 'disabled' class (with a prefix) which could be checked for, and is used by my css to show that it would have no effect
    2. Full buttons with jQuery does a 'non-active' class, which should show this clearly.
    3. Full buttons without jQuery however is perhaps where you are seeing this. You are right - my demo css doesn't really cope with this - but with the custom classes and a bit of custom CSS I think it shouldn't be a problem to add that in for a designer.

    Regards,
    Allan
  • Jens GutzeitJens Gutzeit Posts: 22Questions: 0Answers: 0
    Oops, got it now. "paginate_button" for a disabled one is not very self-explanatory, so I missunderstood its meaning at first.
  • allanallan Posts: 63,695Questions: 1Answers: 10,500 Site admin
    Hi Jens,

    Yup - it would be good to tidy up a few things like that at some point - but in order not to break backwards compatibility with the rest of the 1.x series, it will probably be done at the next major upgrade (a while off... :-) ).

    Regards,
    Allan
This discussion has been closed.