bogdan / datagrid

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

Custom order of columns #285

Closed egracens closed 4 years ago

egracens commented 4 years ago

Hello! I have some datagrids sharing the same columns. These columns are pretty complex and I decided to extract them to a module to reduce code duplication. But I need these columns to be rendered in a different order in different datagrids. Here is an example.

module SharedColumns
  extend ActiveSupport::Concern

  included do
      column(
        :model_type,
        html: true,
        class: 'table__column--type',
        order: QueryHelpers::Order.by_field(:first_column),
        order_desc: QueryHelpers::Order.by_field(:first_column, :desc)
      ) do |record, grid|
        content_tag(:div, class: 'table__cell-wrapper table__cell-image-wrapper') do
          asset_type_icon(grid.model_types[record.id])
        end
      end

    column(:another_column, :with_another_complex_logic)
  end
end
class FirstGrid
  include Datagrid
  include SharedColumns

  column(:id)

  # Here I need the following order of columns: 
  # :model_type, :id, :another_column
end
class SecondGrid
  include Datagrid
  include SharedColumns

  column(:name)

  # Here I need the following order of columns: 
  # :name, :another_column, :model_type
end

I expected to have DSL like this:

column_rendering_order(:name, :another_column, :model_type)

Is there are a solution to my problem in datagrid gem? Searching in issues and googling did not give me anything.

egracens commented 4 years ago

The solution I found is to write custom DSL for it and render columns in custom datagrid view depending on settings.

bogdan commented 4 years ago

I use the following strategy in my project:

module SharedColumns
  module ClassMethods
    def model_type_column(**options = {})
      column(:model-type, 
        html: true,
        class: 'table__column--type',
        order: QueryHelpers::Order.by_field(:first_column),
        order_desc: QueryHelpers::Order.by_field(:first_column, :desc),
        ** options
      ) do
      ....
     end
   def another_column(**options ={})
      column(:another_column, :complex_logic, **options)
  end
end

And then, your shared code can be used in flexile way

class FirstGrid
  include Datagrid
  include SharedColumns

  model_type_column
  column(:id)
  another_column(custom_options)
end

I consider such solution superior to the idea that column order is decoupled from columns definition.

egracens commented 4 years ago

Wow! Thanks for the idea! Looks nice.