bogdan / datagrid

Gem to create tables grids with sortable columns and filters
MIT License
1.02k stars 115 forks source link

Date filter renders as text input #294

Closed rbdmorgan closed 3 years ago

rbdmorgan commented 3 years ago

E.g. the following:

filter(:year_end, :date)

Renders as:

<input class="year_end date_filter" type="text" name="clients_grid[year_end]" id="clients_grid_year_end">

Range works fine.

I think this function is culprit, specifically line 149 - calls datagrid_default_filter if no range specified:

https://github.com/bogdan/datagrid/blob/1e01b18186b93c9ed321bb862294408b11735ead/lib/datagrid/form_builder.rb#L138-L151

And then datagrid_default_filter renders the filter as a text_field:

https://github.com/bogdan/datagrid/blob/1e01b18186b93c9ed321bb862294408b11735ead/lib/datagrid/form_builder.rb#L43-L46

Tempted to try and fix it but might be easier for you to! For now I'll probably just work around it with some good ol'jQuery ;)

Can I just say though this gem is brilliant. Really well designed and has everything I need. Awesome work @bogdan :+1:

bogdan commented 3 years ago

Hey, I didn't get what would expect it to render to. I see that both range and non-range version is rendered to <input type="text"/>. Can you give an example what it should render to instead?

rbdmorgan commented 3 years ago

Hey @bogdan, so for me, this renders as <input type="date"/> i.e. a calendar dropdown as I'd expect:

filter(:year_end, :date, range: true)

However, this renders as an <input type="text"/>, even though I've specified :date as the filter type (not :string):

filter(:year_end, :date)

I would have thought they should both render as <input type="date"/>?

bogdan commented 3 years ago

I don't see how would range: true convert it from text to date type. See: https://github.com/bogdan/datagrid/blob/c06bb11f7d4ed754508aa1ed14e6c2b0d266b630/app/views/datagrid/_range_filter.html.erb#L1

Maybe there is some magic on your end. However, I do admit there is need a feature to specify such input type on the application level. Let me think about it.

rbdmorgan commented 3 years ago

Ah yes, maybe I did tweak that in the view!

Well yes, I think it would be really handy to be able to render a :date filter as an <input type="date"/>.

For now I've worked around it with some jQuery:

$('.datagrid-filter > .date_filter').attr('type', 'date');

Bit of a kludge but works fine!

Thanks @bogdan 😄

bogdan commented 3 years ago

I've consulted with some frontend developers, so they tell that there is no consensus that using type="date" is a good idea by default.

So, here is my solution. We introduce a new option like html_options for filter method and you can use it like so:

class MyGrid
  filter(:created_at, :date, html_options: {type: 'date'});
end

Alternatively, if you want type=date to be everywhere across all your grids make it like so:

class BaseGrid

   INPUT_TYPE_BY_FILTER_TYPE = {
     date: :date,
   }

   def self.filter(name, type = :default, html_options: {}, **options, &block)
     html_options[:type] ||= INPUT_TYPE_BY_FILTER_TYPE[type]
     super(name, type, html_options: html_options, **options, &block)
  end
end

class MyGrid < BaseGrid
  filter(:created_at, :date)
end

I want to confirm if it is working for you before implementing html_options. What do you think?

rbdmorgan commented 3 years ago

Thanks @bogdan this looks great!

Only thing I'm thinking - might it make sense to call the parameter control_options and perhaps have a label_options parameter as well? Reason being, it would be nice to be able to add a CSS class e.g. form-label to the <label /> and form-select to the <select /> to apply Bootstrap styling (or whatever framework you're using).

What do you think?

bogdan commented 3 years ago

Good idea, I would name it input_options and label_options. input_options suppose to apply to <input/> and <select/>. I just think that input_options is a better name.

rbdmorgan commented 3 years ago

Agreed :+1:

Brilliant thanks @bogdan! I look forward to this update. No rush of course 😄

bogdan commented 3 years ago

Released version 1.6.2