wice_grid_mongoid 0.5.6
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +8 -0
- data/CHANGELOG +409 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +1172 -0
- data/Rakefile +42 -0
- data/SAVED_QUERIES_HOWTO.rdoc +123 -0
- data/VERSION +1 -0
- data/generators/common_templates/icons/arrow_down.gif +0 -0
- data/generators/common_templates/icons/arrow_up.gif +0 -0
- data/generators/common_templates/icons/calendar_view_month.png +0 -0
- data/generators/common_templates/icons/delete.png +0 -0
- data/generators/common_templates/icons/expand.png +0 -0
- data/generators/common_templates/icons/page_white_excel.png +0 -0
- data/generators/common_templates/icons/page_white_find.png +0 -0
- data/generators/common_templates/icons/table.png +0 -0
- data/generators/common_templates/icons/table_refresh.png +0 -0
- data/generators/common_templates/icons/tick_all.png +0 -0
- data/generators/common_templates/icons/untick_all.png +0 -0
- data/generators/common_templates/initializers/wice_grid_config.rb +215 -0
- data/generators/common_templates/locales/wice_grid.yml +269 -0
- data/generators/common_templates/stylesheets/wice_grid.css +173 -0
- data/generators/wice_grid_assets_jquery/templates/USAGE +6 -0
- data/generators/wice_grid_assets_jquery/templates/javascripts/wice_grid_jquery.js +161 -0
- data/generators/wice_grid_assets_jquery/wice_grid_assets_jquery_generator.rb +35 -0
- data/generators/wice_grid_assets_prototype/USAGE +8 -0
- data/generators/wice_grid_assets_prototype/templates/javascripts/calendarview.js +1168 -0
- data/generators/wice_grid_assets_prototype/templates/javascripts/wice_grid_prototype.js +153 -0
- data/generators/wice_grid_assets_prototype/templates/stylesheets/calendarview.css +107 -0
- data/generators/wice_grid_assets_prototype/wice_grid_assets_prototype_generator.rb +37 -0
- data/init.rb +1 -0
- data/install.rb +1 -0
- data/lib/grid_output_buffer.rb +52 -0
- data/lib/grid_renderer.rb +531 -0
- data/lib/helpers/js_calendar_helpers.rb +188 -0
- data/lib/helpers/wice_grid_misc_view_helpers.rb +113 -0
- data/lib/helpers/wice_grid_serialized_queries_view_helpers.rb +82 -0
- data/lib/helpers/wice_grid_view_helpers.rb +781 -0
- data/lib/js_adaptors/jquery_adaptor.rb +145 -0
- data/lib/js_adaptors/js_adaptor.rb +12 -0
- data/lib/js_adaptors/prototype_adaptor.rb +168 -0
- data/lib/table_column_matrix.rb +51 -0
- data/lib/view_columns.rb +469 -0
- data/lib/views/create.rjs +13 -0
- data/lib/views/delete.rjs +12 -0
- data/lib/wice_grid.rb +809 -0
- data/lib/wice_grid_controller.rb +165 -0
- data/lib/wice_grid_core_ext.rb +179 -0
- data/lib/wice_grid_misc.rb +99 -0
- data/lib/wice_grid_serialized_queries_controller.rb +77 -0
- data/lib/wice_grid_serialized_query.rb +14 -0
- data/lib/wice_grid_spreadsheet.rb +33 -0
- data/tasks/wice_grid_tasks.rake +28 -0
- data/test/.gitignore +2 -0
- data/test/database.yml +21 -0
- data/test/schema.rb +33 -0
- data/test/test_helper.rb +89 -0
- data/test/views/projects_and_people_grid.html.erb +12 -0
- data/test/views/projects_and_people_grid_invalid.html.erb +12 -0
- data/test/views/simple_projects_grid.html.erb +9 -0
- data/test/wice_grid_core_ext_test.rb +183 -0
- data/test/wice_grid_functional_test.rb +68 -0
- data/test/wice_grid_misc_test.rb +41 -0
- data/test/wice_grid_test.rb +42 -0
- data/test/wice_grid_view_helper_test.rb +12 -0
- data/uninstall.rb +1 -0
- data/wice_grid_mongoid.gemspec +111 -0
- metadata +141 -0
@@ -0,0 +1,153 @@
|
|
1
|
+
function WiceGridProcessor(name, base_request_for_filter, base_link_for_show_all_records,
|
2
|
+
link_for_export, parameter_name_for_query_loading, parameter_name_for_focus, environment){
|
3
|
+
|
4
|
+
this.checkIfJsFrameworkIsLoaded = function(){
|
5
|
+
if (typeof(Prototype) == "undefined"){
|
6
|
+
alert("Prototype javascript library not loaded, WiceGrid cannot proceed!")
|
7
|
+
}
|
8
|
+
}
|
9
|
+
|
10
|
+
|
11
|
+
this.checkIfJsFrameworkIsLoaded();
|
12
|
+
this.name = name;
|
13
|
+
this.parameter_name_for_query_loading = parameter_name_for_query_loading;
|
14
|
+
this.parameter_name_for_focus = parameter_name_for_focus;
|
15
|
+
this.base_request_for_filter = base_request_for_filter;
|
16
|
+
this.base_link_for_show_all_records = base_link_for_show_all_records;
|
17
|
+
this.link_for_export = link_for_export;
|
18
|
+
this.filter_declarations = new Array();
|
19
|
+
this.environment = environment;
|
20
|
+
|
21
|
+
this.toString = function(){
|
22
|
+
return "<WiceGridProcessor instance for grid '" + this.name + "'>";
|
23
|
+
}
|
24
|
+
|
25
|
+
|
26
|
+
this.process = function(dom_id_to_focus){
|
27
|
+
window.location = this.build_url_with_params(dom_id_to_focus);
|
28
|
+
}
|
29
|
+
|
30
|
+
this.reload_page_for_given_grid_state = function(grid_state){
|
31
|
+
var request_path = this.grid_state_to_request(grid_state);
|
32
|
+
window.location = this.append_to_url(this.base_link_for_show_all_records, request_path);
|
33
|
+
}
|
34
|
+
|
35
|
+
this.load_query = function(query_id){
|
36
|
+
var request = this.append_to_url(this.build_url_with_params(),
|
37
|
+
(this.parameter_name_for_query_loading + encodeURIComponent(query_id)));
|
38
|
+
window.location = request;
|
39
|
+
}
|
40
|
+
|
41
|
+
this.save_query = function(query_name, base_path_to_query_controller, grid_state, input_ids){
|
42
|
+
if (input_ids instanceof Array) {
|
43
|
+
input_ids.each(function(dom_id){
|
44
|
+
grid_state.push(['extra[' + dom_id + ']', $F(dom_id)])
|
45
|
+
});
|
46
|
+
}
|
47
|
+
|
48
|
+
var request_path = this.grid_state_to_request(grid_state);
|
49
|
+
|
50
|
+
new Ajax.Request(base_path_to_query_controller, {
|
51
|
+
asynchronous:true,
|
52
|
+
evalScripts:true,
|
53
|
+
parameters: request_path + '&query_name=' + encodeURIComponent(query_name)
|
54
|
+
})
|
55
|
+
}
|
56
|
+
|
57
|
+
this.grid_state_to_request = function(grid_state){
|
58
|
+
return res = grid_state.collect(function(pair){
|
59
|
+
return encodeURIComponent(pair[0]) + '=' + encodeURIComponent(pair[1]);
|
60
|
+
}).join('&');
|
61
|
+
}
|
62
|
+
|
63
|
+
|
64
|
+
this.append_to_url = function(url, str){
|
65
|
+
var sep;
|
66
|
+
if (url.include('?')){
|
67
|
+
if (/[&\?]$/.exec(url)){
|
68
|
+
sep = '';
|
69
|
+
}else{
|
70
|
+
sep = '&';
|
71
|
+
}
|
72
|
+
}else{
|
73
|
+
sep = '?';
|
74
|
+
}
|
75
|
+
return url + sep + str;
|
76
|
+
}
|
77
|
+
|
78
|
+
|
79
|
+
this.build_url_with_params = function(dom_id_to_focus){
|
80
|
+
var results = new Array();
|
81
|
+
this.filter_declarations.each(function(filter_declaration){
|
82
|
+
param = this.read_values_and_form_query_string(
|
83
|
+
filter_declaration.filter_name, filter_declaration.detached,
|
84
|
+
filter_declaration.templates, filter_declaration.ids);
|
85
|
+
if (param && param != ''){
|
86
|
+
results.push(param);
|
87
|
+
}
|
88
|
+
}.bind(this));
|
89
|
+
var res = this.base_request_for_filter;
|
90
|
+
if ( results.length != 0){
|
91
|
+
all_filter_params = results.join('&');
|
92
|
+
res = this.append_to_url(res, all_filter_params);
|
93
|
+
}
|
94
|
+
if (dom_id_to_focus){
|
95
|
+
res = this.append_to_url(res, this.parameter_name_for_focus + dom_id_to_focus);
|
96
|
+
}
|
97
|
+
return res;
|
98
|
+
}
|
99
|
+
|
100
|
+
this.reset = function(){
|
101
|
+
window.location = this.base_request_for_filter;
|
102
|
+
}
|
103
|
+
|
104
|
+
this.export_to_csv = function(){
|
105
|
+
window.location = this.link_for_export;
|
106
|
+
}
|
107
|
+
|
108
|
+
|
109
|
+
this.register = function(func){
|
110
|
+
this.filter_declarations.push(func);
|
111
|
+
}
|
112
|
+
|
113
|
+
this.read_values_and_form_query_string = function(filter_name, detached, templates, ids){
|
114
|
+
var res = new Array();
|
115
|
+
for(i = 0; i < templates.length; i++){
|
116
|
+
if($(ids[i]) == null){
|
117
|
+
if (this.environment == "development"){
|
118
|
+
message = 'WiceGrid: Error reading state of filter "' + filter_name + '". No DOM element with id "' + ids[i] + '" found.'
|
119
|
+
if (detached){
|
120
|
+
message += 'You have declared "' + filter_name +
|
121
|
+
'" as a detached filter but have not output it anywhere in the template. Read documentation about detached filters.'
|
122
|
+
}
|
123
|
+
alert(message);
|
124
|
+
}
|
125
|
+
return '';
|
126
|
+
}
|
127
|
+
var val = $F(ids[i]);
|
128
|
+
if (val instanceof Array) {
|
129
|
+
for(j = 0; j < val.length; j++){
|
130
|
+
if (val[j] && val[j] != "")
|
131
|
+
res.push(templates[i] + encodeURIComponent(val[j]));
|
132
|
+
}
|
133
|
+
} else if (val && ! val.empty()){
|
134
|
+
res.push(templates[i] + encodeURIComponent(val));
|
135
|
+
}
|
136
|
+
}
|
137
|
+
return res.join('&');
|
138
|
+
}
|
139
|
+
|
140
|
+
};
|
141
|
+
|
142
|
+
function toggle_multi_select(select_id, link_obj, expand_label, collapse_label) {
|
143
|
+
var select = $(select_id);
|
144
|
+
if (select.multiple == true) {
|
145
|
+
select.multiple = false;
|
146
|
+
link_obj.title = expand_label;
|
147
|
+
} else {
|
148
|
+
select.multiple = true;
|
149
|
+
link_obj.title = collapse_label;
|
150
|
+
}
|
151
|
+
}
|
152
|
+
|
153
|
+
WiceGridProcessor._version = '0.4.3';
|
@@ -0,0 +1,107 @@
|
|
1
|
+
|
2
|
+
div.calendar
|
3
|
+
{
|
4
|
+
font-size: smaller;
|
5
|
+
color: #000;
|
6
|
+
z-index: 5;
|
7
|
+
}
|
8
|
+
|
9
|
+
div.calendar.popup
|
10
|
+
{
|
11
|
+
margin-left: -40px;
|
12
|
+
margin-top: -100px;
|
13
|
+
}
|
14
|
+
|
15
|
+
div.calendar table
|
16
|
+
{
|
17
|
+
background-color: #eee;
|
18
|
+
border: 1px solid #aaa;
|
19
|
+
border-collapse: collapse;
|
20
|
+
}
|
21
|
+
|
22
|
+
div.calendar thead {
|
23
|
+
background-color: white;
|
24
|
+
}
|
25
|
+
|
26
|
+
div.calendar td,
|
27
|
+
div.calendar th
|
28
|
+
{
|
29
|
+
padding: 3px;
|
30
|
+
text-align: center;
|
31
|
+
}
|
32
|
+
|
33
|
+
div.calendar td.title
|
34
|
+
{
|
35
|
+
font-weight: bold;
|
36
|
+
}
|
37
|
+
|
38
|
+
div.calendar th
|
39
|
+
{
|
40
|
+
background: #ddd;
|
41
|
+
border-bottom: 1px solid #ccc;
|
42
|
+
border-top: 1px solid #ccc;
|
43
|
+
font-weight: bold;
|
44
|
+
color: #555;
|
45
|
+
}
|
46
|
+
|
47
|
+
div.calendar tr.days td {
|
48
|
+
width: 2em;
|
49
|
+
color: #555;
|
50
|
+
text-align: center;
|
51
|
+
cursor: pointer;
|
52
|
+
}
|
53
|
+
|
54
|
+
div.calendar tr.days td:hover,
|
55
|
+
div.calendar td.cvbutton:hover
|
56
|
+
{
|
57
|
+
background-color: #34ABFA;
|
58
|
+
cursor: pointer;
|
59
|
+
}
|
60
|
+
|
61
|
+
|
62
|
+
div.calendar tr td.closeButton:hover
|
63
|
+
{
|
64
|
+
background-color: #34ABFA;
|
65
|
+
cursor: pointer;
|
66
|
+
}
|
67
|
+
|
68
|
+
|
69
|
+
div.calendar tr.days td:active
|
70
|
+
div.calendar td.cvbutton:active
|
71
|
+
{
|
72
|
+
background-color: #cde;
|
73
|
+
}
|
74
|
+
|
75
|
+
div.calendar tr.days td.selected
|
76
|
+
{
|
77
|
+
font-weight: bold;
|
78
|
+
background-color: #fff;
|
79
|
+
color: #000;
|
80
|
+
}
|
81
|
+
|
82
|
+
div.calendar tr.days td.today
|
83
|
+
{
|
84
|
+
font-weight: bold;
|
85
|
+
color: #D50000;
|
86
|
+
}
|
87
|
+
|
88
|
+
div.calendar tr.days td.otherDay
|
89
|
+
{
|
90
|
+
color: #bbb;
|
91
|
+
}
|
92
|
+
|
93
|
+
div.calendar .draggableHandler{
|
94
|
+
cursor: move;
|
95
|
+
}
|
96
|
+
|
97
|
+
/* styles for the date_picker Rails plugin */
|
98
|
+
span.date_picker a.date_label{
|
99
|
+
margin-left: 5px;
|
100
|
+
margin-right: 5px;
|
101
|
+
text-decoration: none;
|
102
|
+
}
|
103
|
+
span.date_picker a.date_label:hover{text-decoration: line-through;}
|
104
|
+
|
105
|
+
span.date_picker span.trigger:hover{
|
106
|
+
cursor: pointer;
|
107
|
+
}
|
@@ -0,0 +1,37 @@
|
|
1
|
+
class WiceGridAssetsPrototypeGenerator < Rails::Generator::Base
|
2
|
+
def active_js_framework
|
3
|
+
'prototype'
|
4
|
+
end
|
5
|
+
def inactive_js_framework
|
6
|
+
'jquery'
|
7
|
+
end
|
8
|
+
|
9
|
+
def manifest
|
10
|
+
record do |m|
|
11
|
+
# wice_grid config
|
12
|
+
m.directory "config/initializers"
|
13
|
+
m.template "../../common_templates/initializers/wice_grid_config.rb", "config/initializers/wice_grid_config.rb"
|
14
|
+
|
15
|
+
# wice_grid locales
|
16
|
+
m.directory "config/locales"
|
17
|
+
m.file "../../common_templates/locales/wice_grid.yml", "config/locales/wice_grid.yml"
|
18
|
+
|
19
|
+
# wice_grid js & css
|
20
|
+
m.file "javascripts/wice_grid_prototype.js", "public/javascripts/wice_grid.js"
|
21
|
+
m.file "../../common_templates/stylesheets/wice_grid.css", "public/stylesheets/wice_grid.css"
|
22
|
+
|
23
|
+
# calendarview js & css
|
24
|
+
m.file "javascripts/calendarview.js", "public/javascripts/calendarview.js"
|
25
|
+
m.file "stylesheets/calendarview.css", "public/stylesheets/calendarview.css"
|
26
|
+
|
27
|
+
# images
|
28
|
+
m.directory "public/images/icons/grid"
|
29
|
+
|
30
|
+
%w(arrow_down.gif calendar_view_month.png expand.png page_white_find.png table_refresh.png
|
31
|
+
arrow_up.gif delete.png page_white_excel.png table.png tick_all.png untick_all.png ).each do |f|
|
32
|
+
m.file "../../common_templates/icons/#{f}", "public/images/icons/grid/#{f}"
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'wice_grid.rb'
|
data/install.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# Install hook code here
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
module Wice
|
3
|
+
|
4
|
+
class GridOutputBuffer < String #:nodoc:
|
5
|
+
|
6
|
+
attr_reader :stubborn_output_mode
|
7
|
+
attr_accessor :return_empty_strings_for_nonexistent_filters
|
8
|
+
|
9
|
+
def stubborn_output_mode=(m)
|
10
|
+
RAILS_DEFAULT_LOGGER.debug("=== WiceGrid: detached filters are requested, postponing output till the second call of the view helper") if m
|
11
|
+
@stubborn_output_mode = m
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(*attrs)
|
15
|
+
super(*attrs)
|
16
|
+
@filters = HashWithIndifferentAccess.new
|
17
|
+
@first_output = false
|
18
|
+
@stubborn_output_mode = false
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
if @first_output || ! @stubborn_output_mode
|
23
|
+
super.html_safe_if_necessary
|
24
|
+
else
|
25
|
+
@first_output = true
|
26
|
+
''
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def add_filter(detach_with_id, filter_code)
|
31
|
+
raise WiceGridException.new("Detached ID #{detach_with_id} is already used!") if @filters.has_key? detach_with_id
|
32
|
+
@filters[detach_with_id] = filter_code
|
33
|
+
end
|
34
|
+
|
35
|
+
def filter_for detach_with_id
|
36
|
+
unless @filters.has_key? detach_with_id
|
37
|
+
if @return_empty_strings_for_nonexistent_filters
|
38
|
+
return ''
|
39
|
+
else
|
40
|
+
raise WiceGridException.new("No filter with Detached ID '#{detach_with_id}'!")
|
41
|
+
end
|
42
|
+
end
|
43
|
+
raise WiceGridException.new("Filter with Detached ID '#{detach_with_id}' has already been requested once! There cannot be two instances of the same filter on one page") if @filters[detach_with_id] == false
|
44
|
+
res = @filters[detach_with_id]
|
45
|
+
@filters[detach_with_id] = false
|
46
|
+
return res
|
47
|
+
end
|
48
|
+
|
49
|
+
alias_method :[], :filter_for
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,531 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
module Wice
|
3
|
+
class GridRenderer
|
4
|
+
|
5
|
+
include ActionView::Helpers::TagHelper
|
6
|
+
include ActionView::Helpers::CaptureHelper
|
7
|
+
include ActionView::Helpers::TextHelper
|
8
|
+
include ActionView::Helpers::AssetTagHelper
|
9
|
+
include ActionView::Helpers::JavaScriptHelper
|
10
|
+
include ::WillPaginate::ViewHelpers
|
11
|
+
|
12
|
+
attr_reader :page_parameter_name
|
13
|
+
attr_reader :after_row_handler
|
14
|
+
attr_reader :before_row_handler
|
15
|
+
attr_reader :blank_slate_handler
|
16
|
+
attr_reader :grid
|
17
|
+
attr_accessor :erb_mode
|
18
|
+
|
19
|
+
attr_accessor :reset_button_present, :submit_button_present, :show_hide_button_present, :csv_export_icon_present
|
20
|
+
|
21
|
+
@@order_parameter_name = "order"
|
22
|
+
@@order_direction_parameter_name = "order_direction"
|
23
|
+
@@page_parameter_name = "page"
|
24
|
+
|
25
|
+
def initialize(grid, view) #:nodoc:
|
26
|
+
@grid = grid
|
27
|
+
@grid.renderer = self
|
28
|
+
@columns = []
|
29
|
+
@columns_table = {}
|
30
|
+
@action_column_present = false
|
31
|
+
@view = view
|
32
|
+
end
|
33
|
+
|
34
|
+
def add_column(vc) #:nodoc:
|
35
|
+
@columns_table[vc.fully_qualified_attribute_name] = vc if vc.attribute_name
|
36
|
+
@columns << vc
|
37
|
+
end
|
38
|
+
|
39
|
+
def [](k) #:nodoc:
|
40
|
+
@columns_table[k]
|
41
|
+
end
|
42
|
+
|
43
|
+
def number_of_columns(filter = nil) #:nodoc:
|
44
|
+
filter_columns(filter).size
|
45
|
+
end
|
46
|
+
|
47
|
+
def each_column_label(filter = nil) #:nodoc:
|
48
|
+
filter_columns(filter).each{|col| yield col.column_name}
|
49
|
+
end
|
50
|
+
|
51
|
+
def column_labels(filter = nil) #:nodoc:
|
52
|
+
filter_columns(filter).collect(&:column_name)
|
53
|
+
end
|
54
|
+
|
55
|
+
def each_column(filter = nil) #:nodoc:
|
56
|
+
filter_columns(filter).each{|col| yield col}
|
57
|
+
end
|
58
|
+
|
59
|
+
def contains_a_text_input? #:nodoc:
|
60
|
+
filter_columns(:in_html).detect(&:contains_a_text_input)
|
61
|
+
end
|
62
|
+
|
63
|
+
def each_column_aware_of_one_last_one(filter = nil) #:nodoc:
|
64
|
+
cols = filter_columns(filter)
|
65
|
+
cols[0..-2].each{|col| yield col, false}
|
66
|
+
yield cols.last, true
|
67
|
+
end
|
68
|
+
|
69
|
+
def last_column_for_html #:nodoc:
|
70
|
+
filter_columns(:in_html).last
|
71
|
+
end
|
72
|
+
|
73
|
+
def select_for(filter) #:nodoc:
|
74
|
+
filter_columns(filter).select{|col| yield col}
|
75
|
+
end
|
76
|
+
|
77
|
+
def find_one_for(filter) #:nodoc:
|
78
|
+
filter_columns(filter).find{|col| yield col}
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
def each_column_with_attribute #:nodoc:
|
83
|
+
@columns.select(&:attribute_name).each{|col| yield col}
|
84
|
+
end
|
85
|
+
|
86
|
+
alias_method :each, :each_column
|
87
|
+
include Enumerable
|
88
|
+
|
89
|
+
def csv_export_icon #:nodoc:
|
90
|
+
tooltip = WiceGridNlMessageProvider.get_message(:CSV_EXPORT_TOOLTIP)
|
91
|
+
@csv_export_icon_present = true
|
92
|
+
image_tag(Defaults::CSV_EXPORT_ICON,
|
93
|
+
:title => tooltip,
|
94
|
+
:class => 'clickable export_to_csv_button',
|
95
|
+
:alt => tooltip
|
96
|
+
)
|
97
|
+
end
|
98
|
+
|
99
|
+
def pagination_panel(no_rightmost_column, hide_csv_button) #:nodoc:
|
100
|
+
panel = yield
|
101
|
+
|
102
|
+
render_csv_button = @grid.export_to_csv_enabled && ! hide_csv_button
|
103
|
+
|
104
|
+
number_of_columns = self.number_of_columns(:in_html)
|
105
|
+
number_of_columns -= 1 if no_rightmost_column
|
106
|
+
|
107
|
+
if panel.nil?
|
108
|
+
if render_csv_button
|
109
|
+
"<tr><td colspan=\"#{number_of_columns}\"></td><td>#{csv_export_icon}</td></tr>"
|
110
|
+
else
|
111
|
+
''
|
112
|
+
end
|
113
|
+
else
|
114
|
+
if render_csv_button
|
115
|
+
"<tr><td colspan=\"#{number_of_columns}\">#{panel}</td><td>#{csv_export_icon}</td></tr>"
|
116
|
+
else
|
117
|
+
"<tr><td colspan=\"#{number_of_columns + 1}\">#{panel}</td></tr>"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def element_to_focus #:nodoc:
|
123
|
+
grid.status['foc']
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
# Adds a column with checkboxes for each record. Useful for actions with multiple records, for example, deleting
|
128
|
+
# selected records. Please note that +action_column+ only creates the checkboxes and the 'Select All' and
|
129
|
+
# 'Deselect All' buttons, and the form itelf as well as processing the parameters should be taken care of
|
130
|
+
# by the application code.
|
131
|
+
#
|
132
|
+
# * <tt>:param_name</tt> - The name of the HTTP parameter.
|
133
|
+
# The complete HTTP parameter is <tt>"#{grid_name}[#{param_name}][]"</tt>.
|
134
|
+
# The default param_name is 'selected'.
|
135
|
+
# * <tt>:td_html_attrs</tt> - a hash of HTML attributes to be included into the <tt>td</tt> tag.
|
136
|
+
# * <tt>:select_all_buttons</tt> - show/hide buttons 'Select All' and 'Deselect All' in the column header.
|
137
|
+
# The default is +true+.
|
138
|
+
# * <tt>:object_property</tt> - a method used to obtain the value for the HTTP parameter. The default is +id+.
|
139
|
+
def action_column(opts = {})
|
140
|
+
|
141
|
+
if @action_column_present
|
142
|
+
raise Wice::WiceGridException.new('There can be only one action column in a WiceGrid')
|
143
|
+
end
|
144
|
+
|
145
|
+
options = {
|
146
|
+
:param_name => :selected,
|
147
|
+
:td_html_attrs => {},
|
148
|
+
:select_all_buttons => true,
|
149
|
+
:object_property => :id
|
150
|
+
}
|
151
|
+
|
152
|
+
opts.assert_valid_keys(options.keys)
|
153
|
+
options.merge!(opts)
|
154
|
+
@action_column_present = true
|
155
|
+
@columns << ActionViewColumn.new(@grid, options[:td_html_attrs], options[:param_name],
|
156
|
+
options[:select_all_buttons], options[:object_property], @view)
|
157
|
+
end
|
158
|
+
|
159
|
+
# Defines everything related to a column in a grid - column name, filtering, rendering cells, etc.
|
160
|
+
#
|
161
|
+
# +column+ is only used inside the block of the +grid+ method. See documentation for the +grid+ method for more details.
|
162
|
+
#
|
163
|
+
# The only parameter is a hash of options. None of them is optional. If no options are supplied, the result will be a
|
164
|
+
# column with no name, no filtering and no sorting.
|
165
|
+
#
|
166
|
+
# * <tt>:column_name</tt> - Name of the column.
|
167
|
+
# * <tt>:td_html_attrs</tt> - a hash of HTML attributes to be included into the <tt>td</tt> tag.
|
168
|
+
# * <tt>:class</tt> - a shortcut for <tt>:td_html_attrs => {:class => 'css_class'}</tt>
|
169
|
+
# * <tt>:attribute_name</tt> - name of a database column (which normally correspond to a model attribute with the
|
170
|
+
# same name). By default the field is assumed to belong to the default table (see documentation for the
|
171
|
+
# +initialize_grid+ method). Parameter <tt>:model_class</tt> allows to specify another table. Presence of
|
172
|
+
# this parameter
|
173
|
+
# * adds sorting capabilities by this field
|
174
|
+
# * automatically creates a filter based on the type of the field unless parameter <tt>:no_filter</tt> is set to true.
|
175
|
+
# The following filters exist for the following types:
|
176
|
+
# * <tt>string</tt> - a text field
|
177
|
+
# * <tt>integer</tt> and <tt>float</tt> - two text fields to specify the range. Both limits or only one
|
178
|
+
# can be specified
|
179
|
+
# * <tt>boolean</tt> - a dropdown list with 'yes', 'no', or '-'. These labels can be changed in
|
180
|
+
# <tt>lib/wice_grid_config.rb</tt>.
|
181
|
+
# * <tt>date</tt> - two sets of standard date dropdown lists so specify the time range.
|
182
|
+
# * <tt>datetime</tt> - two sets of standard datetime dropdown lists so specify the time range. This filter
|
183
|
+
# is far from being user-friendly due to the number of dropdown lists.
|
184
|
+
# * <tt>:no_filter</tt> - Turns off filters even if <tt>:attribute_name</tt> is specified.
|
185
|
+
# This is needed if sorting is required while filters are not.
|
186
|
+
# * <tt>:allow_ordering</tt> - Enable/disable ordering links in the column titles. The default is +true+
|
187
|
+
# (i.e. if <tt>:attribute_name</tt> is defined, ordering is enabled)
|
188
|
+
# * <tt>:model_class</tt> - Name of the model class to which <tt>:attribute_name</tt> belongs to if this is not the main table.
|
189
|
+
# * <tt>:table_alias</tt> - In case there are two joined assocations both referring to the same table, ActiveRecord
|
190
|
+
# constructs a query where the second join provides an alias for the joined table. Setting <tt>:table_alias</tt>
|
191
|
+
# to this alias will enable WiceGrid to order and filter by columns belonging to different associatiations but
|
192
|
+
# originating from the same table without confusion. See README for an example.
|
193
|
+
# * <tt>:custom_filter</tt> - Allows to construct a custom dropdown filter. Depending on the value of
|
194
|
+
# <tt>:custom_filter</tt> different modes are available:
|
195
|
+
# * array of strings and/or numbers - this is a direct definition of possible values of the dropdown.
|
196
|
+
# Every item will be used both as the value of the select option and as its label.
|
197
|
+
# * Array of two-element arrays - Every first item of the two-element array is used for the label of the select option
|
198
|
+
# while the second element is the value of the select option
|
199
|
+
# * Hash - The keys of the hash become the labels of the generated dropdown list,
|
200
|
+
# while the values will be values of options of the dropdown list:
|
201
|
+
# * <tt>:auto</tt> - a powerful option which populates the dropdown list with all unique values of the field specified by
|
202
|
+
# <tt>:attribute_name</tt> and <tt>:model_class</tt>.
|
203
|
+
# <tt>:attribute_name</tt> throughout all pages. In other words, this runs an SQL query without +offset+ and +limit+
|
204
|
+
# clauses and with <tt>distinct(table.field)</tt> instead of <tt>distinct(*)</tt>
|
205
|
+
# * any other symbol name (method name) - The dropdown list is populated by all unique value returned by the
|
206
|
+
# method with this name sent to <em>all</em> ActiveRecord objects throughout all pages. The main difference
|
207
|
+
# from <tt>:auto</tt> is that this method does not have to be a field in the result set, it is just some
|
208
|
+
# value computed in the method after the database call and ActiveRecord instantiation.
|
209
|
+
#
|
210
|
+
# But here lies the major drawback - this mode requires additional query without +offset+ and +limit+
|
211
|
+
# clauses to instantiate _all_ ActiveRecord objects, and performance-wise it brings all the advantages
|
212
|
+
# of pagination to nothing. Thus, memory- and performance-wise this can be really bad for some queries
|
213
|
+
# and tables and should be used with care.
|
214
|
+
#
|
215
|
+
# If the method returns a atomic value like a string or an integer, it is used for both the value and the
|
216
|
+
# label of the select option element. However, if the retuned value is a two element array, the first element
|
217
|
+
# is used for the option label and the second - for the value.
|
218
|
+
# Read more in README, section 'Custom dropdown filters'
|
219
|
+
# * An array of symbols (method names) - similar to the mode with a single symbol name. The first method name
|
220
|
+
# is sent to the ActiveRecord object if it responds to this method, the second method name is sent to the
|
221
|
+
# returned value unless it is +nil+, and so on. In other words, a single symbol mode is a
|
222
|
+
# case of an array of symbols where the array contains just one element. Thus the warning about the single method name
|
223
|
+
# mode applies here as well.
|
224
|
+
#
|
225
|
+
# If the last method returns a atomic value like a string or an integer, it is used for both the value and the
|
226
|
+
# label of the select option element.
|
227
|
+
# However, if the retuned value is a two element array, the first element is used for the option label and the
|
228
|
+
# second - for the value.
|
229
|
+
# Read more in README, section 'Custom dropdown filters'
|
230
|
+
# * <tt>:boolean_filter_true_label</tt> - overrides the default value for <tt>BOOLEAN_FILTER_TRUE_LABEL</tt>
|
231
|
+
# ('+yes+') in the config.
|
232
|
+
# Only has effect in a column with a boolean filter.
|
233
|
+
# * <tt>:boolean_filter_false_label</tt> - overrides the default value for <tt>BOOLEAN_FILTER_FALSE_LABEL</tt>
|
234
|
+
# ('+no+') in the config.
|
235
|
+
# Only has effect in a column with a boolean filter.
|
236
|
+
# * <tt>:allow_multiple_selection</tt> - enables or disables switching between single and multiple selection modes for
|
237
|
+
# custom dropdown boxes. +true+ by default (see +ALLOW_MULTIPLE_SELECTION+ in the configuration file).
|
238
|
+
# * <tt>:filter_all_label</tt> - overrides the default value for <tt>BOOLEAN_FILTER_FALSE_LABEL</tt> ('<tt>--</tt>')
|
239
|
+
# in the config. Has effect in a column with a boolean filter _or_ a custom filter.
|
240
|
+
# * <tt>:detach_with_id</tt> - allows to detach the filter and render it after or before the grid with the
|
241
|
+
# +grid_filter+ helper. The value is an arbitrary unique identifier
|
242
|
+
# of the filter. Read section 'Detached Filters' in README for details.
|
243
|
+
# Has effect in a column with a boolean filter _or_ a custom filter.
|
244
|
+
# * <tt>:in_csv</tt> - When CSV export is enabled, all columns are included into the export. Setting <tt>:in_csv</tt>
|
245
|
+
# to false will prohibit the column from inclusion into the export.
|
246
|
+
# * <tt>:in_html</tt> - When CSV export is enabled and it is needed to use a column for CSV export only and ignore it
|
247
|
+
# in HTML, set this parameter to false.
|
248
|
+
# * <tt>:helper_style</tt> - Changes the flavor of Date and DateTime filters. The values are:
|
249
|
+
# * <tt>:standard</tt> - the default Rails Date/DateTime helper
|
250
|
+
# * <tt>:calendar</tt> - a Javascript popup calendar control
|
251
|
+
# * <tt>:negation_in_filter</tt> - turn on/off the negation checkbox in string filters
|
252
|
+
# * <tt>:auto_reload</tt> - a boolean value specifying if a change in a filter triggers reloading of the grid. Works with all
|
253
|
+
# filter types including the JS calendar, the only exception is the standard Rails date/datetime filters.
|
254
|
+
# The default is false. (see +AUTO_RELOAD+ in the configuration file).
|
255
|
+
#
|
256
|
+
# The block parameter is an ActiveRecord instance. This block is called for every ActiveRecord shown, and the return
|
257
|
+
# value of the block is a string which becomes the contents of one table cell, or an array of two elements where
|
258
|
+
# the first element is the cell contents and the second is a hash of HTML attributes to be added for the <tt><td></tt>
|
259
|
+
# tag of the current cell.
|
260
|
+
#
|
261
|
+
# In case of an array output, please note that if you need to define HTML attributes for all <tt><td></tt>'s in a
|
262
|
+
# column, use +td_html_attrs+. Also note that if the method returns a hash with a <tt>:class</tt> or <tt>'class'</tt>
|
263
|
+
# element, it will not overwrite the class defined in +td_html_attrs+, or classes added by the grid itself
|
264
|
+
# (+active_filter+ and +sorted+), instead they will be all concatenated:
|
265
|
+
# <tt><td class="sorted user_class_for_columns user_class_for_this_specific_cell"></tt>
|
266
|
+
#
|
267
|
+
# It is up to the developer to make sure that what in rendered in column cells
|
268
|
+
# corresponds to sorting and filtering specified by parameters <tt>:attribute_name</tt> and <tt>:model_class</tt>.
|
269
|
+
|
270
|
+
def column(opts = {}, &block)
|
271
|
+
options = {
|
272
|
+
:allow_multiple_selection => Defaults::ALLOW_MULTIPLE_SELECTION,
|
273
|
+
:allow_ordering => true,
|
274
|
+
:attribute_name => nil,
|
275
|
+
:auto_reload => Defaults::AUTO_RELOAD,
|
276
|
+
:boolean_filter_false_label => WiceGridNlMessageProvider.get_message(:BOOLEAN_FILTER_FALSE_LABEL),
|
277
|
+
:boolean_filter_true_label => WiceGridNlMessageProvider.get_message(:BOOLEAN_FILTER_TRUE_LABEL),
|
278
|
+
:class => nil,
|
279
|
+
:column_name => '',
|
280
|
+
:custom_filter => nil,
|
281
|
+
:custom_order => nil,
|
282
|
+
:detach_with_id => nil,
|
283
|
+
:filter_all_label => Defaults::CUSTOM_FILTER_ALL_LABEL,
|
284
|
+
:helper_style => Defaults::HELPER_STYLE,
|
285
|
+
:in_csv => true,
|
286
|
+
:in_html => true,
|
287
|
+
:model_class => nil,
|
288
|
+
:negation_in_filter => Defaults::NEGATION_IN_STRING_FILTERS,
|
289
|
+
:no_filter => false,
|
290
|
+
:table_alias => nil,
|
291
|
+
:td_html_attrs => {}
|
292
|
+
}
|
293
|
+
|
294
|
+
opts.assert_valid_keys(options.keys)
|
295
|
+
options.merge!(opts)
|
296
|
+
|
297
|
+
unless options[:model_class].nil?
|
298
|
+
options[:model_class] = options[:model_class].constantize if options[:model_class].is_a? String
|
299
|
+
raise WiceGridArgumentError.new("Option :model_class can be either a class or a string instance") unless options[:model_class].is_a? Class
|
300
|
+
end
|
301
|
+
|
302
|
+
if options[:attribute_name].nil? && options[:model_class]
|
303
|
+
raise WiceGridArgumentError.new("Option :model_class is only used together with :attribute_name")
|
304
|
+
end
|
305
|
+
|
306
|
+
if options[:attribute_name] && options[:attribute_name].index('.')
|
307
|
+
raise WiceGridArgumentError.new("Invalid attribute name #{options[:attribute_name]}. An attribute name must not contain a table name!")
|
308
|
+
end
|
309
|
+
|
310
|
+
if options[:class]
|
311
|
+
options[:td_html_attrs].add_or_append_class_value!(options[:class])
|
312
|
+
options.delete(:class)
|
313
|
+
end
|
314
|
+
|
315
|
+
if block.nil?
|
316
|
+
if ! options[:attribute_name].blank?
|
317
|
+
block = lambda{|obj| obj.send(options[:attribute_name])}
|
318
|
+
else
|
319
|
+
raise WiceGridArgumentError.new(
|
320
|
+
"Missing column block without attribute_name defined. You can only omit the block if attribute_name is present.")
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
klass = ViewColumn
|
325
|
+
if options[:attribute_name] &&
|
326
|
+
col_type_and_table_name = @grid.declare_column(options[:attribute_name], options[:model_class],
|
327
|
+
options[:custom_filter], options[:table_alias])
|
328
|
+
|
329
|
+
db_column, table_name, main_table = col_type_and_table_name
|
330
|
+
col_type = db_column.type
|
331
|
+
|
332
|
+
if options[:custom_filter]
|
333
|
+
|
334
|
+
custom_filter = if options[:custom_filter] == :auto
|
335
|
+
lambda{ @grid.distinct_values_for_column(db_column) } # Thank God Ruby has higher order functions!!!
|
336
|
+
|
337
|
+
elsif options[:custom_filter].class == Symbol
|
338
|
+
lambda{ @grid.distinct_values_for_column_in_resultset([options[:custom_filter]])}
|
339
|
+
|
340
|
+
elsif options[:custom_filter].class == Hash
|
341
|
+
options[:custom_filter].keys
|
342
|
+
|
343
|
+
options[:custom_filter].to_a
|
344
|
+
|
345
|
+
elsif options[:custom_filter].class == Array
|
346
|
+
if options[:custom_filter].empty?
|
347
|
+
[]
|
348
|
+
elsif options[:custom_filter].all_items_are_of_class(Symbol)
|
349
|
+
lambda{ @grid.distinct_values_for_column_in_resultset(options[:custom_filter]) }
|
350
|
+
|
351
|
+
elsif options[:custom_filter].all_items_are_of_class(String) || options[:custom_filter].all_items_are_of_class(Numeric)
|
352
|
+
options[:custom_filter].map{|i| [i,i]}
|
353
|
+
|
354
|
+
elsif options[:custom_filter].all_items_are_of_class(Array)
|
355
|
+
options[:custom_filter]
|
356
|
+
else
|
357
|
+
raise WiceGridArgumentError.new(
|
358
|
+
':custom_filter can equal :auto, an array of string and/or numbers (direct values for the dropdown), ' +
|
359
|
+
'a homogeneous array of symbols (a sequence of methods to send to AR objects in the result set to ' +
|
360
|
+
'retrieve unique values for the dropdown), a Symbol (a shortcut for a one member array of symbols), ' +
|
361
|
+
'a hash where keys are labels and values are values for the dropdown option, or an array of two-item arrays, ' +
|
362
|
+
'each of which contains the label (first element) and the value (second element) for a dropdown option'
|
363
|
+
)
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
klass = ViewColumnCustomDropdown
|
368
|
+
else
|
369
|
+
klass = ViewColumn.handled_type[col_type] || ViewColumn
|
370
|
+
end # custom_filter
|
371
|
+
end # attribute_name
|
372
|
+
|
373
|
+
vc = klass.new(block, options, @grid, table_name, main_table, custom_filter, @view)
|
374
|
+
|
375
|
+
vc.negation = options[:negation_in_filter] if vc.respond_to? :negation=
|
376
|
+
|
377
|
+
vc.filter_all_label = options[:filter_all_label] if vc.kind_of?(ViewColumnCustomDropdown)
|
378
|
+
if vc.kind_of?(ViewColumnBoolean)
|
379
|
+
vc.boolean_filter_true_label = options[:boolean_filter_true_label]
|
380
|
+
vc.boolean_filter_false_label = options[:boolean_filter_false_label]
|
381
|
+
end
|
382
|
+
add_column(vc)
|
383
|
+
end
|
384
|
+
|
385
|
+
# Optional method inside the +grid+ block, to which every ActiveRecord instance is injected, just like +column+.
|
386
|
+
# Unlike +column+, it returns a hash which will be used as HTML attributes for the row with the given ActiveRecord instance.
|
387
|
+
#
|
388
|
+
# Note that if the method returns a hash with a <tt>:class</tt> or <tt>'class'</tt> element, it will not overwrite
|
389
|
+
# classes +even+ and +odd+, instead they will be concatenated: <tt><tr class="even highlighted_row_class_name"></tt>
|
390
|
+
def row_attributes(&block)
|
391
|
+
@row_attributes_handler = block
|
392
|
+
end
|
393
|
+
|
394
|
+
# Can be used to add HTML code (another row, for example) right after each grid row.
|
395
|
+
# Nothing is added if the block return +false+ or +nil+.
|
396
|
+
def after_row(&block)
|
397
|
+
@after_row_handler = block
|
398
|
+
end
|
399
|
+
|
400
|
+
# Can be used to add HTML code (another row, for example) right before each grid row.
|
401
|
+
# Nothing is added if the block return +false+ or +nil+.
|
402
|
+
def before_row(&block)
|
403
|
+
@before_row_handler = block
|
404
|
+
end
|
405
|
+
|
406
|
+
# The output of the block submitted to +blank_slate+ is rendered instead of the whole grid if no filters are active
|
407
|
+
# and there are no records to render.
|
408
|
+
# In addition to the block style two other variants are accepted:
|
409
|
+
# * <tt>g.blank_slate "some text to be rendered"</tt>
|
410
|
+
# * <tt>g.blank_slate :partial => "partial_name"</tt>
|
411
|
+
def blank_slate(opts = nil, &block)
|
412
|
+
if (opts.is_a?(Hash) && opts.has_key?(:partial) && block.nil?) || (opts.is_a?(String) && block.nil?)
|
413
|
+
@blank_slate_handler = opts
|
414
|
+
elsif opts.nil? && block
|
415
|
+
@blank_slate_handler = block
|
416
|
+
else
|
417
|
+
raise WiceGridArgumentError.new("blank_slate accepts only a string, a block, or :template => 'path_to_template' ")
|
418
|
+
end
|
419
|
+
end
|
420
|
+
|
421
|
+
|
422
|
+
def get_row_attributes(ar_object) #:nodoc:
|
423
|
+
if @row_attributes_handler
|
424
|
+
row_attributes = @row_attributes_handler.call(ar_object)
|
425
|
+
row_attributes = {} if row_attributes.blank?
|
426
|
+
unless row_attributes.is_a?(Hash)
|
427
|
+
raise WiceGridArgumentError.new("row_attributes block must return a hash containing HTML attributes. The returned value is #{row_attributes.inspect}")
|
428
|
+
end
|
429
|
+
row_attributes
|
430
|
+
else
|
431
|
+
{}
|
432
|
+
end
|
433
|
+
end
|
434
|
+
|
435
|
+
|
436
|
+
def no_filter_needed? #:nodoc:
|
437
|
+
not @columns.inject(false){|a,b| a || b.filter_shown? }
|
438
|
+
end
|
439
|
+
|
440
|
+
def no_filter_needed_in_main_table? #:nodoc:
|
441
|
+
not @columns.inject(false){|a,b| a || b.filter_shown_in_main_table? }
|
442
|
+
end
|
443
|
+
|
444
|
+
def base_link_for_filter(controller, extra_parameters = {}) #:nodoc:
|
445
|
+
new_params = controller.params.deep_clone_yl
|
446
|
+
new_params.merge!(extra_parameters)
|
447
|
+
|
448
|
+
if new_params[@grid.name]
|
449
|
+
new_params[@grid.name].delete(:page) # we reset paging here
|
450
|
+
new_params[@grid.name].delete(:f) # no filter for the base url
|
451
|
+
new_params[@grid.name].delete(:foc) # nullify the focus
|
452
|
+
new_params[@grid.name].delete(:q) # and no request for the saved query
|
453
|
+
end
|
454
|
+
|
455
|
+
new_params[:only_path] = false
|
456
|
+
base_link_with_pp_info = controller.url_for(new_params).gsub(/\?+$/,'')
|
457
|
+
|
458
|
+
if new_params[@grid.name]
|
459
|
+
new_params[@grid.name].delete(:pp) # and reset back to pagination if show all mode is on
|
460
|
+
end
|
461
|
+
[base_link_with_pp_info, controller.url_for(new_params).gsub(/\?+$/,'')]
|
462
|
+
end
|
463
|
+
|
464
|
+
|
465
|
+
|
466
|
+
def link_for_export(controller, format, extra_parameters = {}) #:nodoc:
|
467
|
+
new_params = controller.params.deep_clone_yl
|
468
|
+
new_params.merge!(extra_parameters)
|
469
|
+
|
470
|
+
new_params[@grid.name] = {} unless new_params[@grid.name]
|
471
|
+
new_params[@grid.name][:export] = format
|
472
|
+
|
473
|
+
new_params[:only_path] = false
|
474
|
+
controller.url_for(new_params)
|
475
|
+
end
|
476
|
+
|
477
|
+
|
478
|
+
def column_link(column, direction, params, extra_parameters = {}) #:nodoc:
|
479
|
+
|
480
|
+
column_attribute_name = if column.attribute_name.index('.') or column.main_table
|
481
|
+
column.attribute_name
|
482
|
+
else
|
483
|
+
column.table_alias_or_table_name + '.' + column.attribute_name
|
484
|
+
end
|
485
|
+
|
486
|
+
query_params = {@grid.name => {
|
487
|
+
@@order_parameter_name => column_attribute_name,
|
488
|
+
@@order_direction_parameter_name => direction
|
489
|
+
}}
|
490
|
+
|
491
|
+
cleaned_params = params.deep_clone_yl
|
492
|
+
cleaned_params.merge!(extra_parameters)
|
493
|
+
|
494
|
+
cleaned_params.delete(:controller)
|
495
|
+
cleaned_params.delete(:action)
|
496
|
+
|
497
|
+
|
498
|
+
query_params = cleaned_params.rec_merge(query_params)
|
499
|
+
|
500
|
+
'?' + query_params.to_query
|
501
|
+
end
|
502
|
+
|
503
|
+
def contains_auto_reloading_inputs #:nodoc:
|
504
|
+
contains_auto_reloading_elements(:has_auto_reloading_input?)
|
505
|
+
end
|
506
|
+
|
507
|
+
def contains_auto_reloading_inputs_with_negation_checkboxes #:nodoc:
|
508
|
+
contains_auto_reloading_elements(:auto_reloading_input_with_negation_checkbox?)
|
509
|
+
end
|
510
|
+
|
511
|
+
def contains_auto_reloading_selects #:nodoc:
|
512
|
+
contains_auto_reloading_elements(:has_auto_reloading_select?)
|
513
|
+
end
|
514
|
+
|
515
|
+
def contains_auto_reloading_calendars #:nodoc:
|
516
|
+
contains_auto_reloading_elements(:has_auto_reloading_calendar?)
|
517
|
+
end
|
518
|
+
|
519
|
+
protected
|
520
|
+
|
521
|
+
def contains_auto_reloading_elements(what) #:nodoc:
|
522
|
+
filter_columns(:in_html).detect{|column| column.filter_shown? && column.send(what)}
|
523
|
+
end
|
524
|
+
|
525
|
+
|
526
|
+
def filter_columns(method_name = nil) #:nodoc:
|
527
|
+
method_name ? @columns.select(&method_name) : @columns
|
528
|
+
end
|
529
|
+
|
530
|
+
end
|
531
|
+
end
|