wice_grid_ms 3.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/.inch.yml +3 -0
- data/.rspec +3 -0
- data/.rubocop.yml +181 -0
- data/.travis.yml +22 -0
- data/CHANGELOG.md +714 -0
- data/Gemfile +4 -0
- data/MIT-LICENSE +20 -0
- data/README.md +1518 -0
- data/Rakefile +59 -0
- data/SAVED_QUERIES_HOWTO.md +113 -0
- data/TODO.md +16 -0
- data/app/views/kaminari/wice_grid/_gap.html.erb +1 -0
- data/app/views/kaminari/wice_grid/_next_page.html.erb +1 -0
- data/app/views/kaminari/wice_grid/_page.html.erb +1 -0
- data/app/views/kaminari/wice_grid/_paginator.html.erb +19 -0
- data/app/views/kaminari/wice_grid/_prev_page.html.erb +1 -0
- data/config/locales/cz.yml +45 -0
- data/config/locales/de.yml +47 -0
- data/config/locales/en.yml +47 -0
- data/config/locales/es.yml +47 -0
- data/config/locales/fr.yml +45 -0
- data/config/locales/is.yml +46 -0
- data/config/locales/it.yml +38 -0
- data/config/locales/ja.yml +47 -0
- data/config/locales/nl.yml +45 -0
- data/config/locales/pt-BR.yml +36 -0
- data/config/locales/pt.yml +45 -0
- data/config/locales/ru.yml +45 -0
- data/config/locales/sk.yml +45 -0
- data/config/locales/uk.yml +45 -0
- data/config/locales/zh.yml +45 -0
- data/lib/generators/wice_grid/add_migration_for_serialized_queries_generator.rb +20 -0
- data/lib/generators/wice_grid/install_generator.rb +14 -0
- data/lib/generators/wice_grid/templates/create_wice_grid_serialized_queries.rb +14 -0
- data/lib/generators/wice_grid/templates/wice_grid_config.rb +192 -0
- data/lib/wice/active_record_column_wrapper.rb +123 -0
- data/lib/wice/columns.rb +276 -0
- data/lib/wice/columns/column_action.rb +52 -0
- data/lib/wice/columns/column_boolean.rb +40 -0
- data/lib/wice/columns/column_bootstrap_datepicker.rb +48 -0
- data/lib/wice/columns/column_custom_dropdown.rb +115 -0
- data/lib/wice/columns/column_float.rb +9 -0
- data/lib/wice/columns/column_html5_datepicker.rb +31 -0
- data/lib/wice/columns/column_integer.rb +78 -0
- data/lib/wice/columns/column_jquery_datepicker.rb +49 -0
- data/lib/wice/columns/column_processor_index.rb +23 -0
- data/lib/wice/columns/column_rails_date_helper.rb +41 -0
- data/lib/wice/columns/column_rails_datetime_helper.rb +40 -0
- data/lib/wice/columns/column_range.rb +72 -0
- data/lib/wice/columns/column_string.rb +92 -0
- data/lib/wice/columns/common_date_datetime_mixin.rb +20 -0
- data/lib/wice/columns/common_js_date_datetime_conditions_generator_mixin.rb +42 -0
- data/lib/wice/columns/common_js_date_datetime_mixin.rb +15 -0
- data/lib/wice/columns/common_rails_date_datetime_conditions_generator_mixin.rb +26 -0
- data/lib/wice/columns/common_standard_helper_date_datetime_mixin.rb +22 -0
- data/lib/wice/grid_output_buffer.rb +49 -0
- data/lib/wice/grid_renderer.rb +609 -0
- data/lib/wice/helpers/bs_calendar_helpers.rb +66 -0
- data/lib/wice/helpers/js_calendar_helpers.rb +83 -0
- data/lib/wice/helpers/wice_grid_misc_view_helpers.rb +75 -0
- data/lib/wice/helpers/wice_grid_serialized_queries_view_helpers.rb +95 -0
- data/lib/wice/helpers/wice_grid_view_helpers.rb +718 -0
- data/lib/wice/kaminari_monkey_patching.rb +14 -0
- data/lib/wice/table_column_matrix.rb +65 -0
- data/lib/wice/wice_grid_controller.rb +223 -0
- data/lib/wice/wice_grid_core_ext.rb +142 -0
- data/lib/wice/wice_grid_misc.rb +209 -0
- data/lib/wice/wice_grid_serialized_queries_controller.rb +87 -0
- data/lib/wice/wice_grid_serialized_query.rb +14 -0
- data/lib/wice/wice_grid_spreadsheet.rb +20 -0
- data/lib/wice_grid.rb +676 -0
- data/release_notes/RELEASE_NOTES_3.2.pre1.rdoc +81 -0
- data/release_notes/RELEASE_NOTES_3.2.pre2.rdoc +6 -0
- data/release_notes/RELEASE_NOTES_3.3.0.rdoc +21 -0
- data/spec/schema.rb +9 -0
- data/spec/spec_helper.rb +75 -0
- data/spec/support/active_record.rb +11 -0
- data/spec/support/wice_grid_test_config.rb +175 -0
- data/spec/wice/grid_output_buffer_spec.rb +41 -0
- data/spec/wice/table_column_matrix_spec.rb +38 -0
- data/spec/wice/wice_grid_misc_spec.rb +159 -0
- data/spec/wice/wice_grid_spreadsheet_spec.rb +14 -0
- data/test/readme.txt +1 -0
- data/vendor/assets/javascripts/wice_grid.js +3 -0
- data/vendor/assets/javascripts/wice_grid_init.js.coffee +339 -0
- data/vendor/assets/javascripts/wice_grid_processor.js.coffee +133 -0
- data/vendor/assets/javascripts/wice_grid_saved_queries_init.js.coffee +103 -0
- data/vendor/assets/stylesheets/wice_grid.scss +81 -0
- data/wice_grid.gemspec +36 -0
- metadata +335 -0
@@ -0,0 +1,66 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Wice #:nodoc:
|
3
|
+
module BsCalendarHelpers #:nodoc:
|
4
|
+
|
5
|
+
# A struct containing all data for rendering a calendar
|
6
|
+
class CalendarData #:nodoc:
|
7
|
+
|
8
|
+
# :nodoc:
|
9
|
+
attr_accessor :name,
|
10
|
+
:date_string,
|
11
|
+
:dom_id,
|
12
|
+
:datepicker_placeholder_id,
|
13
|
+
:date_div_id,
|
14
|
+
:fire_event,
|
15
|
+
:close_calendar_event_name,
|
16
|
+
:the_other_datepicker_id_to,
|
17
|
+
:the_other_datepicker_id_from
|
18
|
+
end
|
19
|
+
|
20
|
+
def date_calendar_bs(calendar_data) #:nodoc:
|
21
|
+
text_field_tag_options = {
|
22
|
+
:id => calendar_data.dom_id,
|
23
|
+
'data-provide' => 'datepicker',
|
24
|
+
'data-date-language' => I18n.locale,
|
25
|
+
'data-date-autoclose' => true,
|
26
|
+
'data-date-format' => Wice::ConfigurationProvider.value_for(:DATE_FORMAT_BOOTSTRAP)
|
27
|
+
}
|
28
|
+
|
29
|
+
text_field_tag_options['class'] = 'form-control input-sm'
|
30
|
+
|
31
|
+
if Rails.env.development?
|
32
|
+
text_field_tag_options['class'] += ' check-for-bsdatepicker'
|
33
|
+
end
|
34
|
+
|
35
|
+
if calendar_data.fire_event
|
36
|
+
text_field_tag_options['data-close-calendar-event-name'] = calendar_data.close_calendar_event_name
|
37
|
+
end
|
38
|
+
|
39
|
+
if calendar_data.the_other_datepicker_id_to
|
40
|
+
text_field_tag_options['data-the-other-bsdatepicker-id-to'] = calendar_data.the_other_datepicker_id_to
|
41
|
+
end
|
42
|
+
|
43
|
+
if calendar_data.the_other_datepicker_id_from
|
44
|
+
text_field_tag_options['data-the-other-bsdatepicker-id-from'] = calendar_data.the_other_datepicker_id_from
|
45
|
+
end
|
46
|
+
|
47
|
+
date_picker = text_field_tag(calendar_data.name, calendar_data.date_string, text_field_tag_options)
|
48
|
+
|
49
|
+
"<div id=\"#{calendar_data.datepicker_placeholder_id}\">#{date_picker}</div>"
|
50
|
+
end
|
51
|
+
|
52
|
+
def prepare_data_for_bscalendar(options) #:nodoc:
|
53
|
+
date_format = Wice::ConfigurationProvider.value_for(:DATE_FORMAT)
|
54
|
+
|
55
|
+
CalendarData.new.tap do |calendar_data|
|
56
|
+
calendar_data.name = options[:name]
|
57
|
+
calendar_data.date_string = options[:initial_date].nil? ? '' : options[:initial_date].strftime(date_format)
|
58
|
+
calendar_data.dom_id = options[:name].gsub(/([\[\(])|(\]\[)/, '_').gsub(/[\]\)]/, '').gsub(/\./, '_').gsub(/_+/, '_')
|
59
|
+
calendar_data.datepicker_placeholder_id = calendar_data.dom_id + '_date_placeholder'
|
60
|
+
calendar_data.date_div_id = calendar_data.dom_id + '_date_view'
|
61
|
+
calendar_data.close_calendar_event_name = "wg:calendarChanged_#{options[:grid_name]}"
|
62
|
+
calendar_data.fire_event = options[:fire_event]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Wice #:nodoc:
|
3
|
+
module JsCalendarHelpers #:nodoc:
|
4
|
+
|
5
|
+
# A struct containing all data for rendering a calendar
|
6
|
+
class CalendarData
|
7
|
+
|
8
|
+
# :nodoc:
|
9
|
+
attr_accessor :name,
|
10
|
+
:date_string,
|
11
|
+
:dom_id,
|
12
|
+
:datepicker_placeholder_id,
|
13
|
+
:date_span_id,
|
14
|
+
:close_calendar_event_name,
|
15
|
+
:title,
|
16
|
+
:fire_event,
|
17
|
+
:the_other_datepicker_id_to,
|
18
|
+
:the_other_datepicker_id_from
|
19
|
+
end
|
20
|
+
|
21
|
+
def date_calendar_jquery(calendar_data) #:nodoc:
|
22
|
+
hidden_field_tag_options = {
|
23
|
+
:id => calendar_data.dom_id,
|
24
|
+
'data-locale' => I18n.locale,
|
25
|
+
'data-date-format' => Wice::ConfigurationProvider.value_for(:DATE_FORMAT_JQUERY),
|
26
|
+
'data-button-text' => calendar_data.title
|
27
|
+
}
|
28
|
+
|
29
|
+
if calendar_data.fire_event
|
30
|
+
hidden_field_tag_options['data-close-calendar-event-name'] = calendar_data.close_calendar_event_name
|
31
|
+
end
|
32
|
+
|
33
|
+
if Rails.env.development?
|
34
|
+
hidden_field_tag_options['class'] = 'check-for-datepicker'
|
35
|
+
end
|
36
|
+
|
37
|
+
if calendar_data.the_other_datepicker_id_to
|
38
|
+
hidden_field_tag_options['data-the-other-datepicker-id-to'] = calendar_data.the_other_datepicker_id_to
|
39
|
+
end
|
40
|
+
|
41
|
+
if calendar_data.the_other_datepicker_id_from
|
42
|
+
hidden_field_tag_options['data-the-other-datepicker-id-from'] = calendar_data.the_other_datepicker_id_from
|
43
|
+
end
|
44
|
+
|
45
|
+
if year_range = ConfigurationProvider.value_for(:DATEPICKER_YEAR_RANGE)
|
46
|
+
hidden_field_tag_options['data-date-year-range'] = year_range
|
47
|
+
end
|
48
|
+
|
49
|
+
date_picker = hidden_field_tag(calendar_data.name, calendar_data.date_string, hidden_field_tag_options) + ' ' +
|
50
|
+
|
51
|
+
link_to(
|
52
|
+
calendar_data.date_string,
|
53
|
+
'#',
|
54
|
+
:id => calendar_data.date_span_id,
|
55
|
+
:class => 'date-label',
|
56
|
+
:title => ::Wice::NlMessage['date_string_tooltip'],
|
57
|
+
'data-dom-id' => calendar_data.dom_id
|
58
|
+
)
|
59
|
+
|
60
|
+
content_tag(
|
61
|
+
:span,
|
62
|
+
date_picker,
|
63
|
+
id: calendar_data.datepicker_placeholder_id,
|
64
|
+
class: 'jq-datepicker-container'
|
65
|
+
)
|
66
|
+
end
|
67
|
+
|
68
|
+
def prepare_data_for_calendar(options) #:nodoc:
|
69
|
+
date_format = Wice::ConfigurationProvider.value_for(:DATE_FORMAT)
|
70
|
+
|
71
|
+
CalendarData.new.tap do |calendar_data|
|
72
|
+
calendar_data.name = options[:name]
|
73
|
+
calendar_data.date_string = options[:initial_date].nil? ? '' : options[:initial_date].strftime(date_format)
|
74
|
+
calendar_data.dom_id = options[:name].gsub(/([\[\(])|(\]\[)/, '_').gsub(/[\]\)]/, '').gsub(/\./, '_').gsub(/_+/, '_')
|
75
|
+
calendar_data.datepicker_placeholder_id = calendar_data.dom_id + '_date_placeholder'
|
76
|
+
calendar_data.date_span_id = calendar_data.dom_id + '_date_view'
|
77
|
+
calendar_data.close_calendar_event_name = "wg:calendarChanged_#{options[:grid_name]}"
|
78
|
+
calendar_data.title = options[:title]
|
79
|
+
calendar_data.fire_event = options[:fire_event]
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Wice
|
3
|
+
|
4
|
+
# Various grid related helpers
|
5
|
+
module GridViewHelper
|
6
|
+
# This method dumps all HTTP parameters related to filtering and ordering of a certain grid as hidden form fields.
|
7
|
+
# This might be required if you want to keep the state of a grid while reloading the page using other forms.
|
8
|
+
#
|
9
|
+
# The only parameter is a grid object returned by +initialize_grid+ in the controller.
|
10
|
+
def dump_filter_parameters_as_hidden_fields(grid)
|
11
|
+
unless grid.is_a? WiceGrid
|
12
|
+
fail WiceGridArgumentError.new('dump_filter_parameters_as_hidden_fields: the parameter must be a WiceGrid instance.')
|
13
|
+
end
|
14
|
+
|
15
|
+
grid.get_state_as_parameter_value_pairs(true).collect do|param_name, value|
|
16
|
+
hidden_field_tag(param_name, value, id: "hidden-#{param_name.gsub(/[\[\]]/, '-')}")
|
17
|
+
end.join("\n").html_safe
|
18
|
+
end
|
19
|
+
|
20
|
+
# This method dumps all HTTP parameters related to filtering of a certain grid in the form of a hash.
|
21
|
+
# This might be required if you want to keep the state of a grid while reloading the page using Rails routing helpers.
|
22
|
+
# Attention: this does not return parameters for ordering the grid, use +filter_and_order_state_as_hash+ if you
|
23
|
+
# need it.
|
24
|
+
#
|
25
|
+
# The only parameter is a grid object returned by +initialize_grid+ in the controller.
|
26
|
+
def filter_state_as_hash(grid)
|
27
|
+
{ grid.name => { 'f' => grid.status[:f] } }
|
28
|
+
end
|
29
|
+
|
30
|
+
# This method dumps all HTTP parameters related to filtering and ordering of a certain grid in the form of a hash.
|
31
|
+
# This might be required if you want to keep the state of a grid while reloading the page using Rails routing helpers.
|
32
|
+
#
|
33
|
+
# The only parameter is a grid object returned by +initialize_grid+ in the controller.
|
34
|
+
def filter_and_order_state_as_hash(grid)
|
35
|
+
{
|
36
|
+
grid.name => {
|
37
|
+
'f' => grid.status[:f],
|
38
|
+
'order' => grid.status[:order],
|
39
|
+
'order_direction' => grid.status[:order_direction]
|
40
|
+
}
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
# display the state of the grid
|
45
|
+
def dump_state(grid) #:nodoc:
|
46
|
+
debug(grid.get_state_as_parameter_value_pairs)
|
47
|
+
end
|
48
|
+
|
49
|
+
# secret but stupid weapon - takes an ActiveRecord and using reflection tries to build all the column clauses by itself.
|
50
|
+
# WiceGrid is not a scaffolding solution, I hate scaffolding and how certain idiots associate scaffolding with Rails,
|
51
|
+
# so I do not document this method to avoid contributing to this misunderstanding.
|
52
|
+
def scaffolded_grid(grid_obj, opts = {}) #:nodoc:
|
53
|
+
unless grid_obj.is_a? WiceGrid
|
54
|
+
fail WiceGridArgumentError.new('scaffolded_grid: the parameter must be a WiceGrid instance.')
|
55
|
+
end
|
56
|
+
|
57
|
+
# debug grid.klass.column_names
|
58
|
+
columns = grid_obj.klass.column_names
|
59
|
+
if opts[:reject_attributes].is_a? Proc
|
60
|
+
columns = columns.reject { |c| opts[:reject_attributes].call(c) }
|
61
|
+
opts.delete(:reject_attributes)
|
62
|
+
else
|
63
|
+
columns = columns.reject { |c| c =~ opts[:reject_attributes] }
|
64
|
+
opts.delete(:reject_attributes)
|
65
|
+
end
|
66
|
+
grid(grid_obj, opts) do |g|
|
67
|
+
columns.each do |column_name|
|
68
|
+
g.column name: column_name.humanize, attribute: column_name do |ar|
|
69
|
+
ar.send(column_name)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Wice
|
3
|
+
module GridViewHelper
|
4
|
+
# View helper to render the list of saved queries and the form to create a new query.
|
5
|
+
# Parameters:
|
6
|
+
# * <tt>:extra_parameters</tt> - a hash of additional parameters to use when creating a new query object.
|
7
|
+
# * <tt>:confirm</tt> - A boolean value which turns on or off the JS confirm dialogs when deleting saved queries.
|
8
|
+
# Read section "Adding Application Specific Logic to Saving/Restoring Queries" in README for more details.
|
9
|
+
def saved_queries_panel(grid, opts = {})
|
10
|
+
unless grid.is_a? WiceGrid
|
11
|
+
fail WiceGridArgumentError.new('saved_queries_panel: the parameter must be a WiceGrid instance.')
|
12
|
+
end
|
13
|
+
|
14
|
+
options = { extra_parameters: {}, confirm: 1 }
|
15
|
+
opts.assert_valid_keys(options.keys)
|
16
|
+
options.merge!(opts)
|
17
|
+
|
18
|
+
grid_name = grid.name
|
19
|
+
input_field_name = "#{grid_name}_saved_query_name"
|
20
|
+
base_path_to_query_controller = create_serialized_query_url(grid_name: grid_name, confirm: options[:confirm])
|
21
|
+
|
22
|
+
parameters = grid.get_state_as_parameter_value_pairs
|
23
|
+
|
24
|
+
options[:extra_parameters].each do |k, v|
|
25
|
+
parameters << [CGI.unescape({ extra: { k => '' } }.to_query.sub(/=$/, '')), v.to_s]
|
26
|
+
end
|
27
|
+
parameters << ['authenticity_token', form_authenticity_token]
|
28
|
+
notification_messages_id = "#{grid_name}_notification_messages"
|
29
|
+
(%( <div class="wice-grid-query-panel well"><h3>#{NlMessage['saved_query_panel_title']}</h3>) +
|
30
|
+
saved_queries_list(grid_name, grid.saved_query, options[:extra_parameters], options[:confirm]) +
|
31
|
+
%(<div id="#{notification_messages_id}" ></div>) +
|
32
|
+
if block_given?
|
33
|
+
view, ids = yield
|
34
|
+
view
|
35
|
+
else
|
36
|
+
''
|
37
|
+
end +
|
38
|
+
|
39
|
+
'<div class="form-horizontal"><div class="wg-saved-query-input-controls input-append">' + text_field_tag(input_field_name, '', onkeydown: '', class: 'wice-grid-save-query-field form-control ') +
|
40
|
+
button_tag(
|
41
|
+
NlMessage['save_query_button_label'],
|
42
|
+
class: 'wice-grid-save-query-button btn btn-primary',
|
43
|
+
'data-grid-name' => grid_name,
|
44
|
+
'data-base-path-to-query-controller' => base_path_to_query_controller,
|
45
|
+
'data-parameters' => parameters.to_json,
|
46
|
+
'data-ids' => ids.to_json
|
47
|
+
) +
|
48
|
+
'</div></div></div>'
|
49
|
+
).html_safe
|
50
|
+
end
|
51
|
+
|
52
|
+
def saved_queries_list(grid_name, saved_query = nil, extra_parameters = {}, confirm = 1) #:nodoc:
|
53
|
+
link_title = NlMessage['saved_query_link_title']
|
54
|
+
deletion_confirmation = confirm ? NlMessage['saved_query_deletion_confirmation'] : nil
|
55
|
+
deletion_link_title = NlMessage['saved_query_deletion_link_title']
|
56
|
+
|
57
|
+
query_store_model = ::Wice.get_query_store_model
|
58
|
+
currently_loaded_query_id = saved_query ? saved_query.id : nil
|
59
|
+
# with = extra_parameters.nil? ? nil : "'" + {extra: extra_parameters}.to_query + "'"
|
60
|
+
|
61
|
+
%(<ul id="#{grid_name}_query_list" class="query-list"> ) +
|
62
|
+
query_store_model.list(grid_name, controller).collect do |sq|
|
63
|
+
link_opts = {
|
64
|
+
class: 'wice-grid-query-load-link',
|
65
|
+
title: "#{link_title} #{sq.name}",
|
66
|
+
'data-query-id' => sq.id,
|
67
|
+
'data-grid-name' => grid_name
|
68
|
+
}
|
69
|
+
link_opts[:class] += ' current' if saved_query == sq
|
70
|
+
'<li>' + link_to(
|
71
|
+
content_tag(:i, '', class: 'fa fa-trash-o delete-icon'),
|
72
|
+
delete_serialized_query_path(
|
73
|
+
grid_name: grid_name,
|
74
|
+
id: sq.id,
|
75
|
+
current: currently_loaded_query_id,
|
76
|
+
extra: extra_parameters,
|
77
|
+
confirm: confirm
|
78
|
+
),
|
79
|
+
class: 'wice-grid-delete-query',
|
80
|
+
'data-wg-confirm' => deletion_confirmation,
|
81
|
+
'data-grid-name' => grid_name,
|
82
|
+
title: "#{deletion_link_title} #{sq.name}"
|
83
|
+
) + ' ' +
|
84
|
+
link_to(h(sq.name), '#', link_opts) +
|
85
|
+
if sq.respond_to? :description
|
86
|
+
desc = sq.description
|
87
|
+
desc.blank? ? '' : " <i>#{desc}</i>"
|
88
|
+
else
|
89
|
+
''
|
90
|
+
end +
|
91
|
+
'</li>'
|
92
|
+
end.join('') + '</ul>'
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,718 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Wice
|
3
|
+
module GridViewHelper
|
4
|
+
# View helper for rendering the grid.
|
5
|
+
#
|
6
|
+
# The first parameter is a grid object returned by +initialize_grid+ in the controller.
|
7
|
+
#
|
8
|
+
# The second parameter is a hash of options:
|
9
|
+
# * <tt>:html</tt> - a hash of HTML attributes to be included into the <tt>table</tt> tag.
|
10
|
+
# * <tt>:class</tt> - a shortcut for <tt>html: {class: 'css_class'}</tt>
|
11
|
+
# * <tt>:header_tr_html</tt> - a hash of HTML attributes to be included into the first <tt>tr</tt> tag
|
12
|
+
# (or two first <tt>tr</tt>'s if the filter row is present).
|
13
|
+
# * <tt>:show_filters</tt> - defines when the filter is shown. Possible values are:
|
14
|
+
# * <tt>:when_filtered</tt> - the filter is shown when the current table is the result of filtering
|
15
|
+
# * <tt>:always</tt> or <tt>true</tt> - show the filter always
|
16
|
+
# * <tt>:no</tt> or <tt>false</tt> - never show the filter
|
17
|
+
# * <tt>:upper_pagination_panel</tt> - a boolean value which defines whether there is an additional pagination
|
18
|
+
# panel on top of the table. By default it is false.
|
19
|
+
# * <tt>:extra_request_parameters</tt> - a hash which will be added as additional HTTP request parameters to all
|
20
|
+
# links generated by the grid, be it sorting links, filters, or the 'Reset Filter' icon.
|
21
|
+
# Please note that WiceGrid respects and retains all request parameters already present in the URL which
|
22
|
+
# formed the page, so there is no need to enumerate them in <tt>:extra_request_parameters</tt>. A typical
|
23
|
+
# usage of <tt>:extra_request_parameters</tt> is a page with javascript tabs - changing the active tab
|
24
|
+
# does not reload the page, but if one such tab contains a WiceGrid, it could be required that if the user
|
25
|
+
# orders or filters the grid, the result page should have the tab with the grid activated. For this we
|
26
|
+
# need to send an additional parameter specifying from which tab the request was generated.
|
27
|
+
# * <tt>:sorting_dependant_row_cycling</tt> - When set to true (by default it is false) the row styles +odd+
|
28
|
+
# and +even+ will be changed only when the content of the cell belonging to the sorted column changes.
|
29
|
+
# In other words, rows with identical values in the ordered column will have the same style (color).
|
30
|
+
# * <tt>:allow_showing_all_records</tt> - allow or prohibit the "All Records" mode.
|
31
|
+
# * <tt>:hide_reset_button</tt> - Do not show the default Filter Reset button.
|
32
|
+
# Useful when using a custom reset button.
|
33
|
+
# By default it is false.
|
34
|
+
# * <tt>:hide_submit_button</tt> - Do not show the default Filter Submit button.
|
35
|
+
# Useful when using a custom submit button
|
36
|
+
# By default it is false.
|
37
|
+
# * <tt>:hide_csv_button</tt> - a boolean value which defines whether the default Export To CSV button
|
38
|
+
# should be rendered. Useful when using a custom Export To CSV button.
|
39
|
+
# By default it is false.
|
40
|
+
# Please read README for more insights.
|
41
|
+
#
|
42
|
+
# The block contains definitions of grid columns using the +column+ method sent to the object yielded into
|
43
|
+
# the block. In other words, the value returned by each of the blocks defines the content of a cell, the
|
44
|
+
# first block is called for cells of the first column for each row (each ActiveRecord instance), the
|
45
|
+
# second block is called for cells of the second column, and so on. See the example:
|
46
|
+
#
|
47
|
+
# <%= grid(@accounts_grid, html: {class: 'grid_style', id: 'accounts_grid'}, header_tr_html: {class: 'grid_headers'}) do |g|
|
48
|
+
#
|
49
|
+
# g.column name: 'Username', attribute: 'username' do |account|
|
50
|
+
# account.username
|
51
|
+
# end
|
52
|
+
#
|
53
|
+
# g.column name: 'application_account.field.identity_id'._, attribute: 'firstname', model: Person do |account|
|
54
|
+
# link_to(account.identity.name, identity_path(account.identity))
|
55
|
+
# end
|
56
|
+
#
|
57
|
+
# g.column do |account|
|
58
|
+
# link_to('Edit', edit_account_path(account))
|
59
|
+
# end
|
60
|
+
#
|
61
|
+
# end -%>
|
62
|
+
#
|
63
|
+
#
|
64
|
+
# Defaults for parameters <tt>:show_filters</tt> and <tt>:upper_pagination_panel</tt>
|
65
|
+
# can be changed in <tt>lib/wice_grid_config.rb</tt> using constants <tt>Wice::Defaults::SHOW_FILTER</tt> and
|
66
|
+
# <tt>WiceGrid::Defaults::SHOW_UPPER_PAGINATION_PANEL</tt>, this is convenient if you want to set a project wide setting
|
67
|
+
# without having to repeat it for every grid instance.
|
68
|
+
#
|
69
|
+
# Pease read documentation about the +column+ method to achieve the enlightenment.
|
70
|
+
|
71
|
+
def grid(grid, opts = {}, &block)
|
72
|
+
fail WiceGridArgumentError.new('Missing block for the grid helper.' \
|
73
|
+
' For detached filters use first define_grid with the same API as grid, ' \
|
74
|
+
'then grid_filter to add filters, and then render_grid to actually show the grid') if block.nil?
|
75
|
+
define_grid(grid, opts, &block)
|
76
|
+
render_grid(grid)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Has the same parameters as <tt>grid</tt> but does not output the grid. After <tt>define_grid</tt>
|
80
|
+
# <tt>render_grid</tt> can be used to output the grid HTML code.
|
81
|
+
# Usually used with detached filters: first <tt>define_grid</tt>, then <tt>grid_filter</tt>s, and then
|
82
|
+
# <tt>render_grid</tt>
|
83
|
+
def define_grid(grid, opts = {}, &block)
|
84
|
+
# strip the method from HTML stuff
|
85
|
+
unless grid.class == WiceGrid
|
86
|
+
fail WiceGridArgumentError.new('The first argument for the grid helper must be an instance of the WiceGrid class')
|
87
|
+
end
|
88
|
+
|
89
|
+
options = {
|
90
|
+
allow_showing_all_records: Defaults::ALLOW_SHOWING_ALL_RECORDS,
|
91
|
+
class: nil,
|
92
|
+
extra_request_parameters: {},
|
93
|
+
header_tr_html: {},
|
94
|
+
hide_reset_button: false,
|
95
|
+
hide_submit_button: false,
|
96
|
+
hide_csv_button: false,
|
97
|
+
show_filters: Defaults::SHOW_FILTER,
|
98
|
+
sorting_dependant_row_cycling: false,
|
99
|
+
html: {},
|
100
|
+
upper_pagination_panel: Defaults::SHOW_UPPER_PAGINATION_PANEL,
|
101
|
+
pagination_theme: ConfigurationProvider.value_for(:PAGINATION_THEME)
|
102
|
+
}
|
103
|
+
|
104
|
+
opts.assert_valid_keys(options.keys)
|
105
|
+
|
106
|
+
options.merge!(opts)
|
107
|
+
|
108
|
+
options[:show_filters] = :no if options[:show_filters] == false
|
109
|
+
options[:show_filters] = :always if options[:show_filters] == true
|
110
|
+
|
111
|
+
rendering = GridRenderer.new(grid, self)
|
112
|
+
|
113
|
+
block.call(rendering) # calling block containing column() calls
|
114
|
+
|
115
|
+
reuse_last_column_for_filter_buttons =
|
116
|
+
Defaults::REUSE_LAST_COLUMN_FOR_FILTER_ICONS && rendering.last_column_for_html.capable_of_hosting_filter_related_icons?
|
117
|
+
|
118
|
+
if grid.output_csv?
|
119
|
+
grid_csv(grid, rendering)
|
120
|
+
else
|
121
|
+
# If blank_slate is defined we don't show any grid at all
|
122
|
+
if rendering.blank_slate_handler && grid.resultset.size == 0 && !grid.filtering_on?
|
123
|
+
generate_blank_slate(grid, rendering)
|
124
|
+
else
|
125
|
+
grid_html(grid, options, rendering, reuse_last_column_for_filter_buttons)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
grid.view_helper_finished = true
|
130
|
+
|
131
|
+
grid.csv_tempfile ? grid.csv_tempfile.path : nil
|
132
|
+
end
|
133
|
+
|
134
|
+
# Used after <tt>define_grid</tt> to actually output the grid HTML code.
|
135
|
+
# Usually used with detached filters: first <tt>define_grid</tt>, then <tt>grid_filter</tt>s, and then
|
136
|
+
# <tt>render_grid</tt>
|
137
|
+
def render_grid(grid)
|
138
|
+
if grid.output_buffer
|
139
|
+
grid.output_buffer
|
140
|
+
elsif grid.csv_tempfile
|
141
|
+
grid.csv_tempfile.path
|
142
|
+
else
|
143
|
+
fail WiceGridException.new("Attempt to use 'render_grid' without 'define_grid' before.")
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def generate_blank_slate(grid, rendering) #:nodoc:
|
148
|
+
grid.output_buffer = GridOutputBuffer.new
|
149
|
+
|
150
|
+
grid.output_buffer << if rendering.blank_slate_handler.is_a?(Proc)
|
151
|
+
call_block(rendering.blank_slate_handler, nil)
|
152
|
+
elsif rendering.blank_slate_handler.is_a?(Hash)
|
153
|
+
render(rendering.blank_slate_handler)
|
154
|
+
else
|
155
|
+
rendering.blank_slate_handler
|
156
|
+
end
|
157
|
+
|
158
|
+
if rendering.find_one_for(:in_html) { |column| column.detach_with_id }
|
159
|
+
grid.output_buffer.return_empty_strings_for_nonexistent_filters = true
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def call_block(block, ar, extra_argument = nil) #:nodoc:
|
164
|
+
extra_argument ? block.call(ar, extra_argument) : block.call(ar)
|
165
|
+
end
|
166
|
+
|
167
|
+
def get_row_content(rendering, ar, sorting_dependant_row_cycling) #:nodoc:
|
168
|
+
cell_value_of_the_ordered_column = nil
|
169
|
+
row_content = ''
|
170
|
+
rendering.each_column(:in_html) do |column|
|
171
|
+
cell_block = column.cell_rendering_block
|
172
|
+
|
173
|
+
opts = column.html
|
174
|
+
|
175
|
+
opts = opts ? opts.clone : {}
|
176
|
+
|
177
|
+
column_block_output = if column.class == Columns.get_view_column_processor(:action)
|
178
|
+
cell_block.call(ar, params)
|
179
|
+
else
|
180
|
+
call_block(cell_block, ar)
|
181
|
+
end
|
182
|
+
|
183
|
+
if column_block_output.is_a?(Array)
|
184
|
+
|
185
|
+
unless column_block_output.size == 2
|
186
|
+
fail WiceGridArgumentError.new('When WiceGrid column block returns an array it is expected to contain 2 elements only - ' \
|
187
|
+
'the first is the contents of the table cell and the second is a hash containing HTML attributes for the <td> tag.')
|
188
|
+
end
|
189
|
+
|
190
|
+
column_block_output, additional_opts = column_block_output
|
191
|
+
|
192
|
+
unless additional_opts.is_a?(Hash)
|
193
|
+
fail WiceGridArgumentError.new('When WiceGrid column block returns an array its second element is expected to be a ' \
|
194
|
+
"hash containing HTML attributes for the <td> tag. The returned value is #{additional_opts.inspect}. Read documentation.")
|
195
|
+
end
|
196
|
+
|
197
|
+
additional_css_class = nil
|
198
|
+
if additional_opts.key?(:class)
|
199
|
+
additional_css_class = additional_opts[:class]
|
200
|
+
additional_opts.delete(:class)
|
201
|
+
elsif additional_opts.key?('class')
|
202
|
+
additional_css_class = additional_opts['class']
|
203
|
+
additional_opts.delete('class')
|
204
|
+
end
|
205
|
+
opts.merge!(additional_opts)
|
206
|
+
Wice::WgHash.add_or_append_class_value!(opts, additional_css_class) unless additional_css_class.blank?
|
207
|
+
end
|
208
|
+
|
209
|
+
if sorting_dependant_row_cycling && column.attribute && grid.ordered_by?(column)
|
210
|
+
cell_value_of_the_ordered_column = column_block_output
|
211
|
+
end
|
212
|
+
row_content += content_tag(:td, column_block_output, opts)
|
213
|
+
end
|
214
|
+
[row_content, cell_value_of_the_ordered_column]
|
215
|
+
end
|
216
|
+
|
217
|
+
# the longest method? :(
|
218
|
+
def grid_html(grid, options, rendering, reuse_last_column_for_filter_buttons) #:nodoc:
|
219
|
+
table_html_attrs, header_tr_html = options[:html], options[:header_tr_html]
|
220
|
+
|
221
|
+
Wice::WgHash.add_or_append_class_value!(table_html_attrs, 'wice-grid', true)
|
222
|
+
|
223
|
+
if Array === Defaults::DEFAULT_TABLE_CLASSES
|
224
|
+
Defaults::DEFAULT_TABLE_CLASSES.each do |default_class|
|
225
|
+
Wice::WgHash.add_or_append_class_value!(table_html_attrs, default_class, true)
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
if options[:class]
|
230
|
+
Wice::WgHash.add_or_append_class_value!(table_html_attrs, options[:class])
|
231
|
+
options.delete(:class)
|
232
|
+
end
|
233
|
+
|
234
|
+
cycle_class = nil
|
235
|
+
sorting_dependant_row_cycling = options[:sorting_dependant_row_cycling]
|
236
|
+
|
237
|
+
grid.output_buffer = GridOutputBuffer.new
|
238
|
+
|
239
|
+
# Ruby 1.9.x
|
240
|
+
grid.output_buffer.force_encoding('UTF-8') if grid.output_buffer.respond_to?(:force_encoding)
|
241
|
+
|
242
|
+
grid.output_buffer << %(<div class="wice-grid-container table-responsive" data-grid-name="#{grid.name}" id="#{grid.name}"><div id="#{grid.name}_title">)
|
243
|
+
grid.output_buffer << content_tag(:h3, grid.saved_query.name) if grid.saved_query
|
244
|
+
grid.output_buffer << "</div><table #{public_tag_options(table_html_attrs, true)}>"
|
245
|
+
grid.output_buffer << "<caption>#{rendering.kaption}</caption>" if rendering.kaption
|
246
|
+
grid.output_buffer << '<thead>'
|
247
|
+
|
248
|
+
no_filters_at_all = (options[:show_filters] == :no || rendering.no_filter_needed?)
|
249
|
+
|
250
|
+
if no_filters_at_all
|
251
|
+
no_rightmost_column = no_filter_row = no_filters_at_all
|
252
|
+
else
|
253
|
+
no_rightmost_column = no_filter_row = (options[:show_filters] == :no || rendering.no_filter_needed_in_main_table?) ? true : false
|
254
|
+
end
|
255
|
+
|
256
|
+
no_rightmost_column = true if reuse_last_column_for_filter_buttons
|
257
|
+
|
258
|
+
number_of_columns = rendering.number_of_columns(:in_html)
|
259
|
+
number_of_columns -= 1 if no_rightmost_column
|
260
|
+
|
261
|
+
number_of_columns_for_extra_rows = number_of_columns + 1
|
262
|
+
|
263
|
+
pagination_panel_content_html = nil
|
264
|
+
if options[:upper_pagination_panel]
|
265
|
+
grid.output_buffer << rendering.pagination_panel(number_of_columns, options[:hide_csv_button]) do
|
266
|
+
pagination_panel_content_html =
|
267
|
+
pagination_panel_content(grid, options[:extra_request_parameters], options[:allow_showing_all_records], options[:pagination_theme])
|
268
|
+
pagination_panel_content_html
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
title_row_attrs = header_tr_html.clone
|
273
|
+
Wice::WgHash.add_or_append_class_value!(title_row_attrs, 'wice-grid-title-row', true)
|
274
|
+
|
275
|
+
grid.output_buffer << %(<tr #{public_tag_options(title_row_attrs, true)}>)
|
276
|
+
|
277
|
+
filter_row_id = grid.name + '_filter_row'
|
278
|
+
|
279
|
+
# first row of column labels with sorting links
|
280
|
+
|
281
|
+
filter_shown = if options[:show_filters] == :when_filtered
|
282
|
+
grid.filtering_on?
|
283
|
+
elsif options[:show_filters] == :always
|
284
|
+
true
|
285
|
+
end
|
286
|
+
|
287
|
+
rendering.each_column_aware_of_one_last_one(:in_html) do |column, last|
|
288
|
+
column_name = column.name
|
289
|
+
|
290
|
+
opts = column.html
|
291
|
+
|
292
|
+
opts = opts ? opts.clone : {}
|
293
|
+
|
294
|
+
Wice::WgHash.add_or_append_class_value!(opts, column.css_class)
|
295
|
+
|
296
|
+
if column.attribute && column.ordering
|
297
|
+
|
298
|
+
column.add_css_class('active-filter') if grid.filtered_by?(column)
|
299
|
+
|
300
|
+
direction = 'asc'
|
301
|
+
link_style = nil
|
302
|
+
arrow_class = nil
|
303
|
+
|
304
|
+
if grid.ordered_by?(column)
|
305
|
+
column.add_css_class('sorted')
|
306
|
+
Wice::WgHash.add_or_append_class_value!(opts, 'sorted')
|
307
|
+
link_style = grid.order_direction
|
308
|
+
|
309
|
+
case grid.order_direction
|
310
|
+
when 'asc'
|
311
|
+
direction = 'desc'
|
312
|
+
arrow_class = 'down'
|
313
|
+
when 'desc'
|
314
|
+
direction = 'asc'
|
315
|
+
arrow_class = 'up'
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
col_link = link_to(
|
320
|
+
(column_name +
|
321
|
+
if arrow_class
|
322
|
+
' ' + content_tag(:i, '', class: "fa fa-arrow-#{arrow_class}")
|
323
|
+
else
|
324
|
+
''
|
325
|
+
end).html_safe,
|
326
|
+
|
327
|
+
rendering.column_link(
|
328
|
+
column,
|
329
|
+
direction,
|
330
|
+
params,
|
331
|
+
options[:extra_request_parameters]
|
332
|
+
),
|
333
|
+
class: link_style)
|
334
|
+
|
335
|
+
grid.output_buffer << content_tag(:th, col_link, opts)
|
336
|
+
|
337
|
+
else
|
338
|
+
if reuse_last_column_for_filter_buttons && last
|
339
|
+
grid.output_buffer << content_tag(:th,
|
340
|
+
hide_show_icon(filter_row_id, grid, filter_shown, no_filter_row, options[:show_filters], rendering), opts
|
341
|
+
)
|
342
|
+
else
|
343
|
+
grid.output_buffer << content_tag(:th, column_name, opts)
|
344
|
+
end
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
grid.output_buffer << content_tag(:th,
|
349
|
+
hide_show_icon(filter_row_id, grid, filter_shown, no_filter_row, options[:show_filters], rendering)
|
350
|
+
) unless no_rightmost_column
|
351
|
+
|
352
|
+
grid.output_buffer << '</tr>'
|
353
|
+
# rendering first row end
|
354
|
+
|
355
|
+
unless no_filters_at_all # there are filters, we don't know where, in the table or detached
|
356
|
+
if no_filter_row # they are all detached
|
357
|
+
rendering.each_column(:in_html) do |column|
|
358
|
+
if column.filter_shown?
|
359
|
+
filter_html_code = column.render_filter.html_safe
|
360
|
+
grid.output_buffer.add_filter(column.detach_with_id, filter_html_code)
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
else # some filters are present in the table
|
365
|
+
|
366
|
+
filter_row_attrs = header_tr_html.clone
|
367
|
+
Wice::WgHash.add_or_append_class_value!(filter_row_attrs, 'wg-filter-row', true)
|
368
|
+
filter_row_attrs['id'] = filter_row_id
|
369
|
+
|
370
|
+
grid.output_buffer << %(<tr #{public_tag_options(filter_row_attrs, true)} )
|
371
|
+
grid.output_buffer << 'style="display:none"' unless filter_shown
|
372
|
+
grid.output_buffer << '>'
|
373
|
+
|
374
|
+
rendering.each_column_aware_of_one_last_one(:in_html) do |column, last|
|
375
|
+
opts = column.html ? column.html.clone : {}
|
376
|
+
Wice::WgHash.add_or_append_class_value!(opts, column.css_class)
|
377
|
+
|
378
|
+
if column.filter_shown?
|
379
|
+
|
380
|
+
filter_html_code = column.render_filter.html_safe
|
381
|
+
if column.detach_with_id
|
382
|
+
grid.output_buffer << content_tag(:th, '', opts)
|
383
|
+
grid.output_buffer.add_filter(column.detach_with_id, filter_html_code)
|
384
|
+
else
|
385
|
+
grid.output_buffer << content_tag(:th, filter_html_code, opts)
|
386
|
+
end
|
387
|
+
else
|
388
|
+
if reuse_last_column_for_filter_buttons && last
|
389
|
+
grid.output_buffer << content_tag(:th,
|
390
|
+
reset_submit_buttons(options, grid, rendering),
|
391
|
+
Wice::WgHash.add_or_append_class_value!(opts, 'filter_icons')
|
392
|
+
)
|
393
|
+
else
|
394
|
+
grid.output_buffer << content_tag(:th, '', opts)
|
395
|
+
end
|
396
|
+
end
|
397
|
+
end
|
398
|
+
unless no_rightmost_column
|
399
|
+
grid.output_buffer << content_tag(:th, reset_submit_buttons(options, grid, rendering), class: 'filter_icons')
|
400
|
+
end
|
401
|
+
grid.output_buffer << '</tr>'
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|
405
|
+
grid.output_buffer << '</thead><tfoot>'
|
406
|
+
grid.output_buffer << rendering.pagination_panel(number_of_columns, options[:hide_csv_button]) do
|
407
|
+
if pagination_panel_content_html
|
408
|
+
pagination_panel_content_html
|
409
|
+
else
|
410
|
+
pagination_panel_content_html =
|
411
|
+
pagination_panel_content(grid, options[:extra_request_parameters], options[:allow_showing_all_records], options[:pagination_theme])
|
412
|
+
pagination_panel_content_html
|
413
|
+
end
|
414
|
+
end
|
415
|
+
|
416
|
+
grid.output_buffer << '</tfoot><tbody>'
|
417
|
+
|
418
|
+
# rendering rows
|
419
|
+
cell_value_of_the_ordered_column = nil
|
420
|
+
previous_cell_value_of_the_ordered_column = nil
|
421
|
+
|
422
|
+
grid.each do |ar| # rows
|
423
|
+
before_row_output = if rendering.before_row_handler
|
424
|
+
call_block(rendering.before_row_handler, ar, number_of_columns_for_extra_rows)
|
425
|
+
end
|
426
|
+
|
427
|
+
after_row_output = if rendering.after_row_handler
|
428
|
+
call_block(rendering.after_row_handler, ar, number_of_columns_for_extra_rows)
|
429
|
+
end
|
430
|
+
|
431
|
+
replace_row_output = if rendering.replace_row_handler
|
432
|
+
call_block(rendering.replace_row_handler, ar, number_of_columns_for_extra_rows)
|
433
|
+
end
|
434
|
+
|
435
|
+
row_content = if replace_row_output
|
436
|
+
no_rightmost_column = true
|
437
|
+
replace_row_output
|
438
|
+
else
|
439
|
+
row_content, tmp_cell_value_of_the_ordered_column = get_row_content(rendering, ar, sorting_dependant_row_cycling)
|
440
|
+
cell_value_of_the_ordered_column = tmp_cell_value_of_the_ordered_column if tmp_cell_value_of_the_ordered_column
|
441
|
+
row_content
|
442
|
+
end
|
443
|
+
|
444
|
+
row_attributes = rendering.get_row_attributes(ar)
|
445
|
+
|
446
|
+
if sorting_dependant_row_cycling
|
447
|
+
cycle_class = cycle('odd', 'even', name: grid.name) if cell_value_of_the_ordered_column != previous_cell_value_of_the_ordered_column
|
448
|
+
previous_cell_value_of_the_ordered_column = cell_value_of_the_ordered_column
|
449
|
+
else
|
450
|
+
cycle_class = cycle('odd', 'even', name: grid.name)
|
451
|
+
end
|
452
|
+
|
453
|
+
Wice::WgHash.add_or_append_class_value!(row_attributes, cycle_class)
|
454
|
+
|
455
|
+
grid.output_buffer << before_row_output if before_row_output
|
456
|
+
grid.output_buffer << "<tr #{public_tag_options(row_attributes)}>#{row_content}"
|
457
|
+
grid.output_buffer << content_tag(:td, '') unless no_rightmost_column
|
458
|
+
grid.output_buffer << '</tr>'
|
459
|
+
grid.output_buffer << after_row_output if after_row_output
|
460
|
+
end
|
461
|
+
|
462
|
+
last_row_output = if rendering.last_row_handler
|
463
|
+
call_block(rendering.last_row_handler, number_of_columns_for_extra_rows)
|
464
|
+
end
|
465
|
+
|
466
|
+
grid.output_buffer << last_row_output if last_row_output
|
467
|
+
|
468
|
+
grid.output_buffer << '</tbody></table>'
|
469
|
+
|
470
|
+
base_link_for_filter, base_link_for_show_all_records = rendering.base_link_for_filter(controller, options[:extra_request_parameters])
|
471
|
+
|
472
|
+
link_for_export = rendering.link_for_export(controller, 'csv', options[:extra_request_parameters])
|
473
|
+
|
474
|
+
parameter_name_for_query_loading = { grid.name => { q: '' } }.to_query
|
475
|
+
parameter_name_for_focus = { grid.name => { foc: '' } }.to_query
|
476
|
+
|
477
|
+
processor_initializer_arguments = [
|
478
|
+
base_link_for_filter,
|
479
|
+
base_link_for_show_all_records,
|
480
|
+
link_for_export,
|
481
|
+
parameter_name_for_query_loading,
|
482
|
+
parameter_name_for_focus,
|
483
|
+
Rails.env
|
484
|
+
]
|
485
|
+
|
486
|
+
filter_declarations = if no_filters_at_all
|
487
|
+
[]
|
488
|
+
else
|
489
|
+
rendering.select_for(:in_html) do |vc|
|
490
|
+
vc.attribute && vc.filter
|
491
|
+
end.collect(&:yield_declaration)
|
492
|
+
end
|
493
|
+
|
494
|
+
wg_data = {
|
495
|
+
'data-processor-initializer-arguments' => processor_initializer_arguments.to_json,
|
496
|
+
'data-filter-declarations' => filter_declarations.to_json,
|
497
|
+
:class => 'wg-data'
|
498
|
+
}
|
499
|
+
|
500
|
+
wg_data['data-foc'] = grid.status['foc'] if grid.status['foc']
|
501
|
+
|
502
|
+
grid.output_buffer << content_tag(:div, '', wg_data)
|
503
|
+
|
504
|
+
grid.output_buffer << '</div>'
|
505
|
+
|
506
|
+
if Rails.env.development?
|
507
|
+
grid.output_buffer << javascript_tag(%/ $(document).ready(function(){ \n/ +
|
508
|
+
%$ if (typeof(WiceGridProcessor) == "undefined"){\n$ +
|
509
|
+
%$ alert("wice_grid.js not loaded, WiceGrid cannot proceed!\\n" +\n$ +
|
510
|
+
%( "Make sure that you have loaded wice_grid.js.\\n" + ) +
|
511
|
+
%( "Add line //= require wice_grid.js " + ) +
|
512
|
+
%$ "to app/assets/javascripts/application.js")\n$ +
|
513
|
+
%( } ) +
|
514
|
+
%$ }) $)
|
515
|
+
end
|
516
|
+
|
517
|
+
grid.output_buffer
|
518
|
+
end
|
519
|
+
|
520
|
+
def hide_show_icon(_filter_row_id, _grid, filter_shown, no_filter_row, show_filters, _rendering) #:nodoc:
|
521
|
+
no_filter_opening_closing_icon = (show_filters == :always) || no_filter_row
|
522
|
+
|
523
|
+
styles = ['display: block;', 'display: none;']
|
524
|
+
styles.reverse! unless filter_shown
|
525
|
+
|
526
|
+
if no_filter_opening_closing_icon
|
527
|
+
''
|
528
|
+
else
|
529
|
+
|
530
|
+
content_tag(:div, content_tag(:i, '', class: 'fa fa-eye-slash'),
|
531
|
+
title: NlMessage['hide_filter_tooltip'],
|
532
|
+
style: styles[0],
|
533
|
+
class: 'clickable wg-hide-filter'
|
534
|
+
) +
|
535
|
+
|
536
|
+
content_tag(:div, content_tag(:i, '', class: 'fa fa-eye'),
|
537
|
+
title: NlMessage['show_filter_tooltip'],
|
538
|
+
style: styles[1],
|
539
|
+
class: 'clickable wg-show-filter'
|
540
|
+
)
|
541
|
+
|
542
|
+
end
|
543
|
+
end
|
544
|
+
|
545
|
+
def reset_submit_buttons(options, grid, _rendering) #:nodoc:
|
546
|
+
if options[:hide_submit_button]
|
547
|
+
''
|
548
|
+
else
|
549
|
+
content_tag(:div, content_tag(:i, '', class: 'fa fa-filter'),
|
550
|
+
title: NlMessage['filter_tooltip'],
|
551
|
+
id: grid.name + '_submit_grid_icon',
|
552
|
+
class: 'submit clickable'
|
553
|
+
)
|
554
|
+
end.html_safe + ' ' +
|
555
|
+
if options[:hide_reset_button]
|
556
|
+
''
|
557
|
+
else
|
558
|
+
|
559
|
+
content_tag(:div, content_tag(:i, '', class: 'fa fa-table'),
|
560
|
+
title: NlMessage['reset_filter_tooltip'],
|
561
|
+
id: grid.name + '_reset_grid_icon',
|
562
|
+
class: 'reset clickable'
|
563
|
+
)
|
564
|
+
end.html_safe
|
565
|
+
end
|
566
|
+
|
567
|
+
# Renders a detached filter. The parameters are:
|
568
|
+
# * +grid+ the WiceGrid object
|
569
|
+
# * +filter_key+ an identifier of the filter specified in the column declaration by parameter +:detach_with_id+
|
570
|
+
def grid_filter(grid, filter_key)
|
571
|
+
unless grid.is_a? WiceGrid
|
572
|
+
fail WiceGridArgumentError.new('grid_filter: the parameter must be a WiceGrid instance.')
|
573
|
+
end
|
574
|
+
if grid.output_buffer.nil?
|
575
|
+
fail WiceGridArgumentError.new("grid_filter: You have attempted to run 'grid_filter' before 'grid'. Read about detached filters in the documentation.")
|
576
|
+
end
|
577
|
+
if grid.output_buffer == true
|
578
|
+
fail WiceGridArgumentError.new('grid_filter: You have defined no detached filters, or you try use detached filters with' \
|
579
|
+
':show_filters => :no (set :show_filters to :always in this case). Read about detached filters in the documentation.')
|
580
|
+
end
|
581
|
+
|
582
|
+
content_tag :span,
|
583
|
+
grid.output_buffer.filter_for(filter_key),
|
584
|
+
class: "wg-detached-filter #{grid.name}_detached_filter",
|
585
|
+
'data-grid-name' => grid.name
|
586
|
+
end
|
587
|
+
|
588
|
+
def grid_csv(grid, rendering) #:nodoc:
|
589
|
+
spreadsheet = ::Wice::Spreadsheet.new(grid.name, grid.csv_field_separator, grid.csv_encoding)
|
590
|
+
|
591
|
+
# columns
|
592
|
+
spreadsheet << rendering.column_labels(:in_csv)
|
593
|
+
|
594
|
+
# rendering rows
|
595
|
+
grid.each do |ar| # rows
|
596
|
+
row = []
|
597
|
+
|
598
|
+
rendering.each_column(:in_csv) do |column|
|
599
|
+
cell_block = column.cell_rendering_block
|
600
|
+
|
601
|
+
column_block_output = call_block(cell_block, ar)
|
602
|
+
|
603
|
+
if column_block_output.is_a?(Array)
|
604
|
+
column_block_output, _additional_opts = column_block_output
|
605
|
+
end
|
606
|
+
|
607
|
+
row << column_block_output
|
608
|
+
end
|
609
|
+
spreadsheet << row
|
610
|
+
end
|
611
|
+
grid.csv_tempfile = spreadsheet.tempfile
|
612
|
+
end
|
613
|
+
|
614
|
+
def pagination_panel_content(grid, extra_request_parameters, allow_showing_all_records, pagination_theme) #:nodoc:
|
615
|
+
extra_request_parameters = extra_request_parameters.clone
|
616
|
+
if grid.saved_query
|
617
|
+
extra_request_parameters["#{grid.name}[q]"] = grid.saved_query.id
|
618
|
+
end
|
619
|
+
|
620
|
+
html = pagination_info(grid, allow_showing_all_records)
|
621
|
+
|
622
|
+
paginate(grid.resultset,
|
623
|
+
theme: pagination_theme,
|
624
|
+
param_name: "#{grid.name}[page]",
|
625
|
+
params: extra_request_parameters,
|
626
|
+
inner_window: 4,
|
627
|
+
outer_window: 2
|
628
|
+
) +
|
629
|
+
(' <div class="pagination_status">' + html + '</div>').html_safe
|
630
|
+
end
|
631
|
+
|
632
|
+
def show_all_link(collection_total_entries, parameters, _grid_name) #:nodoc:
|
633
|
+
message = NlMessage['all_queries_warning']
|
634
|
+
confirmation = collection_total_entries > Defaults::START_SHOWING_WARNING_FROM ? message : nil
|
635
|
+
|
636
|
+
html = content_tag(:a, NlMessage['show_all_records_label'],
|
637
|
+
href: '#',
|
638
|
+
title: NlMessage['show_all_records_tooltip'],
|
639
|
+
class: 'wg-show-all-link',
|
640
|
+
'data-grid-state' => parameters.to_json,
|
641
|
+
'data-confim-message' => confirmation
|
642
|
+
)
|
643
|
+
|
644
|
+
[html, '']
|
645
|
+
end
|
646
|
+
|
647
|
+
def back_to_pagination_link(parameters, grid_name) #:nodoc:
|
648
|
+
pagination_override_parameter_name = "#{grid_name}[pp]"
|
649
|
+
parameters = parameters.reject { |k, _v| k == pagination_override_parameter_name }
|
650
|
+
|
651
|
+
content_tag(:a, NlMessage['switch_back_to_paginated_mode_label'],
|
652
|
+
href: '#',
|
653
|
+
title: NlMessage['switch_back_to_paginated_mode_tooltip'],
|
654
|
+
class: 'wg-back-to-pagination-link',
|
655
|
+
'data-grid-state' => parameters.to_json
|
656
|
+
)
|
657
|
+
end
|
658
|
+
|
659
|
+
def pagination_info(grid, allow_showing_all_records) #:nodoc:
|
660
|
+
collection = grid.resultset
|
661
|
+
|
662
|
+
if grid.all_record_mode?
|
663
|
+
|
664
|
+
collection_total_entries = collection.length
|
665
|
+
|
666
|
+
first = 1
|
667
|
+
last = collection.size
|
668
|
+
|
669
|
+
num_pages = 1
|
670
|
+
|
671
|
+
class << collection
|
672
|
+
def current_page
|
673
|
+
1
|
674
|
+
end
|
675
|
+
|
676
|
+
def total_pages
|
677
|
+
1
|
678
|
+
end
|
679
|
+
end
|
680
|
+
|
681
|
+
else
|
682
|
+
collection_total_entries = collection.total_count
|
683
|
+
|
684
|
+
first = collection.offset_value + 1
|
685
|
+
last = collection.last_page? ? collection.total_count : collection.offset_value + collection.limit_value
|
686
|
+
|
687
|
+
num_pages = collection.num_pages
|
688
|
+
end
|
689
|
+
|
690
|
+
parameters = grid.get_state_as_parameter_value_pairs
|
691
|
+
|
692
|
+
if num_pages < 2 && collection.length == 0
|
693
|
+
'0'
|
694
|
+
else
|
695
|
+
parameters << ["#{grid.name}[pp]", collection_total_entries]
|
696
|
+
|
697
|
+
show_all_records_link = allow_showing_all_records && collection_total_entries > collection.length
|
698
|
+
|
699
|
+
if show_all_records_link && limit = Wice::ConfigurationProvider.value_for(:SHOW_ALL_ALLOWED_UP_TO, strict: false)
|
700
|
+
show_all_records_link = limit > collection_total_entries
|
701
|
+
end
|
702
|
+
|
703
|
+
"#{first}-#{last} / #{collection_total_entries} " +
|
704
|
+
if show_all_records_link
|
705
|
+
res, _js = show_all_link(collection_total_entries, parameters, grid.name)
|
706
|
+
res
|
707
|
+
else
|
708
|
+
''
|
709
|
+
end
|
710
|
+
end +
|
711
|
+
if grid.all_record_mode?
|
712
|
+
back_to_pagination_link(parameters, grid.name)
|
713
|
+
else
|
714
|
+
''
|
715
|
+
end
|
716
|
+
end
|
717
|
+
end
|
718
|
+
end
|