Module: Datagrid::Columns::InstanceMethods

Defined in:
lib/datagrid/columns.rb

Instance Method Summary collapse

Instance Method Details

#available_columnsArray<Datagrid::Columns::Column>

Returns all columns that are possible to be displayed for the current grid object.

Examples:

class MyGrid
  filter(:search) {|scope, value| scope.full_text_search(value)}
  column(:id)
  column(:name, mandatory: true)
  column(:search_match, if: proc {|grid| grid.search.present? }) do |model, grid|
    search_match_line(model.searchable_content, grid.search)
  end
end

grid = MyGrid.new
grid.columns # => [ #<Column:name> ]
grid.available_columns # => [ #<Column:id>, #<Column:name> ]
grid.search = "keyword"
grid.available_columns # => [ #<Column:id>, #<Column:name>, #<Column:search_match> ]

Returns:



394
395
396
397
398
# File 'lib/datagrid/columns.rb', line 394

def available_columns
  columns_array.select do |column|
    column.enabled?(self)
  end
end

#column(name, query = nil, **options, &block) ⇒ Object

Defines a column at instance level



367
368
369
# File 'lib/datagrid/columns.rb', line 367

def column(name, query = nil, **options, &block)
  self.class.define_column(columns_array, name, query, **options, &block)
end

#column_by_name(name) ⇒ Datagrid::Columns::Column?

Finds a column definition by name

Parameters:

  • name (String, Symbol)

    column name to be found

Returns:



318
319
320
# File 'lib/datagrid/columns.rb', line 318

def column_by_name(name)
  self.class.find_column_by_name(columns_array, name)
end

#columns(*column_names, data: false, html: false) ⇒ Array<Datagrid::Columns::Column>

Returns all columns selected in grid instance.

Examples:

MyGrid.new.columns # => all defined columns
grid = MyGrid.new(column_names: [:id, :name])
grid.columns # => id and name columns
grid.columns(:id, :category) # => id and category column

Parameters:

  • column_names (Array<Symbol, String>)

Returns:



295
296
297
298
299
300
301
# File 'lib/datagrid/columns.rb', line 295

def columns(*column_names, data: false, html: false)
  self.class.filter_columns(
    columns_array, *column_names, data: data, html: html
  ).select do |column|
    column.enabled?(self)
  end
end

#data(*column_names) ⇒ Array<Array<Object>>

Returns data for each row in datagrid assets with header.

Parameters:

  • column_names (Array<String>)

    list of column names if you want to limit data only to specified columns

Returns:

  • (Array<Array<Object>>)

    data for each row in datagrid assets with header.



242
243
244
# File 'lib/datagrid/columns.rb', line 242

def data(*column_names)
  self.rows(*column_names).unshift(self.header(*column_names))
end

#data_columns(*column_names, **options) ⇒ Object

Returns columns that can be represented in plain data(non-html) way.

Parameters:

  • column_names (Array<String, Symbol>)

    list of column names if you want to limit data only to specified columns

Returns:

  • columns that can be represented in plain data(non-html) way



305
306
307
# File 'lib/datagrid/columns.rb', line 305

def data_columns(*column_names, **options)
  self.columns(*column_names, **options, data: true)
end

#data_hashObject

Return Array of Hashes where keys are column names and values are column values for each row in filtered datagrid relation.

Examples:

class MyGrid
  scope { Model }
  column(:id)
  column(:name)
end

Model.create!(name: "One")
Model.create!(name: "Two")

MyGrid.new.data_hash # => [{name: "One"}, {name: "Two"}]


260
261
262
263
264
# File 'lib/datagrid/columns.rb', line 260

def data_hash
  map_with_batches do |asset|
    hash_for(asset)
  end
end

#data_row(asset) ⇒ Datagrid::Columns::DataRow

Returns an object representing a grid row.

Examples:

class MyGrid
  scope { User }
  column(:id)
  column(:name)
  column(:number_of_purchases) do |user|
    user.purchases.count
  end
end

row = MyGrid.new.data_row(User.last)
row.id # => user.id
row.number_of_purchases # => user.purchases.count

Returns:



360
361
362
# File 'lib/datagrid/columns.rb', line 360

def data_row(asset)
  ::Datagrid::Columns::DataRow.new(self, asset)
end

#data_value(column_name, asset) ⇒ Object

Returns a cell data value for given column name and asset.

Returns:

  • (Object)

    a cell data value for given column name and asset



401
402
403
404
405
406
407
408
# File 'lib/datagrid/columns.rb', line 401

def data_value(column_name, asset)
  column = column_by_name(column_name)
  cache(column, asset, :data_value) do
    raise "no data value for #{column.name} column" unless column.data?
    result = generic_value(column, asset)
    result.is_a?(Datagrid::Columns::Column::ResponseFormat) ? result.call_data : result
  end
end

#decorate(model) ⇒ Object

Returns a decorated version of given model if decorator is specified or the model otherwise.

Returns:

  • (Object)

    a decorated version of given model if decorator is specified or the model otherwise.



424
425
426
# File 'lib/datagrid/columns.rb', line 424

def decorate(model)
  self.class.decorate(model)
end

#format(value, &block) ⇒ Datagrid::Columns::Column::ResponseFormat

Gives ability to have a different formatting for CSV and HTML column value.

Examples:

column(:name) do |model|
  format(model.name) do |value|
    (:strong, value)
  end
end

column(:company) do |model|
  format(model.company.name) do
    render partial: "company_with_logo", locals: {company: model.company }
  end
end

Returns:



337
338
339
340
341
342
343
344
# File 'lib/datagrid/columns.rb', line 337

def format(value, &block)
  if block_given?
    self.class.format(value, &block)
  else
    # don't override Object#format method
    super
  end
end

#hash_for(asset) ⇒ Hash

Returns A mapping where keys are column names and values are column values for the given asset.

Parameters:

  • asset (Object)

    asset from datagrid scope

Returns:

  • (Hash)

    A mapping where keys are column names and values are column values for the given asset



224
225
226
227
228
229
230
# File 'lib/datagrid/columns.rb', line 224

def hash_for(asset)
  result = {}
  self.data_columns.each do |column|
    result[column.name] = data_value(column, asset)
  end
  result
end

#header(*column_names) ⇒ Array<String>

Returns human readable column names. See also “Localization” section.

Parameters:

  • column_names (Array<String>)

    list of column names if you want to limit data only to specified columns

Returns:

  • (Array<String>)

    human readable column names. See also “Localization” section



209
210
211
# File 'lib/datagrid/columns.rb', line 209

def header(*column_names)
  data_columns(*column_names).map(&:header)
end

#html_columns(*column_names, **options) ⇒ Object

Returns all columns that can be represented in HTML table.

Parameters:

  • column_names (Array<String>)

    list of column names if you want to limit data only to specified columns

Returns:

  • all columns that can be represented in HTML table



311
312
313
# File 'lib/datagrid/columns.rb', line 311

def html_columns(*column_names, **options)
  self.columns(*column_names, **options, html: true)
end

#html_value(column_name, context, asset) ⇒ Object

Returns a cell HTML value for given column name and asset and view context.

Returns:

  • (Object)

    a cell HTML value for given column name and asset and view context



411
412
413
414
415
416
417
418
419
420
421
# File 'lib/datagrid/columns.rb', line 411

def html_value(column_name, context, asset)
  column  = column_by_name(column_name)
  cache(column, asset, :html_value) do
    if column.html? && column.html_block
      value_from_html_block(context, asset, column)
    else
      result = generic_value(column, asset)
      result.is_a?(Datagrid::Columns::Column::ResponseFormat) ? result.call_html(context) : result
    end
  end
end

#row_for(asset, *column_names) ⇒ Array<Object>

Returns column values for given asset.

Parameters:

  • asset (Object)

    asset from datagrid scope

  • column_names (Array<String>)

    list of column names if you want to limit data only to specified columns

Returns:

  • (Array<Object>)

    column values for given asset



216
217
218
219
220
# File 'lib/datagrid/columns.rb', line 216

def row_for(asset, *column_names)
  data_columns(*column_names).map do |column|
    data_value(column, asset)
  end
end

#rows(*column_names) ⇒ Array<Array<Object>>

Returns with data for each row in datagrid assets without header.

Parameters:

  • column_names (Array<String>)

    list of column names if you want to limit data only to specified columns

Returns:

  • (Array<Array<Object>>)

    with data for each row in datagrid assets without header



234
235
236
237
238
# File 'lib/datagrid/columns.rb', line 234

def rows(*column_names)
  map_with_batches do |asset|
    self.row_for(asset, *column_names)
  end
end

#to_csv(*column_names, **options) ⇒ String

Returns a CSV representation of the data in the grid.

Examples:

grid.to_csv
grid.to_csv(:id, :name)
grid.to_csv(col_sep: ';')

Parameters:

  • column_names (Array<String>)
  • options (Hash)

    CSV generation options

Returns:

  • (String)

    a CSV representation of the data in the grid



274
275
276
277
278
279
280
281
282
283
284
285
# File 'lib/datagrid/columns.rb', line 274

def to_csv(*column_names, **options)
  require "csv"
  CSV.generate(
    headers: self.header(*column_names),
    write_headers: true,
    **options
  ) do |csv|
    each_with_batches do |asset|
      csv << row_for(asset, *column_names)
    end
  end
end