wice_grid 3.0.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. data/.gitignore +1 -0
  2. data/CHANGELOG +412 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +1179 -0
  5. data/Rakefile +42 -0
  6. data/SAVED_QUERIES_HOWTO.rdoc +123 -0
  7. data/VERSION +1 -0
  8. data/lib/generators/wice_grid/templates/calendarview.css +107 -0
  9. data/lib/generators/wice_grid/templates/calendarview.js +1168 -0
  10. data/lib/generators/wice_grid/templates/icons/arrow_down.gif +0 -0
  11. data/lib/generators/wice_grid/templates/icons/arrow_up.gif +0 -0
  12. data/lib/generators/wice_grid/templates/icons/calendar_view_month.png +0 -0
  13. data/lib/generators/wice_grid/templates/icons/delete.png +0 -0
  14. data/lib/generators/wice_grid/templates/icons/expand.png +0 -0
  15. data/lib/generators/wice_grid/templates/icons/page_white_excel.png +0 -0
  16. data/lib/generators/wice_grid/templates/icons/page_white_find.png +0 -0
  17. data/lib/generators/wice_grid/templates/icons/table.png +0 -0
  18. data/lib/generators/wice_grid/templates/icons/table_refresh.png +0 -0
  19. data/lib/generators/wice_grid/templates/icons/tick_all.png +0 -0
  20. data/lib/generators/wice_grid/templates/icons/untick_all.png +0 -0
  21. data/lib/generators/wice_grid/templates/wice_grid.css +173 -0
  22. data/lib/generators/wice_grid/templates/wice_grid.yml +279 -0
  23. data/lib/generators/wice_grid/templates/wice_grid_config.rb +154 -0
  24. data/lib/generators/wice_grid/templates/wice_grid_jquery.js +161 -0
  25. data/lib/generators/wice_grid/templates/wice_grid_prototype.js +153 -0
  26. data/lib/generators/wice_grid/wice_grid_assets_jquery_generator.rb +32 -0
  27. data/lib/generators/wice_grid/wice_grid_assets_prototype_generator.rb +34 -0
  28. data/lib/grid_output_buffer.rb +52 -0
  29. data/lib/grid_renderer.rb +535 -0
  30. data/lib/helpers/js_calendar_helpers.rb +183 -0
  31. data/lib/helpers/wice_grid_misc_view_helpers.rb +113 -0
  32. data/lib/helpers/wice_grid_serialized_queries_view_helpers.rb +91 -0
  33. data/lib/helpers/wice_grid_view_helpers.rb +781 -0
  34. data/lib/js_adaptors/jquery_adaptor.rb +145 -0
  35. data/lib/js_adaptors/js_adaptor.rb +12 -0
  36. data/lib/js_adaptors/prototype_adaptor.rb +168 -0
  37. data/lib/table_column_matrix.rb +51 -0
  38. data/lib/tasks/wice_grid_tasks.rake +28 -0
  39. data/lib/view_columns.rb +486 -0
  40. data/lib/views/create.rjs +13 -0
  41. data/lib/views/create_jq.rjs +31 -0
  42. data/lib/views/delete.rjs +12 -0
  43. data/lib/views/delete_jq.rjs +26 -0
  44. data/lib/wice_grid.rb +827 -0
  45. data/lib/wice_grid_controller.rb +165 -0
  46. data/lib/wice_grid_core_ext.rb +179 -0
  47. data/lib/wice_grid_misc.rb +98 -0
  48. data/lib/wice_grid_serialized_queries_controller.rb +86 -0
  49. data/lib/wice_grid_serialized_query.rb +15 -0
  50. data/lib/wice_grid_spreadsheet.rb +33 -0
  51. data/test/.gitignore +2 -0
  52. data/test/database.yml +21 -0
  53. data/test/schema.rb +33 -0
  54. data/test/test_helper.rb +89 -0
  55. data/test/views/projects_and_people_grid.html.erb +12 -0
  56. data/test/views/projects_and_people_grid_invalid.html.erb +12 -0
  57. data/test/views/simple_projects_grid.html.erb +9 -0
  58. data/test/wice_grid_core_ext_test.rb +183 -0
  59. data/test/wice_grid_functional_test.rb +68 -0
  60. data/test/wice_grid_misc_test.rb +41 -0
  61. data/test/wice_grid_test.rb +42 -0
  62. data/test/wice_grid_view_helper_test.rb +12 -0
  63. data/wice_grid.gemspec +111 -0
  64. metadata +153 -0
@@ -0,0 +1,145 @@
1
+ # encoding: UTF-8
2
+ module Wice::JsAdaptor #:nodoc:
3
+
4
+ module Jquery #:nodoc:
5
+
6
+ def self.included(base) #:nodoc:
7
+ base.extend(ClassMethods)
8
+ end
9
+
10
+ module ClassMethods #:nodoc:
11
+
12
+ def init #:nodoc:
13
+ end
14
+
15
+ def dom_loaded #:nodoc:
16
+ %/$(document).ready(function(){\n/
17
+ end
18
+
19
+ def reset_button_initialization(grid_name, reset_grid_javascript) #:nodoc:
20
+ %/ $('div##{grid_name}.wice_grid_container .reset').click(function(e){\n/+
21
+ %/ #{reset_grid_javascript};\n/+
22
+ %/ });\n/
23
+ end
24
+
25
+ def submit_button_initialization(grid_name, submit_grid_javascript) #:nodoc:
26
+ %/ $('div##{grid_name}.wice_grid_container .submit').click(function(e){\n/+
27
+ %/ #{submit_grid_javascript};\n/+
28
+ %/ });\n/
29
+ end
30
+
31
+ def show_hide_button_initialization(grid_name, filter_row_id) #:nodoc:
32
+ %/ $('##{grid_name}_show_icon').click(function(){\n/+
33
+ %/ $('##{grid_name}_show_icon').hide();\n/+
34
+ %/ $('##{grid_name}_hide_icon').show();\n/+
35
+ %/ $('##{filter_row_id}').show();\n/+
36
+ %/ })\n/+
37
+ %/ $('##{grid_name}_hide_icon').click(function(){\n/+
38
+ %/ $('##{grid_name}_show_icon').show();\n/+
39
+ %/ $('##{grid_name}_hide_icon').hide();\n/+
40
+ %/ $('##{filter_row_id}').hide();\n/+
41
+ %/ });\n/
42
+ end
43
+
44
+ def enter_key_event_registration(grid_name) #:nodoc:
45
+ %! $('div##{grid_name}.wice_grid_container .wice_grid_filter_row input[type=text]').keydown(function(event){\n! +
46
+ %! if (event.keyCode == 13) {#{grid_name}.process()}\n! +
47
+ %! });\n!
48
+ end
49
+
50
+ def csv_export_icon_initialization(grid_name) #:nodoc:
51
+ %! $('div##{grid_name}.wice_grid_container .export_to_csv_button').click(function(e){\n! +
52
+ %! #{grid_name}.export_to_csv()\n! +
53
+ %! });\n!
54
+ end
55
+
56
+ def auto_reloading_selects_event_initialization(grid_name) #:nodoc:
57
+ %! $('div##{grid_name}.wice_grid_container select.auto_reload, .#{grid_name}_detached_filter select.auto_reload').change(function(e){\n! +
58
+ %! #{grid_name}.process()\n! +
59
+ %! });\n!
60
+ end
61
+
62
+ def auto_reloading_inputs_event_initialization(grid_name) #:nodoc:
63
+ %! $('div##{grid_name}.wice_grid_container input.auto_reload, .#{grid_name}_detached_filter input.auto_reload').keyup(function(event, element){\n! +
64
+ %! #{grid_name}.process(this.id);\n! +
65
+ %! });\n!
66
+ end
67
+
68
+ def auto_reloading_inputs_with_negation_checkboxes_event_initialization(grid_name) #:nodoc:
69
+ %! $('div##{grid_name}.wice_grid_container input.negation_checkbox, .#{grid_name}_detached_filter input.negation_checkbox').click(function(event, element){\n! +
70
+ %! #{grid_name}.process(this.id);\n! +
71
+ %! });\n!
72
+ end
73
+
74
+
75
+ def auto_reloading_calendar_event_initialization(grid_name) #:nodoc:
76
+ %! $(document).bind('wg:calendarChanged', function(event){\n! +
77
+ %! #{grid_name}.process()\n! +
78
+ %! });\n!
79
+ end
80
+
81
+ def show_all_link_initialization(grid_name, confirmation, parameters_json) #:nodoc:
82
+ %/ $('div##{grid_name}.wice_grid_container .show_all_link').click(function(e){ \n/ +
83
+ %/ #{confirmation} #{grid_name}.reload_page_for_given_grid_state(#{parameters_json}) \n/ +
84
+ %/})\n/
85
+ end
86
+
87
+ def back_to_pagination_link_initialization(grid_name, parameters_json) #:nodoc:
88
+ %/ $('div##{grid_name}.wice_grid_container .show_all_link').click(function(e){\n/ +
89
+ %/ #{grid_name}.reload_page_for_given_grid_state(#{parameters_json})\n/ +
90
+ %/ })\n/
91
+ end
92
+
93
+ def call_to_save_query_and_key_event_initialization_for_saving_queries(
94
+ id_and_name, grid_name, base_path_to_query_controller, parameters_json, ids_json) #:nodoc:
95
+ %/ function #{grid_name}_save_query(){\n/ +
96
+ %` if ( typeof(#{grid_name}) != "undefined")\n` +
97
+ %! #{grid_name}.save_query($('##{id_and_name}')[0].value, '#{base_path_to_query_controller}', #{parameters_json}, #{ids_json})\n! +
98
+ %/}\n/ +
99
+ %/ $('##{id_and_name}').keydown(function(event){\n/ +
100
+ %/ if (event.keyCode == 13) #{grid_name}_save_query();\n/ +
101
+ %/ })\n/
102
+ end
103
+
104
+ def js_framework_specific_calendar_assets(view) #:nodoc:
105
+ ''
106
+ end
107
+
108
+ def js_framework_specific_calendar_js_name #:nodoc:
109
+ nil
110
+ end
111
+
112
+ def js_framework_specific_calendar_css_name #:nodoc:
113
+ nil
114
+ end
115
+
116
+ def action_column_initialization(grid_name) #:nodoc:
117
+ %! $('div##{grid_name}.wice_grid_container .select_all').click(function(e){\n! +
118
+ %! $('div##{grid_name}.wice_grid_container .sel input').each(function(i, checkbox){\n! +
119
+ %! checkbox.checked = true;\n! +
120
+ %! })\n! +
121
+ %! })\n! +
122
+ %! $('div##{grid_name}.wice_grid_container .deselect_all').click(function(e){\n! +
123
+ %! $('div##{grid_name}.wice_grid_container .sel input').each(function(i, checkbox){\n! +
124
+ %! checkbox.checked = false;\n! +
125
+ %! })\n! +
126
+ %! })\n!
127
+ end
128
+
129
+ def fade_this(notification_messages_id) #:nodoc:
130
+ "$('##{notification_messages_id}').effect('fade')"
131
+ end
132
+
133
+ def focus_element(element_to_focus) #:nodoc:
134
+ %! var elements = $('##{element_to_focus}');\n! +
135
+ %! if (elements[0]){\n! +
136
+ %! var elToFocus = elements[0];\n! +
137
+ %! elToFocus.value = elToFocus.value;\n! + # this will just place the cursor at the end of the text input
138
+ %! elToFocus.focus();\n! +
139
+ %! }\n!
140
+ end
141
+
142
+ end
143
+
144
+ end
145
+ end
@@ -0,0 +1,12 @@
1
+ # encoding: UTF-8
2
+
3
+ module Wice::JsAdaptor #:nodoc:
4
+ mattr_accessor :calendar_module
5
+ def self.init #:nodoc:
6
+ if Wice::Defaults::JS_FRAMEWORK == :prototype
7
+ include Wice::JsAdaptor::Prototype
8
+ else
9
+ include Wice::JsAdaptor::Jquery
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,168 @@
1
+ # encoding: UTF-8
2
+ module Wice::JsAdaptor #:nodoc:
3
+
4
+ module Prototype #:nodoc:
5
+
6
+ def self.included(base) #:nodoc:
7
+ base.extend(ClassMethods)
8
+ end
9
+
10
+ module ClassMethods #:nodoc:
11
+ def init #:nodoc:
12
+ end
13
+
14
+ def dom_loaded #:nodoc:
15
+ %/ document.observe("dom:loaded", function() {\n/
16
+ end
17
+
18
+ def reset_button_initialization(grid_name, reset_grid_javascript) #:nodoc:
19
+ %/ $$('div##{grid_name}.wice_grid_container .reset').each(function(e){\n/+
20
+ %/ e.observe('click', function(){\n/+
21
+ %/ #{reset_grid_javascript};\n/+
22
+ %/ })\n/+
23
+ %/ });\n/
24
+ end
25
+
26
+ def submit_button_initialization(grid_name, submit_grid_javascript) #:nodoc:
27
+ %/ $$('div##{grid_name}.wice_grid_container .submit').each(function(e){\n/+
28
+ %/ e.observe('click', function(){\n/+
29
+ %/ #{submit_grid_javascript};\n/+
30
+ %/ })\n/+
31
+ %/ });\n/
32
+ end
33
+
34
+ def show_hide_button_initialization(grid_name, filter_row_id) #:nodoc:
35
+ %/ $('#{grid_name}_show_icon').observe('click', function(){\n/+
36
+ %/ Element.toggle('#{grid_name}_show_icon');\n/+
37
+ %/ Element.toggle('#{grid_name}_hide_icon');\n/+
38
+ %/ $('#{filter_row_id}').show();\n/+
39
+ %/ })\n/+
40
+ %/ $('#{grid_name}_hide_icon').observe('click', function(){\n/+
41
+ %/ Element.toggle('#{grid_name}_show_icon');\n/+
42
+ %/ Element.toggle('#{grid_name}_hide_icon');\n/+
43
+ %/ $('#{filter_row_id}').hide();\n/+
44
+ %/ });\n/
45
+ end
46
+
47
+ def enter_key_event_registration(grid_name) #:nodoc:
48
+ %! $$('div##{grid_name}.wice_grid_container .wice_grid_filter_row input[type=text]').each(function(e){\n! +
49
+ %! e.observe('keydown', function(event){\n! +
50
+ %! if (event.keyCode == 13) {#{grid_name}.process()}\n! +
51
+ %! })\n! +
52
+ %! });\n!
53
+ end
54
+
55
+ def csv_export_icon_initialization(grid_name) #:nodoc:
56
+ %! $$('div##{grid_name}.wice_grid_container .export_to_csv_button').each(function(e){\n! +
57
+ %! e.observe('click', function(event){\n! +
58
+ %! #{grid_name}.export_to_csv()\n! +
59
+ %! })\n! +
60
+ %! });\n!
61
+ end
62
+
63
+ def auto_reloading_selects_event_initialization(grid_name) #:nodoc:
64
+ %! $$('div##{grid_name}.wice_grid_container select.auto_reload', '.#{grid_name}_detached_filter select.auto_reload').each(function(e){\n! +
65
+ %! e.observe('change', function(event){\n! +
66
+ %! #{grid_name}.process()\n! +
67
+ %! })\n! +
68
+ %! });\n!
69
+ end
70
+
71
+ def auto_reloading_inputs_event_initialization(grid_name) #:nodoc:
72
+ %! $$('div##{grid_name}.wice_grid_container input.auto_reload', '.#{grid_name}_detached_filter input.auto_reload').each(function(e){\n! +
73
+ %! e.observe('keyup', function(event){\n! +
74
+ %! #{grid_name}.process(event.element().id)\n! +
75
+ %! })\n! +
76
+ %! });\n!
77
+ end
78
+
79
+ def auto_reloading_inputs_with_negation_checkboxes_event_initialization(grid_name) #:nodoc:
80
+ %! $$('div##{grid_name}.wice_grid_container input.negation_checkbox', '.#{grid_name}_detached_filter input.negation_checkbox').each(function(e){\n! +
81
+ %! e.observe('click', function(event){\n! +
82
+ %! #{grid_name}.process(event.element().id)\n! +
83
+ %! })\n! +
84
+ %! });\n!
85
+ end
86
+
87
+
88
+ def auto_reloading_calendar_event_initialization(grid_name) #:nodoc:
89
+ %! document.observe('wg:calendarChanged', function(event){\n! +
90
+ %! #{grid_name}.process()\n! +
91
+ %! });\n!
92
+ end
93
+
94
+
95
+ def show_all_link_initialization(grid_name, confirmation, parameters_json) #:nodoc:
96
+ %/ $$('div##{grid_name}.wice_grid_container .show_all_link').each(function(e){\n/ +
97
+ %/ e.observe('click', function(){\n/ +
98
+ %/ #{confirmation} #{grid_name}.reload_page_for_given_grid_state(#{parameters_json})\n/ +
99
+ %/ })\n/ +
100
+ %/ })\n/
101
+ end
102
+
103
+
104
+ def back_to_pagination_link_initialization(grid_name, parameters_json) #:nodoc:
105
+ %/ $$('div##{grid_name}.wice_grid_container .show_all_link').each(function(e){\n/ +
106
+ %/ e.observe('click', function(){\n/ +
107
+ %/ #{grid_name}.reload_page_for_given_grid_state(#{parameters_json})\n/ +
108
+ %/ })\n/ +
109
+ %/ })\n/
110
+ end
111
+
112
+ def call_to_save_query_and_key_event_initialization_for_saving_queries(
113
+ id_and_name, grid_name, base_path_to_query_controller, parameters_json, ids_json) #:nodoc:
114
+ %/ function #{grid_name}_save_query(){\n/ +
115
+ %` if ( typeof(#{grid_name}) != "undefined")\n` +
116
+ %/ #{grid_name}.save_query($F('#{id_and_name}'), '#{base_path_to_query_controller}', #{parameters_json}, #{ids_json})\n/ +
117
+ %/ }\n/ +
118
+ %/ $('#{id_and_name}').observe('keydown', function(event){\n/ +
119
+ %/ if (event.keyCode == 13) #{grid_name}_save_query();\n/ +
120
+ %/ })\n/
121
+ end
122
+
123
+
124
+ def js_framework_specific_calendar_assets(view) #:nodoc:
125
+ view.stylesheet_link_tag("calendarview.css") + view.javascript_include_tag("calendarview.js")
126
+ end
127
+
128
+ def js_framework_specific_calendar_js_name #:nodoc:
129
+ 'calendarview.js'
130
+ end
131
+
132
+ def js_framework_specific_calendar_css_name #:nodoc:
133
+ 'calendarview.css'
134
+ end
135
+
136
+
137
+ def action_column_initialization(grid_name) #:nodoc:
138
+ %! $$('div##{grid_name}.wice_grid_container .select_all').each(function(e){\n! +
139
+ %! e.observe('click', function(){\n! +
140
+ %! $$('div##{grid_name}.wice_grid_container .sel input').each(function(checkbox){\n! +
141
+ %! checkbox.checked = true;\n! +
142
+ %! })\n! +
143
+ %! })\n! +
144
+ %! })\n! +
145
+ %! $$('div##{grid_name}.wice_grid_container .deselect_all').each(function(e){\n! +
146
+ %! e.observe('click', function(){\n! +
147
+ %! $$('div##{grid_name}.wice_grid_container .sel input').each(function(checkbox){\n! +
148
+ %! checkbox.checked = false;\n! +
149
+ %! })\n! +
150
+ %! })\n! +
151
+ %! })\n!
152
+ end
153
+
154
+ def fade_this(notification_messages_id) #:nodoc:
155
+ "new Effect.Fade(this)"
156
+ end
157
+
158
+ def focus_element(element_to_focus) #:nodoc:
159
+ %! var elToFocus = $('#{element_to_focus}');\n! +
160
+ %! elToFocus.focus();\n! +
161
+ %! elToFocus.value = elToFocus.value;\n! # this will just place the cursor at the end of the text input
162
+ end
163
+
164
+ end
165
+
166
+ end
167
+
168
+ end
@@ -0,0 +1,51 @@
1
+ # encoding: UTF-8
2
+ module Wice
3
+ class TableColumnMatrix < Hash #:nodoc:
4
+
5
+ attr_reader :generated_conditions
6
+
7
+ def initialize() #:nodoc:
8
+ super
9
+ @generated_conditions = []
10
+ @by_table_names = HashWithIndifferentAccess.new
11
+ end
12
+
13
+ def add_condition(column, conditions)
14
+ @generated_conditions << [column, conditions] unless conditions.blank?
15
+ end
16
+
17
+ def conditions
18
+ @generated_conditions.collect{|_, cond| cond}
19
+ end
20
+
21
+ alias_method :get, :[]
22
+
23
+ attr_reader :default_model_class
24
+ def default_model_class=(model_klass) #:nodoc:
25
+ init_columns_of_table(model_klass) unless has_key?(model_klass)
26
+ @default_model_class = model_klass
27
+ end
28
+
29
+ def [](model_klass) #:nodoc:
30
+ init_columns_of_table(model_klass) unless has_key?(model_klass)
31
+ get(model_klass)
32
+ end
33
+
34
+ def get_column_by_model_class_and_column_name(model_class, column_name) #:nodoc:
35
+ self[model_class][column_name]
36
+ end
37
+
38
+ def get_column_in_default_model_class_by_column_name(column_name) #:nodoc:
39
+ raise WiceGridException.new("Cannot search for a column in a default model as the default model is not set") if @default_model_class.nil?
40
+ self[@default_model_class][column_name]
41
+ end
42
+
43
+ def init_columns_of_table(model_klass) #:nodoc:
44
+ self[model_klass] = HashWithIndifferentAccess.new(model_klass.columns.index_by(&:name))
45
+ @by_table_names[model_klass.table_name] = self[model_klass]
46
+ self[model_klass].each_value{|c| c.model_klass = model_klass}
47
+ end
48
+ alias_method :<< , :init_columns_of_table
49
+
50
+ end
51
+ end
@@ -0,0 +1,28 @@
1
+ namespace "wice_grid" do
2
+
3
+ desc "Create a table to store saved queries"
4
+ task :create_queries_table => :environment do
5
+
6
+ class CreateWiceGridSerializedQueriesTable < ::ActiveRecord::Migration
7
+ def self.up
8
+ create_table :wice_grid_serialized_queries do |t|
9
+ t.column :name, :string
10
+ t.column :grid_name, :string
11
+ t.column :query, :text
12
+
13
+ t.timestamps
14
+ end
15
+ add_index :wice_grid_serialized_queries, :grid_name
16
+ add_index :wice_grid_serialized_queries, [:grid_name, :id]
17
+ end
18
+
19
+ def self.down
20
+ drop_table :wice_grid_serialized_queries
21
+ end
22
+ end
23
+
24
+ CreateWiceGridSerializedQueriesTable.up
25
+ end
26
+
27
+
28
+ end
@@ -0,0 +1,486 @@
1
+ # encoding: UTF-8
2
+ module Wice
3
+
4
+ class ViewColumn #:nodoc:
5
+ include ActionView::Helpers::FormTagHelper
6
+ include ActionView::Helpers::TagHelper
7
+ include ActionView::Helpers::JavaScriptHelper
8
+ include ActionView::Helpers::AssetTagHelper
9
+
10
+ # fields defined from the options parameter
11
+ FIELDS = [:attribute_name, :column_name, :td_html_attrs, :no_filter, :model_class, :allow_multiple_selection,
12
+ :in_html, :in_csv, :helper_style, :table_alias, :custom_order, :detach_with_id, :allow_ordering, :auto_reload]
13
+
14
+ attr_accessor *FIELDS
15
+
16
+ attr_accessor :cell_rendering_block, :grid, :css_class, :table_name, :main_table, :model_class, :custom_filter
17
+
18
+ attr_reader :contains_a_text_input
19
+
20
+ def initialize(block, options, grid_obj, tname, mtable, cfilter, view) #:nodoc:
21
+ self.cell_rendering_block = block
22
+ self.grid = grid_obj
23
+ self.table_name = tname
24
+ self.main_table = mtable
25
+ self.custom_filter = cfilter
26
+ @view = view
27
+
28
+ FIELDS.each do |field|
29
+ self.send(field.to_s + '=', options[field])
30
+ end
31
+ end
32
+
33
+ cattr_accessor :handled_type
34
+ @@handled_type = Hash.new
35
+
36
+ def css_class #:nodoc:
37
+ @css_class || ''
38
+ end
39
+
40
+ def yield_declaration_of_column_filter #:nodoc:
41
+ nil
42
+ end
43
+
44
+ def detachness #:nodoc:
45
+ (! detach_with_id.blank?).to_s
46
+ end
47
+
48
+ def yield_javascript #:nodoc:
49
+ declaration = yield_declaration_of_column_filter
50
+ if declaration
51
+ %!#{@grid.name}.register( {
52
+ filter_name : "#{self.column_name}",
53
+ detached : #{detachness},
54
+ #{declaration}
55
+ } ); !
56
+ else
57
+ ''
58
+ end
59
+ end
60
+
61
+
62
+ def config #:nodoc:
63
+ @view.config
64
+ end
65
+
66
+ def controller #:nodoc:
67
+ @view.controller
68
+ end
69
+
70
+
71
+ def render_filter #:nodoc:
72
+ params = @grid.filter_params(self)
73
+ res = render_filter_internal(params)
74
+ return (res.is_a?(Array)) ? res : [res, nil]
75
+ end
76
+
77
+ def render_filter_internal(params) #:nodoc:
78
+ '<!-- implement me! -->'
79
+ end
80
+
81
+ def form_parameter_name_id_and_query(v) #:nodoc:
82
+ query = form_parameter_template(v)
83
+ query_without_equals_sign = query.sub(/=$/,'')
84
+ parameter_name = CGI.unescape(query_without_equals_sign)
85
+ dom_id = id_out_of_name(parameter_name)
86
+ return query, query_without_equals_sign, parameter_name, dom_id.tr('.', '_')
87
+ end
88
+
89
+ # bad name, because for the main table the name is not really 'fully_qualified'
90
+ def attribute_name_fully_qualified_for_all_but_main_table_columns #:nodoc:
91
+ self.main_table ? attribute_name : table_alias_or_table_name + '.' + attribute_name
92
+ end
93
+
94
+ def fully_qualified_attribute_name #:nodoc:
95
+ table_alias_or_table_name + '.' + attribute_name
96
+ end
97
+
98
+
99
+ def filter_shown? #:nodoc:
100
+ self.attribute_name && ! self.no_filter
101
+ end
102
+
103
+ def filter_shown_in_main_table? #:nodoc:
104
+ filter_shown? && ! self.detach_with_id
105
+ end
106
+
107
+
108
+ def table_alias_or_table_name #:nodoc:
109
+ table_alias || table_name
110
+ end
111
+
112
+ def capable_of_hosting_filter_related_icons? #:nodoc:
113
+ self.attribute_name.blank? && self.column_name.blank? && ! self.filter_shown?
114
+ end
115
+
116
+ def has_auto_reloading_input? #:nodoc:
117
+ false
118
+ end
119
+
120
+ def auto_reloading_input_with_negation_checkbox? #:nodoc:
121
+ false
122
+ end
123
+
124
+ def has_auto_reloading_select? #:nodoc:
125
+ false
126
+ end
127
+
128
+ def has_auto_reloading_calendar? #:nodoc:
129
+ false
130
+ end
131
+
132
+ protected
133
+
134
+ def form_parameter_template(v) #:nodoc:
135
+ {@grid.name => {:f => {self.attribute_name_fully_qualified_for_all_but_main_table_columns => v}}}.to_query
136
+ end
137
+
138
+ def form_parameter_name(v) #:nodoc:
139
+ form_parameter_template_hash(v).to_query
140
+ end
141
+
142
+ def name_out_of_template(s) #:nodoc:
143
+ CGI.unescape(s).sub(/=$/,'')
144
+ end
145
+
146
+ def id_out_of_name(s) #:nodoc:
147
+ s.gsub(/[\[\]]+/,'_').sub(/_+$/, '')
148
+ end
149
+
150
+ end
151
+
152
+ class ActionViewColumn < ViewColumn #:nodoc:
153
+ def initialize(grid_obj, td_html_attrs, param_name, select_all_buttons, object_property, view) #:nodoc:
154
+ @view = view
155
+ @select_all_buttons = select_all_buttons
156
+ self.grid = grid_obj
157
+ self.td_html_attrs = td_html_attrs
158
+ self.td_html_attrs.add_or_append_class_value!('sel')
159
+ grid_name = self.grid.name
160
+ @param_name = param_name
161
+ @cell_rendering_block = lambda do |object, params|
162
+ selected = if params[grid_name] && params[grid_name][param_name] &&
163
+ params[grid_name][param_name].index(object.send(object_property).to_s)
164
+ true
165
+ else
166
+ false
167
+ end
168
+ check_box_tag("#{grid_name}[#{param_name}][]", object.send(object_property), selected, :id => nil)
169
+ end
170
+ end
171
+
172
+ def in_html #:nodoc:
173
+ true
174
+ end
175
+
176
+ def capable_of_hosting_filter_related_icons? #:nodoc:
177
+ false
178
+ end
179
+
180
+ def column_name #:nodoc:
181
+ return '' unless @select_all_buttons
182
+ select_all_tootip = WiceGridNlMessageProvider.get_message(:SELECT_ALL)
183
+ deselect_all_tootip = WiceGridNlMessageProvider.get_message(:DESELECT_ALL)
184
+
185
+ html = content_tag(:span, image_tag(Defaults::TICK_ALL_ICON, :alt => select_all_tootip),
186
+ :class => 'clickable select_all', :title => select_all_tootip) + ' ' +
187
+ content_tag(:span, image_tag(Defaults::UNTICK_ALL_ICON, :alt => deselect_all_tootip),
188
+ :class => 'clickable deselect_all', :title => deselect_all_tootip)
189
+
190
+ js = JsAdaptor.action_column_initialization(grid.name)
191
+
192
+ [html, js]
193
+ end
194
+
195
+ end
196
+
197
+ class ViewColumnInteger < ViewColumn #:nodoc:
198
+ @@handled_type[:integer] = self
199
+
200
+ def render_filter_internal(params) #:nodoc:
201
+ @contains_a_text_input = true
202
+
203
+ @query, _, parameter_name, @dom_id = form_parameter_name_id_and_query(:fr => '')
204
+ @query2, _, parameter_name2, @dom_id2 = form_parameter_name_id_and_query(:to => '')
205
+
206
+ opts1 = {:size => 3, :id => @dom_id}
207
+ opts2 = {:size => 3, :id => @dom_id2}
208
+
209
+ if auto_reload
210
+ opts1[:class] = ' auto_reload'
211
+ opts2[:class] = ' auto_reload'
212
+ end
213
+
214
+ text_field_tag(parameter_name, params[:fr], opts1) + text_field_tag(parameter_name2, params[:to], opts2)
215
+ end
216
+
217
+ def yield_declaration_of_column_filter #:nodoc:
218
+ %$templates : ['#{@query}', '#{@query2}'],
219
+ ids : ['#{@dom_id}', '#{@dom_id2}'] $
220
+ end
221
+
222
+ def has_auto_reloading_input? #:nodoc:
223
+ auto_reload
224
+ end
225
+
226
+ end
227
+
228
+ class ViewColumnFloat < ViewColumnInteger #:nodoc:
229
+ @@handled_type[:decimal] = self
230
+ @@handled_type[:float] = self
231
+ end
232
+
233
+ class ViewColumnCustomDropdown < ViewColumn #:nodoc:
234
+ include ActionView::Helpers::FormOptionsHelper
235
+
236
+ attr_accessor :filter_all_label
237
+ attr_accessor :custom_filter
238
+
239
+ def render_filter_internal(params) #:nodoc:
240
+ @query, @query_without_equals_sign, @parameter_name, @dom_id = form_parameter_name_id_and_query('')
241
+ @query_without_equals_sign += '%5B%5D='
242
+
243
+ @custom_filter = @custom_filter.call if @custom_filter.kind_of? Proc
244
+
245
+ if @custom_filter.kind_of? Array
246
+
247
+ @custom_filter = [[@filter_all_label, nil]] + @custom_filter.map{|label, value|
248
+ [label.to_s, value.to_s]
249
+ }
250
+
251
+ end
252
+
253
+ select_options = {:name => @parameter_name, :id => @dom_id, :class => 'custom_dropdown'}
254
+
255
+ if @turn_off_select_toggling
256
+ select_toggle = ''
257
+ else
258
+ if self.allow_multiple_selection
259
+ select_options[:multiple] = params.is_a?(Array) && params.size > 1
260
+ select_toggle = content_tag(:a,
261
+ tag(:img, :alt => 'Expand/Collapse', :src => Defaults::TOGGLE_MULTI_SELECT_ICON),
262
+ :href => "javascript: toggle_multi_select('#{@dom_id}', this, 'Expand', 'Collapse');", # TO DO: to locales
263
+ :class => 'toggle_multi_select_icon', :title => 'Expand')
264
+ else
265
+ select_options[:multiple] = false
266
+ select_toggle = ''
267
+ end
268
+ end
269
+
270
+ if auto_reload
271
+ select_options[:class] += ' auto_reload'
272
+ end
273
+
274
+ params_for_select = (params.is_a?(Hash) && params.empty?) ? [nil] : params
275
+
276
+ '<span class="custom_dropdown_container">'.html_safe_if_necessary +
277
+ content_tag(:select,
278
+ options_for_select(@custom_filter, params_for_select),
279
+ select_options) +
280
+ select_toggle.html_safe_if_necessary + '</span>'.html_safe_if_necessary
281
+ end
282
+
283
+ def yield_declaration_of_column_filter #:nodoc:
284
+ %$templates : ['#{@query_without_equals_sign}'],
285
+ ids : ['#{@dom_id}'] $
286
+ end
287
+
288
+ def has_auto_reloading_select? #:nodoc:
289
+ auto_reload
290
+ end
291
+ end
292
+
293
+ class ViewColumnBoolean < ViewColumnCustomDropdown #:nodoc:
294
+ @@handled_type[:boolean] = self
295
+ include ActionView::Helpers::FormOptionsHelper
296
+
297
+ attr_accessor :boolean_filter_true_label, :boolean_filter_false_label
298
+
299
+ def render_filter_internal(params) #:nodoc:
300
+ @custom_filter = {
301
+ @filter_all_label => nil,
302
+ @boolean_filter_true_label => 't',
303
+ @boolean_filter_false_label => 'f'
304
+ }
305
+
306
+ @turn_off_select_toggling = true
307
+ super(params)
308
+ end
309
+ end
310
+
311
+ class ViewColumnDatetime < ViewColumn #:nodoc:
312
+ @@handled_type[:datetime] = self
313
+ @@handled_type[:timestamp] = self
314
+ include ActionView::Helpers::DateHelper
315
+ include Wice::JsCalendarHelpers
316
+
317
+
318
+ # name_and_id_from_options in Rails Date helper does not substitute '.' with '_'
319
+ # like all other simpler form helpers do. Thus, overriding it here.
320
+ def name_and_id_from_options(options, type) #:nodoc:
321
+ options[:name] = (options[:prefix] || DEFAULT_PREFIX) + (options[:discard_type] ? '' : "[#{type}]")
322
+ options[:id] = options[:name].gsub(/([\[\(])|(\]\[)/, '_').gsub(/[\]\)]/, '').gsub(/\./, '_').gsub(/_+/, '_')
323
+ end
324
+
325
+ @@datetime_chunk_names = %w(year month day hour minute)
326
+
327
+ def prepare_for_standard_filter #:nodoc:
328
+ x = lambda{|sym|
329
+ @@datetime_chunk_names.collect{|datetime_chunk_name|
330
+ triple = form_parameter_name_id_and_query(sym => {datetime_chunk_name => ''})
331
+ [triple[0], triple[3]]
332
+ }
333
+ }
334
+
335
+ @queris_ids = x.call(:fr) + x.call(:to)
336
+
337
+ _, _, @name1, _ = form_parameter_name_id_and_query({:fr => ''})
338
+ _, _, @name2, _ = form_parameter_name_id_and_query({:to => ''})
339
+ end
340
+
341
+
342
+ def prepare_for_calendar_filter #:nodoc:
343
+ query, _, @name1, @dom_id = form_parameter_name_id_and_query(:fr => '')
344
+ query2, _, @name2, @dom_id2 = form_parameter_name_id_and_query(:to => '')
345
+
346
+ @queris_ids = [[query, @dom_id], [query2, @dom_id2] ]
347
+ end
348
+
349
+
350
+ def render_standard_filter_internal(params) #:nodoc:
351
+ '<div class="date-filter">' +
352
+ select_datetime(params[:fr], {:include_blank => true, :prefix => @name1}) + '<br/>' +
353
+ select_datetime(params[:to], {:include_blank => true, :prefix => @name2}) +
354
+ '</div>'
355
+ end
356
+
357
+ def render_calendar_filter_internal(params) #:nodoc:
358
+ html1, js1 = datetime_calendar_prototype(params[:fr], @view,
359
+ {:include_blank => true, :prefix => @name1, :id => @dom_id, :fire_event => auto_reload},
360
+ :title => WiceGridNlMessageProvider.get_message(:DATE_SELECTOR_TOOLTIP_FROM))
361
+ html2, js2 = datetime_calendar_prototype(params[:to], @view,
362
+ {:include_blank => true, :prefix => @name2, :id => @dom_id2, :fire_event => auto_reload},
363
+ :title => WiceGridNlMessageProvider.get_message(:DATE_SELECTOR_TOOLTIP_TO))
364
+ [%!<div class="date-filter">#{html1}<br/>#{html2}</div>!, js1 + js2]
365
+ end
366
+
367
+
368
+ def render_filter_internal(params) #:nodoc:
369
+ # falling back to the Rails helpers for Datetime
370
+ if helper_style == :standard || Defaults::JS_FRAMEWORK == :jquery
371
+ prepare_for_standard_filter
372
+ render_standard_filter_internal(params)
373
+ else
374
+ prepare_for_calendar_filter
375
+ render_calendar_filter_internal(params)
376
+ end
377
+ end
378
+
379
+ def yield_declaration_of_column_filter #:nodoc:
380
+ %$templates : [ #{@queris_ids.collect{|tuple| "'" + tuple[0] + "'"}.join(', ')} ],
381
+ ids : [ #{@queris_ids.collect{|tuple| "'" + tuple[1] + "'"}.join(', ')} ] $
382
+ end
383
+
384
+ def has_auto_reloading_calendar? #:nodoc:
385
+ auto_reload && helper_style == :calendar
386
+ end
387
+
388
+ end
389
+
390
+ class ViewColumnDate < ViewColumnDatetime #:nodoc:
391
+ @@handled_type[:date] = self
392
+
393
+ @@datetime_chunk_names = %w(year month day)
394
+
395
+ def render_standard_filter_internal(params) #:nodoc:
396
+ '<div class="date-filter">' +
397
+ select_date(params[:fr], {:include_blank => true, :prefix => @name1, :id => @dom_id}) + '<br/>' +
398
+ select_date(params[:to], {:include_blank => true, :prefix => @name2, :id => @dom_id2}) +
399
+ '</div>'
400
+ end
401
+
402
+ def render_calendar_filter_internal(params) #:nodoc:
403
+
404
+ calendar_helper_method = if Wice::Defaults::JS_FRAMEWORK == :prototype
405
+ :date_calendar_prototype
406
+ else
407
+ :date_calendar_jquery
408
+ end
409
+
410
+ html1, js1 = send(calendar_helper_method, params[:fr], @view,
411
+ {:include_blank => true, :prefix => @name1, :fire_event => auto_reload},
412
+ :title => WiceGridNlMessageProvider.get_message(:DATE_SELECTOR_TOOLTIP_FROM))
413
+ html2, js2 = send(calendar_helper_method, params[:to], @view,
414
+ {:include_blank => true, :prefix => @name2, :fire_event => auto_reload},
415
+ :title => WiceGridNlMessageProvider.get_message(:DATE_SELECTOR_TOOLTIP_TO))
416
+
417
+ [%!<div class="date-filter">#{html1}<br/>#{html2}</div>!, js1 + js2]
418
+ end
419
+
420
+ def render_filter_internal(params) #:nodoc:
421
+
422
+ if helper_style == :standard
423
+ prepare_for_standard_filter
424
+ render_standard_filter_internal(params)
425
+ else
426
+ prepare_for_calendar_filter
427
+ render_calendar_filter_internal(params)
428
+ end
429
+ end
430
+ end
431
+
432
+ class ViewColumnString < ViewColumn #:nodoc:
433
+ @@handled_type[:string] = self
434
+ @@handled_type[:text] = self
435
+
436
+ attr_accessor :negation, :auto_reloading_input_with_negation_checkbox
437
+
438
+ def render_filter_internal(params) #:nodoc:
439
+ @contains_a_text_input = true
440
+ css_class = auto_reload ? 'auto_reload' : nil
441
+
442
+ if negation
443
+ self.auto_reloading_input_with_negation_checkbox = true if auto_reload
444
+
445
+ @query, _, parameter_name, @dom_id = form_parameter_name_id_and_query(:v => '')
446
+ @query2, _, parameter_name2, @dom_id2 = form_parameter_name_id_and_query(:n => '')
447
+
448
+ '<div class="text_filter_container">' +
449
+ text_field_tag(parameter_name, params[:v], :size => 8, :id => @dom_id, :class => css_class) +
450
+ if defined?(::Wice::Defaults::NEGATION_CHECKBOX_LABEL) && ! ::Wice::Defaults::NEGATION_CHECKBOX_LABEL.blank?
451
+ ::Wice::Defaults::NEGATION_CHECKBOX_LABEL
452
+ else
453
+ ''
454
+ end +
455
+ check_box_tag(parameter_name2, '1', (params[:n] == '1'),
456
+ :id => @dom_id2,
457
+ :title => WiceGridNlMessageProvider.get_message(:NEGATION_CHECKBOX_TITLE),
458
+ :class => 'negation_checkbox') +
459
+ '</div>'
460
+ else
461
+ @query, _, parameter_name, @dom_id = form_parameter_name_id_and_query('')
462
+ text_field_tag(parameter_name, (params.blank? ? '' : params), :size => 8, :id => @dom_id, :class => css_class)
463
+ end
464
+ end
465
+
466
+ def yield_declaration_of_column_filter #:nodoc:
467
+ if negation
468
+ %$templates : ['#{@query}', '#{@query2}'],
469
+ ids : ['#{@dom_id}', '#{@dom_id2}'] $
470
+ else
471
+ %$templates : ['#{@query}'],
472
+ ids : ['#{@dom_id}'] $
473
+ end
474
+ end
475
+
476
+ def has_auto_reloading_input? #:nodoc:
477
+ auto_reload
478
+ end
479
+
480
+ def auto_reloading_input_with_negation_checkbox? #:nodoc:
481
+ self.auto_reloading_input_with_negation_checkbox
482
+ end
483
+
484
+ end
485
+
486
+ end