Argument out of range error with date_range cond
clveranis opened this issue · 1 comments
I recently implemented a date_range filter using YADCF and while the date range filter itself works fine, I receive the following error if I try to use the native search input:
Completed 500 Internal Server Error in 7ms (ActiveRecord: 1.7ms)
ArgumentError (argument out of range):
I have them implemented like such:
View_columns:
def view_columns
@view_columns ||= {
...
submitted_on: { source: "Order.created_at", cond: :date_range, delimiter: '-yadcf_delim-',
...
}
end
YADCF JS Initialization:
yadcf.init(tableElement.DataTable(), [{
column_number : 11,
filter_type: "range_date",
datepicker_type: 'bootstrap-datetimepicker',
date_format: 'YYYY-MM-DD',
filter_container_id: 'yadcfDateDiv'
}]);
I don't mind setting the date column to be searchable: false to disable the search feature (which removes the error) but then the date range filter stops working. Any ideas would be greatly appreciated, thanks!
So my work around for this was adding 2 initializers to my rails app:
datetime_ext.rb: to add aparsable?method to the RubyTimeclass to check if the search string is a valid datetimeajax_datatable_rails.rb: to overwrite thenon_regex_searchmethod when the column is set tocond: :date_range
### config/initializers/datetime_ext.rb ###
class Time
def self.parsable?(string)
begin
parse(string)
true
rescue ArgumentError
false
end
end
end
### config/initializers/ajax_datatables_rails.rb ###
module AjaxDatatablesRails
module Datatable
class Column
module Search
def non_regex_search
case cond
when Proc
filter
when :eq, :not_eq, :lt, :gt, :lteq, :gteq, :in
searchable_integer? ? raw_search(cond) : empty_search
when :start_with
text_search("#{formatted_value}%")
when :end_with
text_search("%#{formatted_value}")
when :like
text_search("%#{formatted_value}%")
when :string_eq
raw_search(:eq)
when :string_in
raw_search(:in)
when :null_value
null_value_search
when :date_range
if Time.parsable?(formatted_value)
date_range_search
else
text_search("%#{formatted_value}%")
end
end
end
end
end
end
end
The idea is to check if the searched string is a valid datetime format and can be parsed into a valid Time object, if it's not, then the search function treats the column as if its searching it as a regular string (i.e. if cond: :datetime was not explicitly set). This way you can search against that column as either a string or date time.
One additional thing I noticed is that if you are using the bootstrap-datetimepicker option with YADCF and you clear the date inputs manually (without using the red 'X' button that YADCF creates), then it will submit the search string -yadcf_delim- to the filter search, thus causing your table to search for a date value matching that delim string. My workaround for that was:
### In some .js file where you have yadcf.init() ###
var dateRanges = $('#yadcf-filter--orders-datatable-from-date-11,#yadcf-filter--orders-datatable-to-date-11');
dateRanges.each(function() {
$(this).on('dp.hide', function(e){
if (dateRanges[0].value.length === 0 && dateRanges[1].value.length === 0) {
yadcf.doFilter('clear', '-orders-datatable', 11, 'range_date');
}
});
});
I'm aware this is a bit 'hacky' and I'm sure there is probably a more elegant way to do all of the above but this is where I landed and my table is functioning as desired. Maybe this will help some future Googler or if anyone has any feedback on a better way to do this then I'm all ears. Happy coding!