jhund / filterrific

Filterrific is a Rails Engine plugin that makes it easy to filter, search, and sort your ActiveRecord lists.
http://filterrific.clearcove.ca
MIT License
910 stars 124 forks source link

Buttons problem after filter #179

Open eugesma opened 5 years ago

eugesma commented 5 years ago

After filter the table, the buttons needs to be clicked twice times to work. In application.js:

//= require rails-ujs
//= require jquery
//= require jquery_ujs
//= require jquery-ui
//= require chosen-jquery
//= require bootstrap-select
//= require filterrific/filterrific-jquery
//= require highcharts
//= require chartkick
//= require Chart.bundle
//= require turbolinks
//= require cocoon
//= require moment
//= require moment/es 
//= require bootstrap-switch
//= require bootstrap-datetimepicker
//= require bootstrap-sprockets
//= require bootstrap
//= require bootstrap.min
//= require_tree .

I dont know what happen....

eugesma commented 5 years ago

I think it's related to the automatic filtering. If after fill the field i press in other part of the sreen (unfocusing the filter form), the button to show the item works fine.

stevefolly commented 5 years ago

I'm seeing this as well.

cartond commented 5 years ago

We had this same problem. I believe it's because of the jQuery selector, which IS working correctly, but maybe not how you want it to.

My theory...

Context:

  1. Filterrific is binding onto inputs with class .filterrific-periodically-observed on the events keyup, click, mousemove
  2. It also binds onto change event handler to all Filterrific filter inputs
  3. Both of these actions will trigger Filterrific.submitFilterForm which will refresh the data shown

What I think the "double click" is:

  1. You type into an input box
  2. Filterrific will capture a change on the input, triggers Filterrific.submitFilterForm for the first time
  3. You click ANYWHERE outside of the input, a button for example, but really it is getting captured is step 2. in the context steps - mouseout or maybe change(?)
  4. That clicking of the button (or anywhere else) will trigger the changed input's handler Filterrific.submitFilterForm for a second time.
  5. Thus, when you are clicking the first time, it is refreshing the data because of an input changed

You can verify this by adding some debugging step when the table is refreshed (i.e. a binding.pry for backend or a js debugger for frontend)

To get around it: Don't let Filterrific handle input changes!

Solution: I added a custom ID on the filterrific table

-# Custom ID for custom event handling
= form_for_filterrific @filterrific, {html: {id: 'filterific_filter_custom'}} do |f|

and overwrote how to bind to elements.

In our case, we wanted a submit button, so I added a Submit button (in the form! you can use CSS to hide it if you want..) #submit.btn.btn-green{:role => "submit"} Search

To handle hitting Filterrific's function submitFilterForm, because that function requires some element to inherit the form from (the Submit button in this case).

So in the JS, on the page ready, copy similar functionality binding to the form

var overrideBindings = function(){
    # On submission, let filterrific do the heavy lifting, this stays the same as default functionality
    $('#filterific_filter_custom #submit').click(Filterrific.submitFilterForm)
    # Intercept "Enter" key to avoid the rest of the form from being wiped.
    $('#filterific_filter_custom').submit( (e) -> e.preventDefault(); $('#filterific_filter_custom #submit').click())
}

If this was a better solution, I'd PR it...

chrisedington commented 3 years ago

@cartond thanks for the patch suggestion -- just wanted to see if anyone else has come up with any ideas for preventing this double firing?

chrisedington commented 3 years ago

For reference: https://github.com/jhund/filterrific/issues/84 and https://github.com/jhund/filterrific/issues/139

I used this and it seems to work perfectly (from https://github.com/jhund/filterrific/issues/84):

$('#filterrific_filter').on( "change", ":input", function (e) { e.stopImmediatePropagation(); $(this).off("blur"); Filterrific.submitFilterForm; } );