Deactivating filter button does not reset search filter

Deactivating filter button does not reset search filter

trongarttrongart Posts: 222Questions: 51Answers: 0

In this test case, I am trying to trigger the .filter button at table load with:

table.button('.filter').trigger();

or with

initComplete: function () {
this.api().button('.filter').trigger();
}

For both cases, the button is activated correctly when the table loads, but when I deactivate the button, the search filter is not reset. What could be missing here?

This question has accepted answers - jump to:

Answers

  • kthorngrenkthorngren Posts: 21,332Questions: 26Answers: 4,951

    you are popping the search plugin. You need to follow that with calling draw() for Datatables to update the table filtering.

    Kevin

  • trongarttrongart Posts: 222Questions: 51Answers: 0

    @kthorngren yes when the filter button is deactivated with this.active(false) so that the search plugin is popped with $.fn.dataTable.ext.search.pop(), the last action element is dt.draw() which should update the table filtering, but it does not do that for some reason.

  • trongarttrongart Posts: 222Questions: 51Answers: 0
    edited December 2021

    I added another test case with a reset button that clears all search filters and redraws the table and it does not work here either. Somehow table draw is not triggered at all.

  • kthorngrenkthorngren Posts: 21,332Questions: 26Answers: 4,951
    edited December 2021

    I added some console.log debug statements to look at what is happening. When the button is clicked and active you can see there are to search plugins; the first is yours and the second is from the SearchBuilder:

    When you are popping the plugin added by the SearchBuilder is removed.

    Because its hard to control I don't pop the search plugins. Instead I just add them before Datatables initialization and use if statements in the plugin function to determine if the plugin code should be executed. Basically you would check to see if the button is active. If not the simply `return true;`` otherwise execute the code in the function.

    http://live.datatables.net/rawanise/2/edit

    Kevin

  • trongarttrongart Posts: 222Questions: 51Answers: 0
    edited December 2021

    @kthorngren Thank you so much for looking into this.

    Not sure why .draw does not simply reset everything here.

    My understanding was that with table.button('.filter').trigger() the button function checks if the button is active as it's in the function. How would you add the relevant check before Datatables initialization with if statement in the plugin function to determine if the plugin code should be executed? I think it is the same issue in your test case as well.

  • kthorngrenkthorngren Posts: 21,332Questions: 26Answers: 4,951
    Answer ✓
  • trongarttrongart Posts: 222Questions: 51Answers: 0
    edited December 2021

    @kthorngren This is excellent- thank you so much for your help!!!

  • kthorngrenkthorngren Posts: 21,332Questions: 26Answers: 4,951

    Don't try setting the attributes in the search plugin as it will execute once for each row. In this case you will set the CSS 57 times.

    In the button action function go back to using the if statements you had before. Toggle the state and set the CSS but remove the plugin push and pop.

    Kevin

  • trongarttrongart Posts: 222Questions: 51Answers: 0

    @kthorngren You are right- The CSS gets executed 57 times in the search plugin which is not ideal.

    I've gone back using the if statements without pop and push as you suggested for the CSS and added the state toggle, but something is not working here.

  • kthorngrenkthorngren Posts: 21,332Questions: 26Answers: 4,951

    You need to remove the statement that is toggling the state since you are also toggling the state in the if statements. Remove this:

    this.active( ! this.active() );
    

    http://live.datatables.net/perohovi/2/edit

    Kevin

  • trongarttrongart Posts: 222Questions: 51Answers: 0
    edited December 2021

    Yes this is perfect. Thank you so much Kevin!

    In my project I use the buttons as in this test case. It has 3 buttons, there is a global variable global_index that saves each index and then when a button is deactivated I use .fn.dataTable.ext.search.splice of the index to remove the specific filters. This way not all search filters are removed and I can activate the filters in different sequences while turning them off one by one. This has wroked fine until it stopped when I used a button trigger such as table.button('.filter').trigger() after table load (original issue of this thread).

    In the test case I left the original code with $.fn.dataTable.ext.search.push inside the if statements of every filter but commented it out as we moved it now to before Datatables initialization so I now applied what we found here to my test case. However, only the first filter button seems to work here.

  • kthorngrenkthorngren Posts: 21,332Questions: 26Answers: 4,951

    The problem is you are removing the plugin with $.fn.dataTable.ext.search.splice(global_index.indexOf($('.filter2').index()), 1);. Remove these statements. Updated example:
    http://live.datatables.net/vogasofu/2/edit

    Kevin

  • trongarttrongart Posts: 222Questions: 51Answers: 0
    edited December 2021

    @kthorngren Again thank you so much for your help here! Your feedback is absolutely invaluable!

    This works correctly, but when I applied this to my project with 9000 rows and 30 buttons, I got a huge performance decrease by moving $.fn.dataTable.ext.search.push outside of Datatables initialization. A button click that took almost an instant to filter the table, now takes 6 seconds so this would not be a solution.

    Not sure what I can do here except for simply not using button triggers on table load at all (and with it would not be able to use stateSave on button as triggering them leads to the main issue of this thread). This is the button configuration that worked without $.fn.dataTable.ext.search.push outside of Datatables initialization.

  • kthorngrenkthorngren Posts: 21,332Questions: 26Answers: 4,951
    Answer ✓

    I see two choices:

    1. Restructure the code so you have only one search plugin, like this:
      http://live.datatables.net/vogasofu/5/edit

    2. Use your push / pop method. The problem is, now you need to worry about SearchBuilder adding search plugins. You may need to add more logic to keep track of where the SearchBuilder plugin is in array. Not sure how to do this. One of the developers may have some ideas for you.

    Possibly you can use array.splice() to insert the plugins in the same spot in the array. For example .filter is always the first position, .filter2 is the second, etc. This way you won't affect what other plugins add.

    Kevin

  • trongarttrongart Posts: 222Questions: 51Answers: 0
    edited December 2021

    Thank you @kthorngren

    1. Works, but decreases performance 5-6x for larger datasets with lots of buttons.

    2. This might work, but not sure where to start.

    Would appreciate any input from the developers. Ideal case would be if I could simply trigger/activate a button just like a click on an already loaded table based on stateSave.

    Here is a complete test case with stateSave and button saving/triggering. The issue here is that once you click on Filter1 button for example and reload the table - yes, Filter1 button loads as that gets saved and triggered, but once you deactivate it, the table does not get reset and using method 1 by @kthorngren as above decreases performance considerably.

  • trongarttrongart Posts: 222Questions: 51Answers: 0
    edited December 2021

    I was thinking of something like this even:

    jQuery(function(){
    jQuery('.filter1').click();
    });

    But same issue. Is there a way to click the buttons after everything is fully loaded based on those buttons that need to be triggered from stateSave as in my testcase?

  • kthorngrenkthorngren Posts: 21,332Questions: 26Answers: 4,951

    The problem is the same as I described before. You are removing the SearchBuilder plugin and not the one for the inactive button so the filter is still active when you don't expect it to be. I added a console.log into a draw event function so you can see this.
    http://live.datatables.net/kebubiho/2/edit

    Start the page with no filters active. Activate 1 and 2. and look at the output. You will see three plugins in the array. Reload the page then deactivate filter 1. You will see 2 plugins in the array but the table hasn't changed because the wrong plugin was removed. Deactivate the other filter and still the table hasn't changed and you will see the SearchBuilder plugin was removed (the one with the (e,f,g) parameters. Now the SearchBuilder doesn't work either. You can see this by trying to apply the filter Position > Not > Accountant.

    Kevin

  • kthorngrenkthorngren Posts: 21,332Questions: 26Answers: 4,951
    Answer ✓

    Thinking about this for a bit you will need to trigger the active buttons after initComplete and after SearchBuilder has added its plugin. Looks like after the SearchBuilder is initialized it calls draw(). You can instantiate the draw event in initComplete using jQuery one() instead of on() so it runs once. If the length of the search plugin array 1 or more, then you can trigger the active buttons. After that the array splicing you are doing doesn't seem to affect the SearchBuilder plugin.
    http://live.datatables.net/jinuroje/1/edit

    I'll leave it yo you to test and make sure it works properly.

    Kevin

  • trongarttrongart Posts: 222Questions: 51Answers: 0

    @kthorngren I must say that this is absolutely genius and yes it works as intended! Thank you so much again. Your help and feedback have been extremely invaluable!!

    One small thing: I do not want to save the searchBuilder with stateSave and I do this by adding delete data.searchBuilder; into stateLoadParams, but doing so breaks this approach as filter buttons are no longer saved. Is there maybe an alternative way to not load searchBuilder?

    Test case with delete data.searchBuilder;.

  • kthorngrenkthorngren Posts: 21,332Questions: 26Answers: 4,951
    edited December 2021

    Looks like deleting the searchBuilder object causes searchBuilder to not execute the initial draw so the draw in initComplete doesn't execute when expected. If you investigate what searchBuilder saves with an empty search you will see its {}. Setting data.searchBuilder = {}; instead of deleting it seems to work.
    http://live.datatables.net/gaduneva/1/edit

    This likely means that if you disable SearchBuilder then you will need to remove the draw in initComplete for your solution to work properly.

    Kevin

  • trongarttrongart Posts: 222Questions: 51Answers: 0

    Thank you so much Kevin!!! Have a nice weekend B)

Sign In or Register to comment.