mongoid_wice_grid 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. data/.gitignore +9 -0
  2. data/CHANGELOG +409 -0
  3. data/Gemfile +17 -0
  4. data/Gemfile.lock +140 -0
  5. data/MIT-LICENSE +20 -0
  6. data/README.rdoc +1188 -0
  7. data/Rakefile +40 -0
  8. data/SAVED_QUERIES_HOWTO.rdoc +123 -0
  9. data/VERSION +1 -0
  10. data/lib/filter_conditions_generators.rb +126 -0
  11. data/lib/generators/wice_grid/templates/calendarview.css +107 -0
  12. data/lib/generators/wice_grid/templates/calendarview.js +1168 -0
  13. data/lib/generators/wice_grid/templates/icons/arrow_down.gif +0 -0
  14. data/lib/generators/wice_grid/templates/icons/arrow_up.gif +0 -0
  15. data/lib/generators/wice_grid/templates/icons/calendar_view_month.png +0 -0
  16. data/lib/generators/wice_grid/templates/icons/delete.png +0 -0
  17. data/lib/generators/wice_grid/templates/icons/expand.png +0 -0
  18. data/lib/generators/wice_grid/templates/icons/page_white_excel.png +0 -0
  19. data/lib/generators/wice_grid/templates/icons/page_white_find.png +0 -0
  20. data/lib/generators/wice_grid/templates/icons/table.png +0 -0
  21. data/lib/generators/wice_grid/templates/icons/table_refresh.png +0 -0
  22. data/lib/generators/wice_grid/templates/icons/tick_all.png +0 -0
  23. data/lib/generators/wice_grid/templates/icons/untick_all.png +0 -0
  24. data/lib/generators/wice_grid/templates/wice_grid.css +173 -0
  25. data/lib/generators/wice_grid/templates/wice_grid.yml +269 -0
  26. data/lib/generators/wice_grid/templates/wice_grid_config.rb +215 -0
  27. data/lib/generators/wice_grid/templates/wice_grid_jquery.js +161 -0
  28. data/lib/generators/wice_grid/templates/wice_grid_prototype.js +153 -0
  29. data/lib/generators/wice_grid/wice_grid_assets_jquery_generator.rb +32 -0
  30. data/lib/generators/wice_grid/wice_grid_assets_prototype_generator.rb +34 -0
  31. data/lib/grid_output_buffer.rb +52 -0
  32. data/lib/grid_renderer.rb +547 -0
  33. data/lib/helpers/js_calendar_helpers.rb +183 -0
  34. data/lib/helpers/wice_grid_misc_view_helpers.rb +113 -0
  35. data/lib/helpers/wice_grid_serialized_queries_view_helpers.rb +82 -0
  36. data/lib/helpers/wice_grid_view_helpers.rb +761 -0
  37. data/lib/js_adaptors/jquery_adaptor.rb +145 -0
  38. data/lib/js_adaptors/js_adaptor.rb +12 -0
  39. data/lib/js_adaptors/prototype_adaptor.rb +168 -0
  40. data/lib/mongoid_field.rb +50 -0
  41. data/lib/tasks/wice_grid_tasks.rake +28 -0
  42. data/lib/view_columns.rb +464 -0
  43. data/lib/views/create.rjs +13 -0
  44. data/lib/views/delete.rjs +12 -0
  45. data/lib/wice_grid.rb +521 -0
  46. data/lib/wice_grid_controller.rb +165 -0
  47. data/lib/wice_grid_core_ext.rb +179 -0
  48. data/lib/wice_grid_misc.rb +99 -0
  49. data/lib/wice_grid_serialized_queries_controller.rb +77 -0
  50. data/lib/wice_grid_serialized_query.rb +14 -0
  51. data/lib/wice_grid_spreadsheet.rb +33 -0
  52. data/test/.gitignore +2 -0
  53. data/test/blueprint.rb +17 -0
  54. data/test/database.yml +21 -0
  55. data/test/public/javascripts/jquery-1.4.2.min.js +154 -0
  56. data/test/public/javascripts/wice_grid.js +163 -0
  57. data/test/rails_mongoid_test.rb +104 -0
  58. data/test/rails_test_app.rb +71 -0
  59. data/test/require_gems.rb +19 -0
  60. data/test/schema.rb +33 -0
  61. data/test/spec_helper.rb +22 -0
  62. data/test/test_helper.rb +89 -0
  63. data/test/views/projects_and_people_grid.html.erb +12 -0
  64. data/test/views/projects_and_people_grid_invalid.html.erb +12 -0
  65. data/test/views/simple_projects_grid.html.erb +9 -0
  66. data/test/wice_grid_core_ext_test.rb +183 -0
  67. data/test/wice_grid_functional_test.rb +68 -0
  68. data/test/wice_grid_initializer.rb +215 -0
  69. data/test/wice_grid_misc_test.rb +41 -0
  70. data/test/wice_grid_test.rb +42 -0
  71. data/test/wice_grid_view_helper_test.rb +12 -0
  72. metadata +150 -0
@@ -0,0 +1,13 @@
1
+ if @notification_messages
2
+ page.replace_html(@notification_messages_dom_id, %!<div class="wice_grid_notice"> #{h @notification_messages}</div>!)
3
+ end
4
+
5
+ if @error_messages
6
+ page.replace_html(@notification_messages_dom_id, %!<div class="errorExplanation"> #{h @error_messages} </div>!)
7
+ else
8
+ page.replace(@query_list_dom_id, saved_queries_list(@grid_name, @saved_query, controller.extra))
9
+ page[@query_list_dom_id].visual_effect :highlight
10
+ page.replace_html(@grid_title_id, content_tag(:h3,@saved_query.name))
11
+ end
12
+
13
+ page[@notification_messages_dom_id].show
@@ -0,0 +1,12 @@
1
+ if @notification_messages
2
+ page.replace_html(@notification_messages_dom_id, %!<div class="wice_grid_notice"> #{h @notification_messages}</div>!)
3
+ end
4
+
5
+ if @error_messages
6
+ page.replace_html(@notification_messages_dom_id, %!<div class="errorExplanation"> #{h @error_messages} </div>!)
7
+ else
8
+ page.replace(@query_list_dom_id, saved_queries_list(@grid_name, @current, controller.extra))
9
+ page[@query_list_dom_id].visual_effect :highlight
10
+ end
11
+
12
+ page[@notification_messages_dom_id].show
data/lib/wice_grid.rb ADDED
@@ -0,0 +1,521 @@
1
+ # encoding: UTF-8
2
+ require 'wice_grid_misc.rb'
3
+ require 'wice_grid_core_ext.rb'
4
+ require 'grid_renderer.rb'
5
+ require 'helpers/wice_grid_view_helpers.rb'
6
+ require 'helpers/wice_grid_misc_view_helpers.rb'
7
+ require 'helpers/wice_grid_serialized_queries_view_helpers.rb'
8
+ require 'helpers/wice_grid_view_helpers.rb'
9
+ require 'helpers/js_calendar_helpers.rb'
10
+ require 'grid_output_buffer.rb'
11
+ require 'wice_grid_controller.rb'
12
+ require 'mongoid_field'
13
+ require 'wice_grid_spreadsheet.rb'
14
+ require 'wice_grid_serialized_queries_controller.rb'
15
+ require 'js_adaptors/js_adaptor.rb'
16
+ require 'js_adaptors/jquery_adaptor.rb'
17
+ require 'js_adaptors/prototype_adaptor.rb'
18
+ require 'view_columns.rb'
19
+
20
+
21
+ ActionController::Base.send(:helper_method, :wice_grid_custom_filter_params)
22
+
23
+ module Wice
24
+
25
+ class WiceGridRailtie < Rails::Railtie
26
+
27
+ initializer "wice_grid_railtie.configure_rails_initialization" do |app|
28
+ ActionController::Base.send(:include, Wice::Controller)
29
+ Mongoid::Field.send(:include, ::Wice::MongoidField)
30
+ ::ActionView::Base.class_eval { include Wice::GridViewHelper }
31
+
32
+ [ActionView::Helpers::AssetTagHelper,
33
+ ActionView::Helpers::TagHelper,
34
+ ActionView::Helpers::JavaScriptHelper,
35
+ ActionView::Helpers::FormTagHelper].each do |m|
36
+ JsCalendarHelpers.send(:include, m)
37
+ end
38
+ end
39
+
40
+ rake_tasks do
41
+ load 'tasks/wice_grid_tasks.rake'
42
+ end
43
+ end
44
+
45
+ class WiceGrid
46
+
47
+ attr_reader :klass, :name, :resultset, :custom_order, :query_store_model, :options, :controller
48
+ attr_reader :ar_options, :status, :export_to_csv_enabled, :csv_file_name, :saved_query
49
+ attr_writer :renderer
50
+ attr_accessor :output_buffer, :view_helper_finished, :csv_tempfile
51
+
52
+ # core workflow methods START
53
+
54
+ def initialize(klass, controller, opts = {}) #:nodoc:
55
+ @controller = controller
56
+
57
+ unless klass.kind_of?(Class) && klass.ancestors.index(Mongoid::Document)
58
+ raise WiceGridArgumentError.new("ActiveRecord model class (second argument) must be a Class derived from Mongoid::Document")
59
+ end
60
+ # validate :with_resultset & :with_paginated_resultset
61
+ [:with_resultset, :with_paginated_resultset].each do |callback_symbol|
62
+ unless [NilClass, Symbol, Proc].index(opts[callback_symbol].class)
63
+ raise WiceGridArgumentError.new(":#{callback_symbol} must be either a Proc or Symbol object")
64
+ end
65
+ end
66
+
67
+ opts[:order_direction].downcase! if opts[:order_direction].kind_of?(String)
68
+
69
+ # validate :order_direction
70
+ if opts[:order_direction] && ! (opts[:order_direction] == 'asc' ||
71
+ opts[:order_direction] == :asc ||
72
+ opts[:order_direction] == 'desc' ||
73
+ opts[:order_direction] == :desc)
74
+ raise WiceGridArgumentError.new(":order_direction must be either 'asc' or 'desc'.")
75
+ end
76
+
77
+ # options that are understood
78
+ @options = {
79
+ :conditions => nil,
80
+ :csv_file_name => nil,
81
+ :custom_order => {},
82
+ :enable_export_to_csv => Defaults::ENABLE_EXPORT_TO_CSV,
83
+ :group => nil,
84
+ :include => nil,
85
+ :joins => nil,
86
+ :name => Defaults::GRID_NAME,
87
+ :order => nil,
88
+ :order_direction => Defaults::ORDER_DIRECTION,
89
+ :per_page => Defaults::PER_PAGE,
90
+ :saved_query => nil,
91
+ :select => nil,
92
+ :total_entries => nil,
93
+ :with_paginated_resultset => nil,
94
+ :with_resultset => nil
95
+ }
96
+
97
+ # validate parameters
98
+ opts.assert_valid_keys(@options.keys)
99
+
100
+ @options.merge!(opts)
101
+ @export_to_csv_enabled = @options[:enable_export_to_csv]
102
+ @csv_file_name = @options[:csv_file_name]
103
+
104
+ case @name = @options[:name]
105
+ when String
106
+ when Symbol
107
+ @name = @name.to_s
108
+ else
109
+ raise WiceGridArgumentError.new("name of the grid should be a string or a symbol")
110
+ end
111
+ raise WiceGridArgumentError.new("name of the grid can only contain alphanumeruc characters") unless @name =~ /^[a-zA-Z\d_]*$/
112
+
113
+ @klass = klass
114
+ @criteria = Mongoid::Criteria.new(@klass)
115
+ @has_any_filter_criteria = false
116
+ @status = HashWithIndifferentAccess.new
117
+
118
+ if @options[:order]
119
+ @options[:order] = @options[:order].to_s
120
+ @options[:order_direction] = @options[:order_direction].to_s
121
+
122
+ @status[:order_direction] = @options[:order_direction]
123
+ @status[:order] = @options[:order]
124
+
125
+ end
126
+ @status[:total_entries] = @options[:total_entries]
127
+ @status[:per_page] = @options[:per_page]
128
+ @status[:page] = @options[:page]
129
+ @status[:conditions] = @options[:conditions]
130
+ @status[:f] = @options[:f]
131
+
132
+ process_loading_query
133
+ process_params
134
+ @criteria_formed = false
135
+ end
136
+
137
+ def has_any_filter_criteria?
138
+ @has_any_filter_criteria
139
+ end
140
+
141
+ def has_more_to_show?
142
+ @status[:per_page].to_i < resultset.count
143
+ end
144
+ # A block executed from within the plugin to process records of the current page.
145
+ # The argument to the callback is the array of the records. See the README for more details.
146
+ def with_paginated_resultset(&callback)
147
+ @options[:with_paginated_resultset] = callback
148
+ end
149
+
150
+ # A block executed from within the plugin to process all records browsable through
151
+ # all pages with the current filters. The argument to
152
+ # the callback is a lambda object which returns the list of records when called. See the README for the explanation.
153
+ def with_resultset(&callback)
154
+ @options[:with_resultset] = callback
155
+ end
156
+
157
+ def process_loading_query #:nodoc:
158
+ @saved_query = nil
159
+ if params[name] && params[name][:q]
160
+ @saved_query = load_query(params[name][:q])
161
+ params[name].delete(:q)
162
+ elsif @options[:saved_query]
163
+ if @options[:saved_query].is_a? ActiveRecord::Base
164
+ @saved_query = @options[:saved_query]
165
+ else
166
+ @saved_query = load_query(@options[:saved_query])
167
+ end
168
+ else
169
+ return
170
+ end
171
+
172
+ unless @saved_query.nil?
173
+ params[name] = HashWithIndifferentAccess.new if params[name].blank?
174
+ [:f, :order, :order_direction].each do |key|
175
+ if @saved_query.query[key].blank?
176
+ params[name].delete(key)
177
+ else
178
+ params[name][key] = @saved_query.query[key]
179
+ end
180
+ end
181
+ end
182
+ end
183
+
184
+ def process_params #:nodoc:
185
+ if this_grid_params
186
+ @status.merge!(this_grid_params)
187
+ @status.delete(:export) unless self.export_to_csv_enabled
188
+ end
189
+ end
190
+
191
+ def declare_column(field_name, custom_filter_active) #:nodoc:
192
+ field = @klass.fields[field_name]
193
+ raise WiceGridArgumentError.new("Model #{@klass.name} does not have field '#{field_name}'.! ") unless field
194
+
195
+ criteria_added = field.wice_add_filter_criteria(@status[:f], @criteria, custom_filter_active)
196
+ @status[:f].delete(field_name) if @status[:f] && !criteria_added
197
+
198
+ @has_any_filter_criteria ||= criteria_added
199
+ [field, nil , true]
200
+ end
201
+
202
+ def form_criteria(opts = {}) #:nodoc:
203
+
204
+ return if @criteria_formed
205
+ @criteria_formed = true unless opts[:forget_generated_options]
206
+
207
+ # validate @status[:order_direction]
208
+ @status[:order_direction] = case @status[:order_direction]
209
+ when /desc/i
210
+ 'desc'
211
+ when /asc/i
212
+ 'asc'
213
+ else
214
+ ''
215
+ end
216
+
217
+ @status.delete(:f) if !@has_any_filter_criteria
218
+
219
+ if !opts[:skip_ordering] && @status[:order]
220
+ order_by = @status[:order].to_sym.send( @status[:order_direction].to_sym )
221
+ @criteria.order_by(order_by)
222
+ end
223
+
224
+ @criteria.limit(@status[:per_page].to_i)
225
+ # #fix-this, Criteria must respect options
226
+ # if self.output_html?
227
+ # @criteria[:per_page] = if all_record_mode?
228
+ # # reset the :pp value in all records mode
229
+ # @status[:pp] = count_resultset_without_paging_without_user_filters
230
+ # else
231
+ # @status[:per_page]
232
+ # end
233
+
234
+ # @criteria[:page] = @status[:page]
235
+ # @criteria[:total_entries] = @status[:total_entries] if @status[:total_entries]
236
+ # end
237
+
238
+ # @criteria[:joins] = @options[:joins]
239
+ # @criteria[:include] = @options[:include]
240
+ # @criteria[:group] = @options[:group]
241
+ # @criteria[:select] = @options[:select]
242
+ end
243
+
244
+ def read #:nodoc:
245
+ form_criteria
246
+ with_exclusive_scope do
247
+ @criteria.options[:limit] = nil if @resultset = self.output_csv?
248
+ @resultset = @criteria
249
+ end
250
+ invoke_resultset_callbacks
251
+ end
252
+
253
+
254
+ # core workflow methods END
255
+
256
+ # Getters
257
+
258
+ def filter_params(view_column) #:nodoc:
259
+ return @status[:f][view_column.attribute_name] if @status[:f]
260
+ {}
261
+ end
262
+
263
+ def resultset #:nodoc:
264
+ self.read unless @resultset # database querying is late!
265
+ @resultset
266
+ end
267
+
268
+ def each #:nodoc:
269
+ self.read unless @resultset # database querying is late!
270
+ @resultset.each do |r|
271
+ yield r
272
+ end
273
+ end
274
+
275
+ def ordered_by?(column) #:nodoc:
276
+ return nil if @status[:order].blank?
277
+ @status[:order] == column.attribute_name
278
+ end
279
+
280
+ def ordered_by #:nodoc:
281
+ @status[:order]
282
+ end
283
+
284
+
285
+ def order_direction #:nodoc:
286
+ @status[:order_direction]
287
+ end
288
+
289
+ def filtering_on? #:nodoc:
290
+ not @status[:f].blank?
291
+ end
292
+
293
+ def filtered_by #:nodoc:
294
+ @status[:f].nil? ? [] : @status[:f].keys
295
+ end
296
+
297
+ def filtered_by?(view_column) #:nodoc:
298
+ @status[:f] && @status[:f].has_key?(view_column.attribute_name)
299
+ end
300
+
301
+ def get_state_as_parameter_value_pairs(including_saved_query_request = false) #:nodoc:
302
+ res = []
303
+ unless status[:f].blank?
304
+ status[:f].parameter_names_and_values([name, 'f']).collect do |param_name, value|
305
+ if value.is_a?(Array)
306
+ param_name_ar = param_name + '[]'
307
+ value.each do |v|
308
+ res << [param_name_ar, v]
309
+ end
310
+ else
311
+ res << [param_name, value]
312
+ end
313
+ end
314
+ end
315
+
316
+ if including_saved_query_request && @saved_query
317
+ res << ["#{name}[q]", @saved_query.id ]
318
+ end
319
+
320
+ [:order, :order_direction].select{|parameter|
321
+ status[parameter]
322
+ }.collect do |parameter|
323
+ res << ["#{name}[#{parameter}]", status[parameter] ]
324
+ end
325
+
326
+ res
327
+ end
328
+
329
+ def count #:nodoc:
330
+ form_criteria(:skip_ordering => true, :forget_generated_options => true)
331
+ @klass.count(:conditions => @criteria[:conditions], :joins => @criteria[:joins], :include => @criteria[:include], :group => @criteria[:group])
332
+ end
333
+
334
+ alias_method :size, :count
335
+
336
+ def empty? #:nodoc:
337
+ self.count == 0
338
+ end
339
+
340
+ # with this variant we get even those values which do not appear in the resultset
341
+ def distinct_values_for_column(column) #:nodoc:
342
+ res = column.model_klass.find(:all, :select => "distinct #{column.name}", :order => "#{column.name} asc").collect{|ar|
343
+ ar[column.name]
344
+ }.reject{|e| e.blank?}.map{|i|[i,i]}
345
+ end
346
+
347
+
348
+ def distinct_values_for_column_in_resultset(messages) #:nodoc:
349
+ uniq_vals = Set.new
350
+
351
+ resultset_without_paging_without_user_filters.each do |ar|
352
+ v = ar.deep_send(*messages)
353
+ uniq_vals << v unless v.nil?
354
+ end
355
+ return uniq_vals.to_a.map{|i|
356
+ if i.is_a?(Array) && i.size == 2
357
+ i
358
+ elsif i.is_a?(Hash) && i.size == 1
359
+ i.to_a.flatten
360
+ else
361
+ [i,i]
362
+ end
363
+ }.sort{|a,b| a[0]<=>b[0]}
364
+ end
365
+
366
+ def output_csv? #:nodoc:
367
+ @status[:export] == 'csv'
368
+ end
369
+
370
+ def output_html? #:nodoc:
371
+ @status[:export].blank?
372
+ end
373
+
374
+ def all_record_mode? #:nodoc:
375
+ @status[:pp]
376
+ end
377
+
378
+ def dump_status #:nodoc:
379
+ " params: #{params[name].inspect}\n" +
380
+ " status: #{@status.inspect}\n" +
381
+ " ar_options #{@criteria.inspect}\n"
382
+ end
383
+
384
+
385
+ def selected_records #:nodoc:
386
+ STDERR.puts "WiceGrid: Parameter :#{selected_records} is deprecated, use :#{all_pages_records} or :#{current_page_records} instead!"
387
+ all_pages_records
388
+ end
389
+
390
+ # Returns the list of objects browsable through all pages with the current filters.
391
+ # Should only be called after the +grid+ helper.
392
+ def all_pages_records
393
+ raise WiceGridException.new("all_pages_records can only be called only after the grid view helper") unless self.view_helper_finished
394
+ resultset_without_paging_with_user_filters
395
+ end
396
+
397
+ # Returns the list of objects displayed on current page. Should only be called after the +grid+ helper.
398
+ def current_page_records
399
+ raise WiceGridException.new("current_page_records can only be called only after the grid view helper") unless self.view_helper_finished
400
+ @resultset
401
+ end
402
+
403
+
404
+
405
+ protected
406
+
407
+ def invoke_resultset_callback(callback, argument) #:nodoc:
408
+ case callback
409
+ when Proc
410
+ callback.call(argument)
411
+ when Symbol
412
+ @controller.send(callback, argument)
413
+ end
414
+ end
415
+
416
+ def invoke_resultset_callbacks #:nodoc:
417
+ invoke_resultset_callback(@options[:with_paginated_resultset], @resultset)
418
+ invoke_resultset_callback(@options[:with_resultset], lambda{self.send(:resultset_without_paging_with_user_filters)})
419
+ end
420
+
421
+ def with_exclusive_scope #:nodoc:
422
+ yield
423
+ end
424
+
425
+ def complete_column_name(col_name) #:nodoc:
426
+ if col_name.index('.') # already has a table name
427
+ col_name
428
+ else # add the default table
429
+ "#{@klass.collection_name}.#{col_name}"
430
+ end
431
+ end
432
+
433
+ def params #:nodoc:
434
+ @controller.params
435
+ end
436
+
437
+ def this_grid_params #:nodoc:
438
+ params[name]
439
+ end
440
+
441
+
442
+ def resultset_without_paging_without_user_filters #:nodoc:
443
+ form_criteria
444
+ with_exclusive_scope do
445
+ @klass.find(:all, :joins => @criteria[:joins],
446
+ :include => @criteria[:include],
447
+ :group => @criteria[:group],
448
+ :conditions => @options[:conditions])
449
+ end
450
+ end
451
+
452
+ def count_resultset_without_paging_without_user_filters #:nodoc:
453
+ form_criteria
454
+ with_exclusive_scope do
455
+ @klass.count(
456
+ :joins => @criteria[:joins],
457
+ :include => @criteria[:include],
458
+ :group => @criteria[:group],
459
+ :conditions => @options[:conditions]
460
+ )
461
+ end
462
+ end
463
+
464
+
465
+ def resultset_without_paging_with_user_filters #:nodoc:
466
+ form_criteria
467
+ with_exclusive_scope do
468
+ @klass.find(:all, :joins => @criteria[:joins],
469
+ :include => @criteria[:include],
470
+ :group => @criteria[:group],
471
+ :conditions => @criteria[:conditions],
472
+ :order => @criteria[:order])
473
+ end
474
+ end
475
+
476
+
477
+ def load_query(query_id) #:nodoc:
478
+ @query_store_model ||= Wice::get_query_store_model
479
+ query = @query_store_model.find_by_id_and_grid_name(query_id, self.name)
480
+ Wice::log("Query with id #{query_id} for grid '#{self.name}' not found!!!") if query.nil?
481
+ query
482
+ end
483
+
484
+
485
+ end
486
+
487
+ # routines called from WiceGridExtentionToActiveRecordColumn (ActiveRecord::ConnectionAdapters::Column) or FilterConditionsGenerator classes
488
+ module GridTools #:nodoc:
489
+ class << self
490
+ def special_value(str) #:nodoc:
491
+ str =~ /^\s*(not\s+)?null\s*$/i
492
+ end
493
+
494
+ # create a Time instance out of parameters
495
+ def params_2_datetime(par) #:nodoc:
496
+ return nil if par.blank?
497
+ params = [par[:year], par[:month], par[:day], par[:hour], par[:minute]].collect{|v| v.blank? ? nil : v.to_i}
498
+ begin
499
+ Time.local(*params)
500
+ rescue ArgumentError, TypeError
501
+ nil
502
+ end
503
+ end
504
+
505
+ # create a Date instance out of parameters
506
+ def params_2_date(par) #:nodoc:
507
+ return nil if par.blank?
508
+ params = [par[:year], par[:month], par[:day]].collect{|v| v.blank? ? nil : v.to_i}
509
+ begin
510
+ Date.civil(*params)
511
+ rescue ArgumentError, TypeError
512
+ nil
513
+ end
514
+ end
515
+
516
+ end
517
+ end
518
+
519
+
520
+
521
+ end