简体   繁体   中英

Make ActiveAdmin use inclusive date filter?

Usually when selecting date ranges you expect the dates to be inclusive. ie "11/07/2011" - "11/09/2011" you expect it to return results from Nov. 7th, 8th, and 9th. The way the ActiveAdmin filter is working right now looks like that date range would only return results from the 8th which is counter-intuitive.

What would I have to modify in order to change this behaviour to what is expected?

While Raels' main idea is correct the solution is too hacky. You should not patch the client side. All we have to do is to add time extension to the *_lte inputs of datetime columns using before_filter . We can easily achieve that monkeypatching the filter method of ActiveAdmin::ResourceDSL .

Here is the universal solution that solves this issue: https://gist.github.com/4015836 .

The code in AA uses gte and lte so it is trying to be inclusive. I found the issue to be using datetimes instead of dates. The issue is that the code only specifies the date part, which when extended to a datetime yields the same date at midnight (00:00:00.000000). This happens for both the gte (where it is harmless) and lte (where it is deadly) parts. The part comparing lte needs to instead compare against a time part of 23:59:59.999999.

So, here is what I did that seems to work.

Create a coffeescript file at relative path 'app/assets/javascript/make_datetime_lte_work.js.coffee' with the following contents:

    $(document).ready ->
      $('input.datepickerlte').datepicker 'option', {dateFormat: 'yy-mm-dd     23:59:59.99999'}

Next, we will monkey patch the date range filter code. Put the following content into a ruby file at relative path 'config/initializers/make_datetime_lte_work.rb':

module ActiveAdmin
  module Inputs
    class FilterDateRangeInput

      def to_html
        input_wrapping do
          [ label_html,
            builder.text_field(gt_input_name, input_html_options(gt_input_name)),
            template.content_tag(:span, "-", :class => "seperator"),
            builder.text_field(lt_input_name, input_html_options(lt_input_name, ' datepickerlte')),
          ].join("\n").html_safe
        end
      end

      def input_html_options(input_name = gt_input_name, extra_class = '')
        current_value = @object.send(input_name)
        { :size => 12,
          :class => "datepicker" + extra_class,
          :max => 10,
          :value => current_value.respond_to?(:strftime) ? current_value.strftime("%Y-%m-%d") : "" }
      end
    end
  end
end

Now, make sure to edit your app/assets/javascript/active_admin.js to reference your new javascript file by adding the reference to it in a comment. Here is what mine looks like:

//= require active_admin/base
//= require make_datetime_lte_work

Restart your rails app so the initializers get called.

Now, the ending part of the date range in the filter will have 23:59:59.999999 appended to the date, which will include (almost) the entire day.

Hope that helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM