fancygrid 1.1.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. data/CHANGELOG +9 -2
  2. data/Gemfile +6 -9
  3. data/Gemfile.lock +88 -103
  4. data/README.md +226 -0
  5. data/ROADMAP +0 -1
  6. data/Rakefile +2 -2
  7. data/VERSION +1 -1
  8. data/app/views/fancygrid/controls.html.haml +34 -0
  9. data/app/views/fancygrid/fancygrid.html.haml +18 -0
  10. data/app/views/fancygrid/search.html.haml +24 -0
  11. data/app/views/fancygrid/sort.html.haml +8 -0
  12. data/app/views/fancygrid/table.html.haml +25 -0
  13. data/config/locales/fancygrid.de.yml +17 -19
  14. data/config/locales/fancygrid.en.yml +14 -17
  15. data/fancygrid.gemspec +48 -88
  16. data/lib/assets/javascripts/fancygrid.js +425 -0
  17. data/lib/assets/javascripts/fancygrid.min.js +15 -0
  18. data/lib/assets/stylesheets/fancygrid.css +177 -0
  19. data/lib/fancygrid.rb +63 -44
  20. data/lib/fancygrid/column.rb +165 -0
  21. data/lib/fancygrid/controller/helper.rb +46 -0
  22. data/lib/fancygrid/grid.rb +171 -317
  23. data/lib/fancygrid/node.rb +85 -490
  24. data/lib/fancygrid/object_wrapper.rb +24 -0
  25. data/lib/fancygrid/orm/active_record.rb +39 -0
  26. data/lib/fancygrid/orm/sql_generator.rb +127 -0
  27. data/lib/fancygrid/view/helper.rb +44 -0
  28. data/lib/fancygrid/view_state.rb +161 -0
  29. data/spec/column_spec.rb +29 -0
  30. data/spec/dummy/app/controllers/application_controller.rb +48 -0
  31. data/spec/dummy/app/views/application/index.html.haml +11 -0
  32. data/spec/dummy/app/views/layouts/application.html.erb +1 -1
  33. data/spec/dummy/config/application.rb +1 -1
  34. data/spec/dummy/config/environments/development.rb +2 -2
  35. data/spec/dummy/config/environments/test.rb +2 -2
  36. data/spec/dummy/config/routes.rb +3 -2
  37. data/spec/dummy/db/development.sqlite3 +0 -0
  38. data/spec/dummy/db/schema.rb +26 -0
  39. data/spec/dummy/public/javascripts/jquery-1.4.2.js +6240 -0
  40. data/spec/dummy/public/javascripts/jquery-fancygrid.js +425 -0
  41. data/spec/dummy/public/javascripts/jquery-ui.js +41 -0
  42. data/spec/dummy/public/stylesheets/fancygrid.css +183 -0
  43. data/spec/node_spec.rb +79 -301
  44. data/spec/spec_helper.rb +0 -29
  45. data/spec/view_state_spec.rb +91 -0
  46. metadata +124 -137
  47. data/.bundle/config +0 -2
  48. data/README.rdoc +0 -299
  49. data/app/views/fancygrid/_cells.html.haml +0 -13
  50. data/app/views/fancygrid/base/controls.html.haml +0 -40
  51. data/app/views/fancygrid/base/list_frame.html.haml +0 -37
  52. data/app/views/fancygrid/base/search.html.haml +0 -33
  53. data/app/views/fancygrid/base/sort.html.haml +0 -20
  54. data/app/views/fancygrid/base/table_frame.html.haml +0 -45
  55. data/config/initializers/fancygrid.rb +0 -67
  56. data/lib/fancygrid/helper.rb +0 -129
  57. data/lib/fancygrid/query_generator.rb +0 -340
  58. data/lib/fancygrid/view.rb +0 -148
  59. data/lib/generators/install_generator.rb +0 -61
  60. data/lib/generators/views_generator.rb +0 -25
  61. data/lib/version.rb +0 -0
  62. data/public/images/fancygrid/add.png +0 -0
  63. data/public/images/fancygrid/clear.png +0 -0
  64. data/public/images/fancygrid/ddn.png +0 -0
  65. data/public/images/fancygrid/dn.png +0 -0
  66. data/public/images/fancygrid/dots.png +0 -0
  67. data/public/images/fancygrid/loading.gif +0 -0
  68. data/public/images/fancygrid/magnifier.png +0 -0
  69. data/public/images/fancygrid/next.png +0 -0
  70. data/public/images/fancygrid/order.png +0 -0
  71. data/public/images/fancygrid/prev.png +0 -0
  72. data/public/images/fancygrid/reload.png +0 -0
  73. data/public/images/fancygrid/remove.png +0 -0
  74. data/public/images/fancygrid/spacer.gif +0 -0
  75. data/public/images/fancygrid/submit.png +0 -0
  76. data/public/images/fancygrid/th_bg.png +0 -0
  77. data/public/images/fancygrid/up.png +0 -0
  78. data/public/images/fancygrid/uup.png +0 -0
  79. data/public/javascripts/fancygrid.js +0 -477
  80. data/public/javascripts/fancygrid.min.js +0 -17
  81. data/public/stylesheets/fancygrid.css +0 -289
  82. data/public/stylesheets/fancygrid.scss +0 -302
  83. data/spec/dummy/log/development.log +0 -0
  84. data/spec/dummy/log/production.log +0 -0
  85. data/spec/dummy/log/server.log +0 -0
  86. data/spec/dummy/log/test.log +0 -1026
  87. data/spec/dummy/public/javascripts/application.js +0 -2
  88. data/spec/dummy/public/javascripts/controls.js +0 -965
  89. data/spec/dummy/public/javascripts/dragdrop.js +0 -974
  90. data/spec/dummy/public/javascripts/effects.js +0 -1123
  91. data/spec/dummy/public/javascripts/prototype.js +0 -6001
  92. data/spec/dummy/public/javascripts/rails.js +0 -175
  93. data/spec/grid_spec.rb +0 -15
  94. data/spec/integration/navigation_spec.rb +0 -9
  95. data/spec/query_generator_spec.rb +0 -358
@@ -0,0 +1,46 @@
1
+ module Fancygrid
2
+ module Controller
3
+ module Helper
4
+ include ActionView::Helpers::TextHelper
5
+
6
+ # Creates a fancygrid instance for the given model name
7
+ def fancygrid_for(name, options = {})#:yields: grid
8
+ persist_state = (options.delete(:persist) == true)
9
+ state_hash = resolve_fancystate_hash(name, persist_state)
10
+
11
+ klass = options.fetch(:builder, Fancygrid::Grid)
12
+ instance = klass.new(name, options.merge(:state_hash => state_hash))
13
+
14
+ @fancygrid_collection ||= HashWithIndifferentAccess.new
15
+ @fancygrid_collection[name] = instance
16
+
17
+ yield instance if block_given?
18
+ return instance
19
+ end
20
+
21
+ def resolve_fancystate_hash(name, persist_state = false)
22
+ state_hash = params.fetch(:fancygrid, {}).fetch(name, nil)
23
+
24
+ if persist_state
25
+ if state_hash.nil?
26
+ state_hash = load_fancystate_hash(name)
27
+ else
28
+ store_fancystate_hash(name, state_hash)
29
+ end
30
+ end
31
+
32
+ return state_hash || HashWithIndifferentAccess.new
33
+ end
34
+
35
+ # Loads a fancygrid state for given name
36
+ def load_fancystate_hash(name)
37
+ session.fetch("fancygrid_#{name}", HashWithIndifferentAccess.new)
38
+ end
39
+
40
+ # Stores the given fancygrid state under given name
41
+ def store_fancystate_hash(name, state)
42
+ session["fancygrid_#{name}"] = state
43
+ end
44
+ end
45
+ end
46
+ end
@@ -1,399 +1,253 @@
1
- require "active_support/hash_with_indifferent_access"
2
-
3
1
  module Fancygrid#:nodoc:
4
-
2
+
5
3
  class Grid < Fancygrid::Node
6
4
 
7
- # Collection of all fancygrid leafs. These are instances of Fancygrid::Node
8
- # and define the columns of a table. They may refer to an attribute or a
9
- # method or a renderable cell of a model
5
+ # Collection of all defined columns.
10
6
  attr_accessor :leafs
11
7
 
12
- # The database query that is sent to the database.
13
- attr_accessor :query
8
+ # The grids view state.
9
+ attr_accessor :view_state
14
10
 
15
- # The current POST or GET parameters.
16
- attr_accessor :request_params
11
+ # The class of the database connector implementation to be used.
12
+ attr_accessor :orm
17
13
 
18
- # The result of the database query. This is the data that is going to be rendered.
19
- attr_accessor :dataset
14
+
15
+ # The result of the database query. This is the data that is going
16
+ # to be rendered.
17
+ attr_accessor :records
20
18
 
21
- # Number of possible matching results.
22
- attr_accessor :resultcount
23
-
24
- # Order and visibility definition for each column
25
- attr_accessor :view
26
-
27
-
19
+ # Number of matching records. This is displayed in the pagination.
20
+ attr_accessor :record_count
28
21
 
29
22
  # Url for the ajax callback.
30
- attr_accessor :url
23
+ attr_accessor :ajax_url
31
24
 
32
- # the request type for the ajax callback
25
+ # The request method for the ajax callback e.g. GET or POST.
33
26
  attr_accessor :ajax_type
34
27
 
35
- # enables or disables the sort window
36
- attr_accessor :enable_sort_window
37
-
38
- # The template name that is used to render this grid.
39
- attr_accessor :template
28
+ # Array of fancygrid component names that are going to be rendered.
29
+ attr_accessor :components
40
30
 
41
- # Enables or disables the input fields for simple search.
42
- attr_accessor :search_visible
43
-
44
- # Specifies the type of the search. Must be one of "simple" or "complex"
45
- attr_accessor :search_type
31
+ # Specifies whether sql select optimization should be performed
32
+ attr_accessor :select
33
+
34
+ # If true then hides the search bar, but keeps it enabled.
35
+ attr_accessor :hide_search
46
36
 
47
- # Specifies a set of enabled search operators
37
+ # Array of enabled search operators.
48
38
  attr_accessor :search_operators
49
39
 
50
- # Enables or disables the rendering of the top control bar.
51
- attr_accessor :hide_top_control
52
-
53
- # Enables or disables the rendering of the bottom control bar.
54
- attr_accessor :hide_bottom_control
55
-
56
- # Specifies the rendering strategy. May be one of 'table' or 'list'
57
- attr_accessor :grid_type
58
-
59
- # Spcified the select options for per page drop down
60
- attr_accessor :per_page_options
61
-
62
- # Spcified theselected value in the per page drop down
63
- attr_accessor :per_page_selection
64
-
65
- # Specifies the search options for search input fields
66
- attr_accessor :search_formats
67
-
68
- # Specifies what operators the simple search has to ose for specific columns
69
- attr_accessor :simple_search_operators
70
-
71
-
40
+ # The default search operator.
41
+ attr_accessor :search_operator
42
+
43
+ # Specifies whether pagination is enabled or not.
44
+ attr_accessor :paginate
72
45
 
46
+ # Array of select options for per page drop down.
47
+ attr_accessor :per_page_values
73
48
 
74
- # Initializes the root node of the fancygrid tree.
75
- def initialize(name, klass = nil, table_name = nil, params = nil)
76
- super(self, nil, name)
77
- initialize_node(name, klass, table_name)
78
-
79
- self.url = nil
80
- self.ajax_type = :get
81
- self.enable_sort_window = false
82
- self.leafs = []
83
- self.dataset = nil
84
- self.resultcount = 0
49
+ # The default value for the per page drop down.
50
+ attr_accessor :per_page_value
85
51
 
86
- self.query = {}
87
- self.request_params = (params || {})
88
-
89
- self.grid_type = Fancygrid.default_grid_type
90
- self.search_visible = Fancygrid.search_visible
91
- self.search_type = Fancygrid.default_search_type
92
- self.search_operators = Fancygrid.search_operators
93
- self.search_formats = {}
94
- self.simple_search_operators = ActiveSupport::HashWithIndifferentAccess.new({})
95
-
96
- if Fancygrid.use_grid_name_as_cells_template
97
- self.template = File.join(Fancygrid.cells_template_directory.to_s, name.to_s)
98
- else
99
- self.template = File.join(Fancygrid.cells_template_directory.to_s, Fancygrid.cells_template.to_s)
100
- end
101
-
102
- self.per_page_options = Fancygrid.default_per_page_options
103
- self.per_page_selection = Fancygrid.default_per_page_selection
104
-
105
- view_opts = self.request_params[:fancygrid] || {}
106
- view_opts = view_opts[self.name]
107
-
108
- self.load_view(view_opts || {})
109
- end
52
+ # If pagination is enabled this value holds the total number of
53
+ # available data pages.
54
+ attr_accessor :page_count
110
55
 
111
- # Inserts a given node into the leafs collection.
112
- #
113
- def insert_node(node)
114
- raise "Node must be a leaf" unless node.is_leaf?
115
- if (self.view)
116
- node.position = self.view.get_node_position(node)
117
- node.visible = self.view.get_node_visibility(node)
118
- node.search_value = self.view.get_node_search_value(node)
119
- end
120
- leafs << node
121
- end
56
+ # Options that have been passed to initialize the fancygrid.
57
+ attr_accessor :options
122
58
 
123
- # Sorts the leafs by position attribute
59
+ # Initializes the fancygrid
124
60
  #
125
- def sort_leafs!
126
- leafs.sort! { |a, b| a.position.to_i <=> b.position.to_i }
61
+ def initialize(name, options = {})
62
+ self.options = Fancygrid.default_options.merge(options)
63
+ super(nil, name, self.options)
64
+ self.apply_options(self.options)
127
65
  end
128
66
 
129
- # Takes the given view hash and aligns the leafs using the passed view definitions
67
+ # Applies the given options and sets default values
130
68
  #
131
- def load_view options
132
- options ||= {}
133
- options = options[:fancygrid] || options
134
- options = options[self.name] || options
135
- self.view = Fancygrid::View.new(options)
136
-
137
- # reorder current leafs
138
- new_leafs = self.leafs
139
- self.leafs = []
140
- new_leafs.each do |leaf|
141
- insert_node(leaf)
142
- end
143
- end
69
+ def apply_options(options)
70
+ self.leafs = []
71
+ self.view_state = Fancygrid::ViewState.new(options.fetch(:state_hash, {}))
144
72
 
145
- # Yields a query generator which should be used to build a find query
146
- #
147
- # == Options
148
- # The options are the same as in active record finder method
149
- # * <tt>:conditions</tt> - An SQL fragment like “administrator = 1”, ["user_name = ?", username], or ["user_name = :user_name", { :user_name => user_name }]
150
- # * <tt>:order</tt> - An SQL fragment like “created_at DESC, name”.
151
- # * <tt>:group</tt> - An attribute name by which the result should be grouped. Uses the GROUP BY SQL-clause.
152
- # * <tt>:having</tt> - Combined with :group this can be used to filter the records that a GROUP BY returns. Uses the HAVING SQL-clause.
153
- # * <tt>:limit</tt> - An integer determining the limit on the number of rows that should be returned.
154
- # * <tt>:offset</tt> - An integer determining the offset from where the rows should be fetched. So at 5, it would skip rows 0 through 4.
155
- # * <tt>:joins</tt> - Either an SQL fragment for additional joins like “LEFT JOIN comments ON comments.post_id = id” (rarely needed), named associations in the same form used for the :include option, which will perform an INNER JOIN on the associated table(s), or an array containing a mixture of both strings and named associations. If the value is a string, then the records will be returned read-only since they will have attributes that do not correspond to the table’s columns. Pass :readonly => false to override.
156
- # * <tt>:include</tt> - Names associations that should be loaded alongside. The symbols named refer to already defined associations. See eager loading under Associations.
157
- # * <tt>:select</tt> - By default, this is “*” as in “SELECT * FROM”, but can be changed if you, for example, want to do a join but not include the joined columns. Takes a string with the SELECT SQL fragment (e.g. “id, name”).
158
- # * <tt>:from</tt> - By default, this is the table name of the class, but can be changed to an alternate table name (or even the name of a database view).
159
- # * <tt>:readonly</tt> - Mark the returned records read-only so they cannot be saved or updated.
160
- # * <tt>:lock</tt> - An SQL fragment like “FOR UPDATE” or “LOCK IN SHARE MODE”. :lock => true gives connection’s default exclusive lock, usually “FOR UPDATE”.
161
- def find(options={})#:yields: generator
162
- raise "calling 'find' twice or after 'data=' is not allowed" unless dataset.nil?
163
-
164
- # don not process same or equal leafs twice
165
- leafs.compact!
166
-
167
- # get the parameters for this grid instance, they are mapped like this { :fancygrid => { :gird_name => ..options.. }}
168
- params = request_params[:fancygrid] || {}
169
- params = params[self.name] || {}
170
-
171
- # build default query hash
172
- url_options = {
173
- :select => self.leafs.map{ |leaf| leaf.select_name }.compact,
174
- :conditions => params[:conditions],
175
- :pagination => params[:pagination],
176
- :operator => params[:operator]
177
- }
178
-
179
- generator = Fancygrid::QueryGenerator.new(url_options, self)
180
- generator.parse_options(options)
181
- yield(generator) if block_given?
73
+ self.records = []
74
+ self.record_count = 0
75
+ self.orm = options[:orm].classify.constantize
76
+
77
+ self.ajax_url = nil
78
+ self.ajax_type = options[:ajax_type]
79
+ self.components = options[:components]
182
80
 
183
- generator.order(self.view.get_sort_order)
81
+ self.hide_search = options[:hide_search]
82
+ self.search_operators = options[:search_operators]
83
+ self.search_operator = options[:search_operator]
184
84
 
185
- self.query = generator.query
85
+ self.per_page_values = options[:per_page_values]
86
+ self.per_page_value = self.view_state.pagination_per_page(options[:per_page_value])
87
+ self.paginate = true
88
+ self.select = true
89
+ self.page_count = 0
186
90
  end
187
91
 
188
- # Sets a custom dataset that should be rendered.Blanks out the
189
- # callback <tt>url</tt> so no ajax request will be made.
190
- #
191
- def data= data
192
- leafs.compact!
92
+ def find &block
93
+ self.collect_columns
94
+
95
+ query_options = {}
96
+ query_options[:grid] = self
97
+ query_options[:conditions] = self.view_state.conditions
98
+ query_options[:operator] = self.view_state.operator
193
99
 
194
- self.dataset = data.to_a
195
- self.url = nil
196
- end
197
-
198
- # Runs the current query and caches the resulting data
199
- #
200
- def query_for_data
201
- if self.record_klass < ActiveRecord::Base
202
- self.dataset = self.record_klass.find(:all, self.query)
203
-
204
- count_query = self.query.reject do |k, v|
205
- [:limit, :offset, :order].include?(k.to_sym )
206
- end
207
- self.resultcount = self.record_klass.count(:all, count_query)
208
-
209
- elsif self.record_klass < ActiveResource::Base
210
- self.dataset = self.record_klass.find(:all, :params => self.query)
211
- self.resultcount = self.dataset.delete_at(self.dataset.length - 1).total
212
- else
213
- raise "Unable to query for data. Supported base classes are 'ActiveRecord::Base' and 'ActiveResource::Base' but '#{self.record_klass}' was given"
100
+ if self.select
101
+ query_options[:select] = self.leafs.select { |leaf| leaf.selectable }.map{ |leaf| leaf.identifier }
102
+ end
103
+
104
+ if self.paginate && self.dynamic?
105
+ query_options[:pagination] = self.view_state.pagination_options(1, self.per_page_value)
214
106
  end
215
107
 
216
- self.resultcount = self.resultcount.length if self.resultcount.respond_to?(:length)
108
+ self.records, self.record_count = self.orm.new(query_options).execute(resource_class, &block)
109
+ self.page_count = (self.record_count.to_f / self.per_page_value.to_f).ceil
217
110
  end
218
111
 
219
-
220
-
221
-
222
-
223
- # Returns true if the callback url is blank, that is when no ajax
224
- # functionality is wanted.
225
- def is_static?
226
- self.url.blank?
227
- end
228
-
229
- # Determines whether the grid instance is initialized with simle search
230
- #
231
- def has_simple_search?
232
- self.search_type.to_s == "simple" && !self.is_static?
233
- end
234
-
235
- # Determines whether the grid instance is initialized with complex search
236
- #
237
- def has_complex_search?
238
- self.search_type.to_s == "complex" && !self.is_static?
239
- end
240
-
241
- # Determines whether the grid instance displays the top control bar
112
+ # Determines whether ajax callbacks are enabled or not
242
113
  #
243
- def has_top_control?
244
- !self.hide_top_control && !self.is_static?
114
+ def dynamic?
115
+ self.ajax_url.present?
245
116
  end
246
117
 
247
- # Determines whether the grid instance displays the bottom control bar
118
+ # Determines whether the given component is enabled or not.
248
119
  #
249
- def has_bottom_control?
250
- !self.hide_bottom_control && !self.is_static?
120
+ def component?(name)
121
+ self.components.include?(name)
251
122
  end
252
123
 
253
- # Determines whether the grid instance is able to sort columns
124
+ # Determines whether the simple search component is enabled.
254
125
  #
255
- def has_sort_window?
256
- !self.is_static? && self.enable_sort_window
126
+ def simple_search?
127
+ dynamic? && component?(:search_bar)
257
128
  end
258
129
 
259
- def enable_state_caching!
260
- load_view_proc do |instance|
261
- opts = session[:fancygrid] || {}
262
- opts[instance.name.to_s] || {}
263
- end
264
- load_view_proc do |instance, dump|
265
- session[:fancygrid] ||= {}
266
- session[:fancygrid][instance.name.to_s] = dump
267
- end
268
- end
269
-
270
- # If a block is given a new Proc is created for later css evaluation
130
+ # Determines whether the complex search component is enabled.
271
131
  #
272
- def css_proc
273
- @css_proc = Proc.new if block_given?
274
- @css_proc
132
+ def complex_search?
133
+ dynamic? && component?(:search)
275
134
  end
276
135
 
277
- # Evaluates the css class for a table row by using the passed record and the ccs_proc of this grid
136
+ # Determines whether the top control bar component is enabled.
278
137
  #
279
- def css_proc_evaluate(record)
280
- @css_proc and @css_proc.call(record) or ""
138
+ def top_control?
139
+ dynamic? && component?(:top_bar)
281
140
  end
282
141
 
283
- # Gets and sets a proc for loading a dumped view from session, database or whatever place
284
- #
285
- # == Example
142
+ # Determines whether the bottom control bar component is enabled.
286
143
  #
287
- # fancygrid_for :companies do |g|
288
- # g.load_view_proc do |instance|
289
- # # load a hash from session, fancygrid will use that to initiate its view
290
- # session["fancygrid_#{instance.name.to_s}"] || {}
291
- # end
292
- # end
293
- def load_view_proc
294
- @load_view_proc = Proc.new if block_given?
295
- @load_view_proc
144
+ def bottom_control?
145
+ dynamic? && component?(:bottom_bar)
296
146
  end
297
147
 
298
- # Evaluates the <tt>load_view_proc</tt> if available
148
+ # Determines whether the sort window component is enabled.
299
149
  #
300
- def load_view_proc_evaluate
301
- return load_view_proc.call(self) if load_view_proc.is_a?(Proc)
150
+ def sort_window?
151
+ dynamic? && component?(:sort_window)
152
+ end
153
+
154
+ # Collects and returns all columns that are marked to be visible.
155
+ # The collection is sorted by the column position attribute.
156
+ #
157
+ def visible_columns
158
+ @visible_columns ||= leafs.select { |leaf|
159
+ leaf.visible
160
+ }.sort { |a, b|
161
+ a.position <=> b.position
162
+ }
302
163
  end
303
164
 
304
- # Gets and sets a proc for storing a dumped view to session, database or whatever place
305
- #
306
- # == Example
165
+ # Collects and returns all columns that are marked to be hidden.
166
+ # The collection is sorted by the column position attribute.
307
167
  #
308
- # fancygrid_for :companies do |g|
309
- # g.store_view_proc do |instance, dump|
310
- # # store the dump to. The dump comes from the fancygrid view
311
- # session["fancygrid_#{instance.name.to_s}"] = dump
312
- # end
313
- # end
314
- def store_view_proc
315
- @store_view_proc = Proc.new if block_given?
316
- @store_view_proc
168
+ def hidden_columns
169
+ @hidden_columns ||= leafs.select { |leaf|
170
+ leaf.hidden
171
+ }.sort { |a, b|
172
+ a.position <=> b.position
173
+ }
317
174
  end
318
-
319
- # Evaluates the <tt>store_view_proc</tt> if available
175
+
176
+ # Generates options for dropdown selection to select a column.
320
177
  #
321
- def store_view_proc_evaluate
322
- store_view_proc.call(self, self.view.dump) if store_view_proc.is_a?(Proc)
178
+ def select_column_options
179
+ leafs.select { |leaf|
180
+ !leaf.hidden && leaf.searchable
181
+ }.map { |leaf|
182
+ [leaf.human_name, leaf.identifier]
183
+ }
323
184
  end
324
185
 
325
-
326
- # Yields each leaf that is visible
186
+ # Generates options for dropdown selection to select a comparison operator.
327
187
  #
328
- def each_leaf#:yields: leaf
329
- leafs.compact!
330
-
331
- leafs.each do |leaf|
332
- yield leaf
188
+ def select_operator_options
189
+ @select_operator_options ||= self.search_operators.map do |op|
190
+ [ self.operator_human_name(op.to_s), op.to_s ]
333
191
  end
334
192
  end
335
193
 
336
- # Yields each leaf that is visible
194
+ # Gets the human readable name for given comparison operator.
337
195
  #
338
- def each_visible_leaf#:yields: leaf
339
- leafs.compact!
340
-
341
- leafs.each do |leaf|
342
- yield leaf if leaf.visible
343
- end
196
+ def operator_human_name(name)
197
+ I18n.t(:"search.operator.#{name}", {
198
+ :default => name.humanize,
199
+ :scope => Fancygrid.i18n_scope
200
+ })
344
201
  end
345
202
 
346
- # Yields each leaf that is not visible
203
+ # Sets the search options for given column.
347
204
  #
348
- def each_hidden_leaf#:yields: leaf
349
- leafs.compact!
350
-
351
- leafs.each do |leaf|
352
- yield leaf unless leaf.visible
353
- end
205
+ def search_filter column, collection
206
+ node = self.children.select { |leaf| leaf.respond_to?(:identifier) && leaf.identifier == column }.first
207
+ node.search_options = Array(collection).map { |v| v.is_a?(Array) ? v : [v.to_s, v.to_s]}
354
208
  end
355
209
 
356
- # Gets all leafs that are visible and searchable
357
- def serachable_leafs
358
- leafs.select { |leaf| leaf && leaf.searchable && leaf.visible }.compact
359
- end
360
-
361
- # Yields each fetched record if available
210
+ # Builds the javascript options for the javascript part of fancygrid.
362
211
  #
363
- def each_record#:yields: record
364
- return unless self.dataset
365
- self.dataset.each do |record|
366
- yield record
367
- end
368
- end
369
-
370
- def simple_search_operator table, column
371
- return simple_search_operators if simple_search_operators.is_a? Symbol
372
- opts = (simple_search_operators || {})
373
- opts = opts[table] || {}
374
- return opts if opts.is_a? Symbol
375
- opts[column]
376
- end
377
-
378
- # Builds the javascript options for the javascript part of fancygrid
379
212
  def js_options
380
213
  {
381
- :url => self.url,
214
+ :ajaxUrl => self.ajax_url,
382
215
  :ajaxType => self.ajax_type,
383
216
  :name => self.name,
384
- :isStatic => self.is_static?,
385
- :gridType => self.grid_type,
386
- :searchVisible => (self.view.search_visible or self.search_visible),
387
- :searchType => self.search_type,
388
- :hideTopControl => self.hide_top_control,
389
- :hideBottomControl => self.hide_bottom_control,
390
- :paginationPage => self.view.get_pagination_page,
391
- :paginationPerPage => self.view.get_pagination_per_page,
392
- }.to_json
217
+ :page => self.view_state.pagination_page,
218
+ :perPage => self.per_page_value,
219
+ :searchVisible => !self.hide_search || !self.view_state.conditions.empty?
220
+ }.to_json.gsub("<|>", "")
393
221
  end
394
222
 
395
- def log(message)#:nodoc:
396
- #Rails.logger.debug("[FANCYGRID] #{message.to_s}")
223
+ # Reorganizes the defined columns and post fixes some options
224
+ #
225
+ def collect_columns
226
+ leafs.clear
227
+ super(leafs)
228
+ leafs.each do |leaf|
229
+ leaf.position = self.view_state.column_option(leaf, :position, leaf.position).to_i
230
+ leaf.width = self.view_state.column_option(leaf, :width, leaf.width)
231
+ leaf.visible = self.view_state.column_option(leaf, :visible, leaf.visible).to_s == "true"
232
+
233
+ leaf.search_operator = self.view_state.column_condition(leaf, :operator, leaf.search_operator)
234
+ leaf.search_value = self.view_state.column_condition(leaf, :value, leaf.search_value)
235
+ end
236
+ leafs.sort! { |a, b| a.position <=> b.position }
237
+ end
238
+
239
+ # Dumps the fetched records into an array of hashes that
240
+ # can be rendered as xml or cvs.
241
+ #
242
+ def dump_records
243
+ result = []
244
+ self.records.each do |record|
245
+ result << (dump = {})
246
+ self.visible_columns.each do |col|
247
+ dump[col.identifier] = col.fetch_value_and_format(record)
248
+ end
249
+ end
250
+ return result
397
251
  end
398
252
  end
399
253
  end