nasty behavior (bugs?) on search events triggered from column search inputs

nasty behavior (bugs?) on search events triggered from column search inputs

normadizenormadize Posts: 31Questions: 6Answers: 1

I was inspired by the example here here to add an input search box for column searching, which uses both change and keyup events.

var input = $('<input type="text" class="form-control" placeholder="Search, regex enabled">');
input.on('change keyup', function () {
  if (column.search() != this.value) {
    console.log('triggering search');
    column.search(this.value, true, false).draw();
  }
});

$(column.footer()).append(input);

datatable.on('search.dt', function () {
  console.log('search triggered');
});

Here's what happens when I type one character in the column search input (latest Chrome on windows)

  • the change keyup handler is correctly called only once (so far so good)
  • keyup triggers 2 search events (not good)
  • if I sort the column by clicking on its header, i get yet another search event triggered (not good)
  • change sometimes triggers 1 additional search event, sometimes triggers 3 additional search events when I click somewhere in the page (defocusing the input element), while sometimes it doesn't trigger any search events at all (inconsistent, not good)

I can try and do without change, but why are there 2 search events triggered for keyup and yet 1 more search event when sorting the column?

How much of the above is normal behavior and what can I do to have only one search event triggered?

Cheers

Replies

  • kmd1970kmd1970 Posts: 36Questions: 8Answers: 1

    firstly, you need to recreate your issue using jsfiddle. Take a look at this.

    http://jsfiddle.net/kmd1970/jz1zvvr1/

    Hope it helps.

  • normadizenormadize Posts: 31Questions: 6Answers: 1

    Thanks. I don't see the issue there. I need to debug further ... any tips would be appreciated!

  • normadizenormadize Posts: 31Questions: 6Answers: 1

    I can try to debug in Chrome to trace the events back to their origin and see what causes the duplicates, but I'm not exactly sure what to look for ... any hints?

  • normadizenormadize Posts: 31Questions: 6Answers: 1
    edited November 2015

    In my case a search event is triggered when ordering is triggered, whereas on the JSfiddle code that doesn't happen ... any clues as to why that could be? I didn't define any handler on dt.order.

    Debugging in Chrome shows that the event was triggered by the change keyup handler function but on the JSfiddle that happens only once. The change keyup handler is executed only once in my case as well, but two consecutive search events are then triggered, and I suspect it has something to do with the order function.

    The main difference is that I'm loading the data from a JS array.

  • allanallan Posts: 61,773Questions: 1Answers: 10,112 Site admin

    I've just put this little test case together this I believe reproduces the double search event that you are seeing: http://live.datatables.net/seroyodo/1/edit .

    This is caused by a bit of a flaw in the DataTables code for how it handles these events. Calling column().search() will cause the search to be executed, but so will draw() (which will do a full resort and filter).

    You could use the new page option of draw() to avoid this: http://live.datatables.net/bepakunu/1/edit .

    Although this is sub-optimal, it isn't quite as bad as it looks initially - DataTables' filtering code will see that there is no change in the search input and therefore that part of the code will execute very fast / almost immediately.

    This is most certainly an area that needs to be improved though!

    Allan

  • normadizenormadize Posts: 31Questions: 6Answers: 1

    Thanks Allan, I think that must be it! I'm loading the data from a JS array and call draw() at the end (do I have to?). I'll look at your suggestions and report back.

  • normadizenormadize Posts: 31Questions: 6Answers: 1

    Also, just to add, it's not the speed I was worried about -- filtering/sorting is quick enough -- but the fact that my custom search event handlers were called multiple times, causing all sort of other issues.

    I'll try the page option (anecdotally, just a couple of days ago I discovered the false option)

  • normadizenormadize Posts: 31Questions: 6Answers: 1
    edited November 2015

    Unfortunately, .draw('page') didn't help. I'm still getting multiple search events when typing a letter in the column search input box.

    EDIT: Sorry, I was looking in the wrong place. Yes, .draw('page') on the column did result in a single search event being fired. Unfortunately, I don't like the bahavior of retaining pagination position ... it would be great if you could fix it - must a search event be triggered on .draw()?

    Is there a way to reset the paging position without triggering .draw()? If yes then I could use .draw('page') and manually reset paging ... which defeats the whole purpose of the page option, but could help my scenario.

  • normadizenormadize Posts: 31Questions: 6Answers: 1
    edited November 2015

    To answer my own question, is there any danger in doing:

    column.search('foo');
    table.page(0).draw('page');
    

    That results in a single search event being fired and the paging set to the first page. Rather than doing:

    column.search('foo').draw('page');
    

    Which does not reset paging position.

  • allanallan Posts: 61,773Questions: 1Answers: 10,112 Site admin

    That should work correctly at the moment. It is possible that when I come to address this multiple event issue that there might be a problem there (I'm not yet sure to be honest, since I'm not sure how I'm going to fix it!) - but that likely won't be until the next major release of DataTables.

    Out of interest, what are you doing with the search event - it is relatively unusual to listen for it, so I'm curious? :-)

    Allan

  • normadizenormadize Posts: 31Questions: 6Answers: 1
    edited November 2015

    First, I take it your newborn son is asleep or else you probably shouldn't be in here :). Congrats once again by the way.

    I have a nice set of dynamic graphs (dc.js) which I refresh automatically with the filtered table data whenever the table is filtered. It makes for a lovely user experience.

    Multiple search events one after the other is problematic as there are many graphs (also slows down the browser). My initial fix, which I decided to keep, was to use clearTimeout(timer); timer = setTimeout(..., 500) in the handler in order to discard all but the last search event that is triggered within 500 ms. This is a good idea anyway since the user could type rapidly and trigger many unnecessary graph refreshes. I had to deal with the first draw of the table though which was issuing 3 search events ...

    NOTE: When you fix it properly, could you please post in this thread so that I'm notified? Maybe make a note of this thread's URL in your bug system. Otherwise I'll surely forget and will pull my hair out again when I upgrade DataTables :)

  • allanallan Posts: 61,773Questions: 1Answers: 10,112 Site admin

    I'll try to remember to post back here, but with around 30 new threads a day and it likely to be around 6 months or more before I do the next major update it is possible I'll forget :-). It will be noted in the release notes.

    Another option would be to use the draw event and check to see if the search condition has changed. Not fantastic, but that would work and be forward compatible.

    Allan

  • normadizenormadize Posts: 31Questions: 6Answers: 1
    edited November 2015

    The draw event fires when changing pagination and when sorting columns if I'm not mistaken, which is excessive. The search event is great. I could check if the search condition changed in the search handler too if I wanted (no need to use draw), unless I misunderstood you.

    In any case, it's working now as intended so I'm happy. If you put this thread's link in the release notes next to the bug fix then I'll be able to pick it up - thanks!

This discussion has been closed.