Class: TrkDatatables::RenderHtml

Inherits:
Object
  • Object
show all
Defined in:
lib/trk_datatables/render_html.rb

Class Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(search_link, datatable, html_options = {}) ⇒ RenderHtml

Returns a new instance of RenderHtml.



4
5
6
7
8
9
# File 'lib/trk_datatables/render_html.rb', line 4

def initialize(search_link, datatable, html_options = {})
  @search_link = search_link
  @datatable = datatable
  @html_options = html_options.symbolize_keys
  self.class.indent = 0
end

Class Attribute Details

.indentObject

Returns the value of attribute indent.



20
21
22
# File 'lib/trk_datatables/render_html.rb', line 20

def indent
  @indent
end

Instance Method Details

#_content_tag(tag, options = {}, content = nil) ⇒ Object

rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity

_content_tag :p, ‘Hi’ _content_tag :p, class: ‘button’, ‘Hi’ _content_tag :div, do _content_tag :div, class: ‘background’ do



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/trk_datatables/render_html.rb', line 36

def (tag, options = {}, content = nil)
  if !options.is_a?(Hash)
    # content is first argument, do not pass hash as content
    inline = true
    content = options
    options = {}
  elsif content.present?
    inline = true
  end
  self.class.indent += 1
  html = "#{"  " * self.class.indent}<#{tag}".html_safe
  options.each do |attribute, value|
    value = value.to_json if value.is_a?(Hash) || value.is_a?(Array)
    html << " #{attribute}='".html_safe << replace_quote(value) << "'".html_safe
  end
  html << if inline
    ">".html_safe << content.to_s << "</#{tag}>\n".html_safe
  else
    ">\n".html_safe << yield << "\n#{"  " * self.class.indent}</#{tag}>".html_safe
  end
  self.class.indent -= 1 if self.class.indent > 1
  html
end

#_select_find_options(options, search_value) ⇒ Object

{ key: ‘draft’, value: 0}, ‘published’, value: 1, selected: ‘selected


62
63
64
65
66
67
# File 'lib/trk_datatables/render_html.rb', line 62

def _select_find_options(options, search_value)
  selected = search_value.to_s.split(MULTIPLE_OPTION_SEPARATOR)
  options.map do |key, value|
    {key: key, value: value}.merge(selected.include?(value.to_s) ? {selected: "selected"} : {})
  end
end

#replace_quote(string) ⇒ Object

We need to replace single quote since it is used in option=‘value’



70
71
72
73
74
75
76
77
78
79
# File 'lib/trk_datatables/render_html.rb', line 70

def replace_quote(string)
  # do not know those two are different
  #  ERB::Util.html_escape string.to_s.gsub 'aaa', 'bbb'
  #  ERB::Util.html_escape string.to_s
  # since it is safebuffer and html_safe, this will output with single
  # quotes for example: data-datatable-multiselect='      <select multiple='multi
  # ERB::Util.html_escape string
  # replace single quote with double quote
  string.to_s.tr "'", '"'
end

#resultObject



11
12
13
14
15
16
17
# File 'lib/trk_datatables/render_html.rb', line 11

def result
  if @search_link.nil?
    table_tag_client
  else
    table_tag_server
  end
end

#safe_join(array, sep = $,) ⇒ Object



24
25
26
27
28
# File 'lib/trk_datatables/render_html.rb', line 24

def safe_join(array, sep = $,)
  sep = ERB::Util.unwrapped_html_escape(sep)

  array.map { |i| ERB::Util.unwrapped_html_escape(i) }.join(sep).html_safe
end

#table_tag_clientObject



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/trk_datatables/render_html.rb', line 134

def table_tag_client
  # Should we allow generating datatable only in view
  # <%= ClientDatatable.new(self).render_html do %>
  #    <thead>
  #      <tr>
  # so we do not need datatable and search route
  # than we just need <table> tag, but it uses datatable to determine page
  # length and order (which in turn it determines from params or
  # preferences)
  # _content_tag(
  #   :table,
  #   class: "table table-bordered table-striped #{@html_options[:class]}",
  #   'data-datatable': true,
  #   'data-datatable-ajax-url': @search_link,
  #   'data-datatable-page-length': @datatable.dt_per_page_or_default,
  #   'data-datatable-order': @datatable.dt_orders_or_default_index_and_direction.to_json,
  #   # for initial page load we do not have ability to show recordsTotal
  #   # https://github.com/trkin/trk_datatables_js/issues/1
  #   'data-datatable-total-length': @datatable.filtered_items_count,
  # ) do
  ""
end

#table_tag_serverObject



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/trk_datatables/render_html.rb', line 81

def table_tag_server
  (
    :table,
    class: "table table-bordered table-striped #{@html_options[:class]}",
    "data-datatable": true,
    "data-datatable-ajax-url": @search_link,
    "data-datatable-page-length": @datatable.dt_per_page_or_default,
    "data-datatable-order": @datatable.dt_orders_or_default_index_and_direction.to_json,
    # for initial page load we do not have ability to show recordsTotal
    # https://github.com/trkin/trk_datatables_js/issues/1
    "data-datatable-total-length": @datatable.filtered_items_count,
    "data-datatable-dom": @html_options[:"data-datatable-dom"] || '<"trk-global-search-wrapper"f>rtp<"trk-move-up"il>'
  ) do
    thead << "\n".html_safe << tbody
  end +
    "\n" # add new line at the end so we can test with HERE_DOC </table>
end

#tbodyObject



120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/trk_datatables/render_html.rb', line 120

def tbody
  # use raw html_safe only for <td>, not for data since it could be injection
  # hole if we show, for example some params
   :tbody do
    safe_join(@datatable.rows(@datatable.ordered_paginated_filtered_items).map do |row|
       :tr do
        safe_join(row.map do |col|
           :td, col.to_s
        end)
      end
    end, "\n".html_safe)
  end
end

#theadObject



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/trk_datatables/render_html.rb', line 99

def thead
   :thead do
     :tr do
      safe_join(@datatable.column_key_options.map do |column_key_option|
        options = column_key_option[:html_options]
        # add eventual value from params
        search_value = @datatable.param_get(column_key_option[:column_key]) if options["data-searchable"] != false
        options["data-datatable-search-value"] = search_value if search_value.present?
        # add eventual select element
        select_options = column_key_option[:column_options][ColumnKeyOptions::SELECT_OPTIONS]
        if select_options.present?
          options["data-datatable-multiselect"] =
            _select_find_options select_options, search_value
        end
        # all other options are pulled from column_key_option[:html_options]
         :th, options, column_key_option[:title]
      end)
    end
  end
end