module ActiveScaffold::DataStructures class Column include ActiveScaffold::Configurable include ActiveScaffold::OrmChecks NO_PARAMS = Set.new.freeze NO_OPTIONS = {}.freeze attr_reader :active_record_class alias model active_record_class # this is the name of the getter on the ActiveRecord model. it is the only absolutely required attribute ... all others will be inferred from this name. attr_reader :name # Whether to enable inplace editing for this column. Currently works for text columns, in the List. attr_reader :inplace_edit def inplace_edit=(value) clear_link if value @inplace_edit = value end # :table to refresh list # true or :row to refresh row attr_accessor :inplace_edit_update # Whether this column set is collapsed by default in contexts where collapsing is supported attr_accessor :collapsed # Whether to enable add_existing for this column attr_accessor :allow_add_existing # What columns load from main table attr_accessor :select_columns # Any extra parameters this particular column uses. This is for create/update purposes. def params return @params || NO_PARAMS if frozen? @params ||= NO_PARAMS.dup end # the display-name of the column. this will be used, for instance, as the column title in the table and as the field name in the form. # if left alone it will utilize human_attribute_name which includes localization attr_writer :label def label(record = nil, scope = nil) if @label.respond_to?(:call) if record @label.call(record, self, scope) else # sometimes label is called without a record in context (ie, from table # headers). In this case fall back to the humanized attribute name # instead of the Proc active_record_class.human_attribute_name(name.to_s) end else as_(@label) || active_record_class.human_attribute_name(name.to_s) end end # a textual description of the column and its contents. this will be displayed with any associated form input widget, so you may want to consider adding a content example. attr_writer :description def description(record = nil, scope = nil) if @description&.respond_to?(:call) @description.call(record, self, scope) elsif @description @description else I18n.t name, :scope => [:activerecord, :description, active_record_class.to_s.underscore.to_sym], :default => '' end end # A placeholder text, to be used inside blank text fields to describe, what should be typed in attr_writer :placeholder def placeholder @placeholder || I18n.t(name, :scope => [:activerecord, :placeholder, active_record_class.to_s.underscore.to_sym], :default => '') end # this will be /joined/ to the :name for the td's class attribute. useful if you want to style columns on different ActiveScaffolds the same way, but the columns have different names. attr_accessor :css_class # whether the field is required or not. used on the form for visually indicating the fact to the user. # TODO: move into predicate attr_writer :required def required?(action = nil) if action && @required @required == true || @required.include?(action) else @required end end attr_reader :update_columns # update dependent columns after value change in form # update_columns = :name # update_columns = [:name, :age] def update_columns=(column_names) @update_columns = Array(column_names) end # send all the form instead of only new value when this column change cattr_accessor :send_form_on_update_column, instance_accessor: false attr_accessor :send_form_on_update_column # add a custom attr_accessor that can contain a Proc (or boolean or symbol) # that will be called when the column renders, such that we can dynamically # hide or show the column with an element that can be replaced by # update_columns, but won't affect the form submission. # The value can be set in the scaffold controller as follows to dynamically # hide the column based on a Proc's output: # config.columns[:my_column].hide_form_column_if = Proc.new { |record, column, scope| record.vehicle_type == 'tractor' } # OR to always hide the column: # config.columns[:my_column].hide_form_column_if = true # OR to call a method on the record to determine whether to hide the column: # config.columns[:my_column].hide_form_column_if = :hide_tractor_fields? attr_accessor :hide_form_column_if # sorting on a column can be configured four ways: # sort = true default, uses intelligent sorting sql default # sort = false sometimes sorting doesn't make sense # sort = {:sql => ""} define your own sql for sorting. this should be result in a sortable value in SQL. ActiveScaffold will handle the ascending/descending. # sort = {:method => ""} define ruby-side code for sorting. this is SLOW with large recordsets! def sort=(value) if value.is_a? Hash value.assert_valid_keys(:sql, :method) @sort = value else @sort = value ? true : false # force true or false end end def sort initialize_sort if @sort == true @sort end def sortable? sort != false && !sort.nil? end # a configuration helper for the self.sort property. simply provides a method syntax instead of setter syntax. def sort_by(options) self.sort = options end # supported options: # * for association columns # * :select - displays a simple