lib/ui_rules.rb
# Generate HTML for a table of columns from the +@form_object+.
# The table shows only elements that are in the `columns` array.
# If the columns array is an array of arrays, each array will be a vertical set of items.
#
# @param columns [array] the columns to display in the table in sequence. Array of symbols matching attributes in the +@`form_object+. (Can be multidemensional)
# @param display_columns [integer] the number of table columns (combination of `th` for label and `td` for value) to display. Defaults to 2.
# @param header_captions [hash] captions for columns where the default is not good enough. Hash in the form `{ column_name: 'Header caption' }`.
# @param with_object [hash] object to use for values instead of the +@form_object+. Hash in the form `{ column_name: value }`.
Generate HTML for a table of columns from the +@form_object+.
The table shows only elements that are in the `columns` array.
If the columns array is an array of arrays, each array will be a vertical set of items.
Generate HTML for a table of columns from the + @form_object + . The table shows only elements that are in the ` columns ` array . If the columns array is an array of arrays each array will be a vertical set of items .
def compact_header(columns:, display_columns: 2, header_captions: {}, with_object: nil) 
      raise Crossbeams::FrameworkError, "#{self.class} form object has not been set up before calling 'compact_header`" if @form_object.nil? && with_object.nil?
      if columns.first.is_a?(Array)
        raise Crossbeams::FrameworkError, "#{self.class} columns array has #{columns.length} column sets, which does not match `display_columns` (#{display_columns})." if columns.length != display_columns
        max = columns.map(&:length).max
        cols = []
        max.times { |n| columns.each { |a| cols << a[n] unless a[n].nil? } }
      else
        cols = columns
      end
      row = 0
      cells = {}
      cols.each_with_index do |a, i|
        row += 1 if (i % display_columns).zero?
        cells[row] ||= []
        val = (with_object || @form_object)[a]
        val = val.to_s('F') if val.is_a?(BigDecimal)
        val = <<~HTML if val.is_a?(TrueClass)
          <div class="cbl-input dark-green">
            #{Crossbeams::Layout::Icon.render(:checkon, css_class: 'mr1')}
          </div>
        HTML
        val = <<~HTML if val.is_a?(FalseClass)
          <div class="cbl-input light-red">
            #{Crossbeams::Layout::Icon.render(:checkoff, css_class: 'mr1')}
          </div>
        HTML
        cells[row] << %(<td class="b gray">#{header_captions[a] || make_caption(a)}</td><td>#{val}</td>)
      end
      inner = cells.map do |_, v|
        %(<tr class="hover-row">#{v.join}</tr>)
      end.join
      @rules[:compact_header] = <<~HTML
        <table class="thinbordertable">
          #{inner}
        </table>
      HTML
    end
def compact_header ( columns : , display_columns : 2 , header_captions : { } , with_object : nil ) raise Crossbeams :: FrameworkError , "#{self.class} form object has not been set up before calling 'compact_header`" if @form_object . nil? && with_object . nil? if columns . first . is_a? ( Array ) raise Crossbeams :: FrameworkError , "#{self.class} columns array has #{columns.length} column sets, which does not match `display_columns` (#{display_columns})." if columns . length != display_columns max = columns . map ( & :length ) . max cols = [ ] max . times { | n | columns . each { | a | cols << a [ n ] unless a [ n ] . nil? } } else cols = columns end row = 0 cells = { } cols . each_with_index do | a , i | row += 1 if ( i % display_columns ) . zero? cells [ row ] ||= [ ] val = ( with_object || @form_object ) [ a ] val = val . to_s ( 'F' ) if val . is_a? ( BigDecimal ) val = <<~HTML if val . is_a? ( TrueClass ) 
          <div class="cbl-input dark-green">
             #{ Crossbeams :: Layout :: Icon . render ( :checkon , css_class : 'mr1' ) } 
          </div>
         HTML val = <<~HTML if val . is_a? ( FalseClass ) 
          <div class="cbl-input light-red">
             #{ Crossbeams :: Layout :: Icon . render ( :checkoff , css_class : 'mr1' ) } 
          </div>
         HTML cells [ row ] << %(<td class="b gray">#{header_captions[a] || make_caption(a)}</td><td>#{val}</td>) end inner = cells . map do | _ , v | %(<tr class="hover-row">#{v.join}</tr>) end . join @rules [ :compact_header ] = <<~HTML 
        <table class="thinbordertable">
           #{ inner } 
        </table>
       HTML end
Generate HTML for a table of columns from the +@form_object+.
Generate HTML for a table of columns from the + @form_object + .
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity # cols.each_slice(3) {|a| puts a.join(', ') }
columns
the columns to display in the table in sequence. Array of symbols matching attributes in the +@`form_object+. (Can be multidemensional)
the columns to display in the table in sequence . Array of symbols matching attributes in the + @ ` form_object + . ( Can be multidemensional )
display_columns
the number of table columns (combination of `th` for label and `td` for value) to display. Defaults to 2.
the number of table columns ( combination of ` th ` for label and ` td ` for value ) to display . Defaults to 2 .
header_captions
captions for columns where the default is not good enough. Hash in the form `{ column_name: 'Header caption' }`.
captions for columns where the default is not good enough . Hash in the form ` { column_name : ' Header caption ' } ` .
with_object
object to use for values instead of the +@form_object+. Hash in the form `{ column_name: value }`.
object to use for values instead of the + @form_object + . Hash in the form ` { column_name : value } ` .