netzke-basepack 0.7.0 → 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (169) hide show
  1. data/CHANGELOG.rdoc +9 -1
  2. data/README.md +5 -8
  3. data/Rakefile +0 -1
  4. data/lib/netzke/active_record/attributes.rb +13 -5
  5. data/lib/netzke/basepack.rb +0 -1
  6. data/lib/netzke/basepack/data_accessor.rb +76 -17
  7. data/lib/netzke/basepack/form_panel.rb +23 -34
  8. data/lib/netzke/basepack/form_panel/fields.rb +7 -0
  9. data/lib/netzke/basepack/form_panel/services.rb +6 -3
  10. data/lib/netzke/basepack/grid_panel/services.rb +2 -49
  11. data/lib/netzke/basepack/version.rb +1 -1
  12. data/netzke-basepack.gemspec +158 -154
  13. data/test/{rails_app → basepack_test_app}/.gitignore +2 -1
  14. data/test/basepack_test_app/.rvmrc +1 -0
  15. data/test/{rails_app → basepack_test_app}/Gemfile +2 -3
  16. data/test/{rails_app → basepack_test_app}/Gemfile.lock +80 -70
  17. data/test/{rails_app → basepack_test_app}/README +0 -0
  18. data/test/{rails_app → basepack_test_app}/Rakefile +0 -0
  19. data/test/{rails_app → basepack_test_app}/app/components/author_form.rb +0 -0
  20. data/test/{rails_app → basepack_test_app}/app/components/author_grid.rb +0 -0
  21. data/test/{rails_app → basepack_test_app}/app/components/book_form.rb +3 -2
  22. data/test/{rails_app → basepack_test_app}/app/components/book_form_with_custom_fields.rb +0 -0
  23. data/test/basepack_test_app/app/components/book_form_with_defaults.rb +8 -0
  24. data/test/{rails_app → basepack_test_app}/app/components/book_form_with_nested_attributes.rb +0 -0
  25. data/test/{rails_app → basepack_test_app}/app/components/book_grid.rb +0 -0
  26. data/test/{rails_app → basepack_test_app}/app/components/book_grid_loader.rb +0 -0
  27. data/test/{rails_app → basepack_test_app}/app/components/book_grid_with_custom_columns.rb +0 -0
  28. data/test/{rails_app → basepack_test_app}/app/components/book_grid_with_default_values.rb +0 -0
  29. data/test/{rails_app → basepack_test_app}/app/components/book_grid_with_extra_feedback.rb +0 -0
  30. data/test/{rails_app → basepack_test_app}/app/components/book_grid_with_extra_filters.rb +0 -0
  31. data/test/{rails_app → basepack_test_app}/app/components/book_grid_with_nested_attributes.rb +0 -0
  32. data/test/{rails_app → basepack_test_app}/app/components/book_grid_with_paging.rb +0 -0
  33. data/test/{rails_app → basepack_test_app}/app/components/book_grid_with_persistence.rb +0 -0
  34. data/test/{rails_app → basepack_test_app}/app/components/book_grid_with_scoped_authors.rb +0 -0
  35. data/test/{rails_app → basepack_test_app}/app/components/book_grid_with_virtual_attributes.rb +1 -1
  36. data/test/{rails_app → basepack_test_app}/app/components/book_paging_form_panel.rb +0 -0
  37. data/test/{rails_app → basepack_test_app}/app/components/book_query_builder.rb +0 -0
  38. data/test/{rails_app → basepack_test_app}/app/components/book_search_panel.rb +0 -0
  39. data/test/{rails_app → basepack_test_app}/app/components/book_search_panel/javascripts/i18n_de.js +0 -0
  40. data/test/{rails_app → basepack_test_app}/app/components/book_with_custom_primary_key_grid.rb +0 -0
  41. data/test/{rails_app → basepack_test_app}/app/components/books_bound_to_author.rb +0 -0
  42. data/test/{rails_app → basepack_test_app}/app/components/double_book_grid.rb +0 -0
  43. data/test/basepack_test_app/app/components/extras/book_presentation.rb +20 -0
  44. data/test/{rails_app → basepack_test_app}/app/components/form_without_model.rb +0 -0
  45. data/test/{rails_app → basepack_test_app}/app/components/generic_user_form.rb +0 -0
  46. data/test/{rails_app → basepack_test_app}/app/components/lockable_book_form.rb +0 -0
  47. data/test/{rails_app → basepack_test_app}/app/components/lockable_user_form.rb +0 -0
  48. data/test/{rails_app → basepack_test_app}/app/components/paging_form_with_search.rb +0 -0
  49. data/test/{rails_app → basepack_test_app}/app/components/simple_accordion.rb +0 -0
  50. data/test/{rails_app → basepack_test_app}/app/components/simple_panel.rb +0 -0
  51. data/test/{rails_app → basepack_test_app}/app/components/simple_tab_panel.rb +0 -0
  52. data/test/{rails_app → basepack_test_app}/app/components/simple_window.rb +0 -0
  53. data/test/{rails_app → basepack_test_app}/app/components/simple_wrapper.rb +0 -0
  54. data/test/{rails_app → basepack_test_app}/app/components/some_accordion_panel.rb +0 -0
  55. data/test/{rails_app → basepack_test_app}/app/components/some_auth_app.rb +0 -0
  56. data/test/{rails_app → basepack_test_app}/app/components/some_border_layout.rb +0 -0
  57. data/test/{rails_app → basepack_test_app}/app/components/some_simple_app.rb +0 -0
  58. data/test/{rails_app → basepack_test_app}/app/components/some_tab_panel.rb +0 -0
  59. data/test/{rails_app → basepack_test_app}/app/components/user_form.rb +1 -1
  60. data/test/{rails_app → basepack_test_app}/app/components/user_form_with_default_fields.rb +0 -0
  61. data/test/{rails_app → basepack_test_app}/app/components/user_grid.rb +0 -0
  62. data/test/{rails_app → basepack_test_app}/app/components/user_grid_with_customized_form_fields.rb +0 -0
  63. data/test/{rails_app → basepack_test_app}/app/components/window_component_loader.rb +0 -0
  64. data/test/{rails_app → basepack_test_app}/app/controllers/application_controller.rb +0 -0
  65. data/test/basepack_test_app/app/controllers/components_controller.rb +10 -0
  66. data/test/basepack_test_app/app/controllers/welcome_controller.rb +9 -0
  67. data/test/basepack_test_app/app/helpers/application_helper.rb +8 -0
  68. data/test/{rails_app → basepack_test_app}/app/helpers/embedded_components_helper.rb +0 -0
  69. data/test/{rails_app → basepack_test_app}/app/models/address.rb +0 -0
  70. data/test/{rails_app → basepack_test_app}/app/models/author.rb +0 -0
  71. data/test/{rails_app → basepack_test_app}/app/models/book.rb +0 -0
  72. data/test/{rails_app → basepack_test_app}/app/models/book_with_custom_primary_key.rb +0 -0
  73. data/test/{rails_app → basepack_test_app}/app/models/role.rb +0 -0
  74. data/test/{rails_app → basepack_test_app}/app/models/user.rb +0 -0
  75. data/test/{rails_app → basepack_test_app}/app/presenters/forms/generic_user.rb +0 -0
  76. data/test/{rails_app → basepack_test_app}/app/views/components/loadable_window.html.erb +0 -0
  77. data/test/{rails_app → basepack_test_app}/app/views/components/simple_panel.html.erb +0 -0
  78. data/test/basepack_test_app/app/views/layouts/application.html.erb +12 -0
  79. data/test/{rails_app/app/views/layouts/application.html.erb → basepack_test_app/app/views/layouts/components.html.erb} +0 -0
  80. data/test/{rails_app → basepack_test_app}/app/views/layouts/nested.html.erb +0 -0
  81. data/test/basepack_test_app/app/views/welcome/index.html.erb +10 -0
  82. data/test/{rails_app → basepack_test_app}/config.ru +0 -0
  83. data/test/{rails_app → basepack_test_app}/config/application.rb +7 -0
  84. data/test/{rails_app → basepack_test_app}/config/boot.rb +0 -0
  85. data/test/{rails_app → basepack_test_app}/config/cucumber.yml +0 -0
  86. data/test/{rails_app → basepack_test_app}/config/database.yml.sample +0 -0
  87. data/test/{rails_app → basepack_test_app}/config/environment.rb +0 -0
  88. data/test/{rails_app → basepack_test_app}/config/environments/development.rb +1 -1
  89. data/test/{rails_app → basepack_test_app}/config/environments/production.rb +0 -0
  90. data/test/{rails_app → basepack_test_app}/config/environments/test.rb +0 -0
  91. data/test/{rails_app → basepack_test_app}/config/initializers/backtrace_silencers.rb +0 -1
  92. data/test/{rails_app → basepack_test_app}/config/initializers/inflections.rb +0 -0
  93. data/test/{rails_app → basepack_test_app}/config/initializers/mime_types.rb +0 -0
  94. data/test/{rails_app → basepack_test_app}/config/initializers/netzke.rb +1 -1
  95. data/test/{rails_app → basepack_test_app}/config/initializers/secret_token.rb +0 -0
  96. data/test/{rails_app → basepack_test_app}/config/initializers/session_store.rb +1 -1
  97. data/test/{rails_app → basepack_test_app}/config/locales/de.yml +0 -0
  98. data/test/{rails_app → basepack_test_app}/config/locales/es.yml +0 -0
  99. data/test/{rails_app → basepack_test_app}/config/routes.rb +0 -0
  100. data/test/basepack_test_app/db/development_structure.sql +88 -0
  101. data/test/{rails_app → basepack_test_app}/db/migrate/20100914104207_create_users.rb +0 -0
  102. data/test/{rails_app → basepack_test_app}/db/migrate/20100914104236_create_roles.rb +0 -0
  103. data/test/{rails_app → basepack_test_app}/db/migrate/20101026185816_create_authors.rb +0 -0
  104. data/test/{rails_app → basepack_test_app}/db/migrate/20101026190021_create_books.rb +0 -0
  105. data/test/{rails_app → basepack_test_app}/db/migrate/20110101143818_create_addresses.rb +0 -0
  106. data/test/{rails_app → basepack_test_app}/db/migrate/20110213213050_create_netzke_component_states.rb +0 -0
  107. data/test/{rails_app → basepack_test_app}/db/migrate/20110701070052_create_book_with_custom_primary_keys.rb +0 -0
  108. data/test/basepack_test_app/db/migrate/20110901114016_add_last_read_at_to_books.rb +9 -0
  109. data/test/{rails_app → basepack_test_app}/db/schema.rb +4 -2
  110. data/test/{rails_app → basepack_test_app}/db/seeds.rb +0 -0
  111. data/test/{rails_app → basepack_test_app}/features/accordion_panel.feature +0 -0
  112. data/test/{rails_app → basepack_test_app}/features/components_in_view.feature +0 -0
  113. data/test/{rails_app → basepack_test_app}/features/form_panel.feature +15 -0
  114. data/test/{rails_app → basepack_test_app}/features/grid_panel.feature +0 -0
  115. data/test/{rails_app → basepack_test_app}/features/grid_panel_with_custom_primary_key.feature +0 -0
  116. data/test/basepack_test_app/features/grid_sorting.feature +39 -0
  117. data/test/{rails_app → basepack_test_app}/features/i18n.feature +0 -0
  118. data/test/{rails_app → basepack_test_app}/features/nested_attributes.feature +0 -0
  119. data/test/{rails_app → basepack_test_app}/features/paging_form_panel.feature +0 -1
  120. data/test/{rails_app → basepack_test_app}/features/search_in_grid.feature +0 -0
  121. data/test/{rails_app → basepack_test_app}/features/simple_app.feature +0 -0
  122. data/test/{rails_app → basepack_test_app}/features/simple_panel.feature +0 -0
  123. data/test/{rails_app → basepack_test_app}/features/step_definitions/accordion_steps.rb +0 -0
  124. data/test/{rails_app → basepack_test_app}/features/step_definitions/ext_steps.rb +0 -0
  125. data/test/{rails_app → basepack_test_app}/features/step_definitions/form_panel_steps.rb +4 -7
  126. data/test/{rails_app → basepack_test_app}/features/step_definitions/generic_steps.rb +0 -0
  127. data/test/{rails_app → basepack_test_app}/features/step_definitions/grid_panel_steps.rb +28 -5
  128. data/test/{rails_app → basepack_test_app}/features/step_definitions/pickle_steps.rb +0 -0
  129. data/test/{rails_app → basepack_test_app}/features/step_definitions/web_steps.rb +0 -0
  130. data/test/{rails_app → basepack_test_app}/features/support/env.rb +2 -5
  131. data/test/{rails_app → basepack_test_app}/features/support/paths.rb +0 -0
  132. data/test/{rails_app → basepack_test_app}/features/support/pickle.rb +0 -0
  133. data/test/{rails_app → basepack_test_app}/features/support/selectors.rb +0 -0
  134. data/test/{rails_app → basepack_test_app}/features/tab_panel.feature +0 -0
  135. data/test/{rails_app → basepack_test_app}/features/validations_in_grid.feature +0 -0
  136. data/test/{rails_app → basepack_test_app}/features/virtual_attributes.feature +0 -0
  137. data/test/{rails_app → basepack_test_app}/features/window.feature +0 -0
  138. data/test/{rails_app → basepack_test_app}/lib/tasks/.gitkeep +0 -0
  139. data/test/{rails_app → basepack_test_app}/lib/tasks/cucumber.rake +0 -0
  140. data/test/{rails_app → basepack_test_app}/public/404.html +0 -0
  141. data/test/{rails_app → basepack_test_app}/public/422.html +0 -0
  142. data/test/{rails_app → basepack_test_app}/public/500.html +0 -0
  143. data/test/{rails_app → basepack_test_app}/public/favicon.ico +0 -0
  144. data/test/{rails_app → basepack_test_app}/public/images/header-deco.gif +0 -0
  145. data/test/{rails_app → basepack_test_app}/public/images/rails.png +0 -0
  146. data/test/{rails_app → basepack_test_app}/public/javascripts/application.js +0 -0
  147. data/test/{rails_app → basepack_test_app}/public/javascripts/controls.js +0 -0
  148. data/test/{rails_app → basepack_test_app}/public/javascripts/dragdrop.js +0 -0
  149. data/test/{rails_app → basepack_test_app}/public/javascripts/effects.js +0 -0
  150. data/test/{rails_app → basepack_test_app}/public/javascripts/prototype.js +0 -0
  151. data/test/{rails_app → basepack_test_app}/public/javascripts/rails.js +0 -0
  152. data/test/{rails_app → basepack_test_app}/public/robots.txt +0 -0
  153. data/test/{rails_app → basepack_test_app}/public/stylesheets/.gitkeep +0 -0
  154. data/test/{rails_app → basepack_test_app}/script/cucumber +0 -0
  155. data/test/{rails_app → basepack_test_app}/script/rails +0 -0
  156. data/test/{rails_app → basepack_test_app}/spec/active_record/attributes_spec.rb +0 -0
  157. data/test/{rails_app → basepack_test_app}/spec/active_record/relation_extensions_spec.rb +0 -0
  158. data/test/{rails_app → basepack_test_app}/spec/components/form_panel_spec.rb +0 -0
  159. data/test/{rails_app → basepack_test_app}/spec/components/grid_panel_spec.rb +0 -0
  160. data/test/{rails_app → basepack_test_app}/spec/factories.rb +0 -0
  161. data/test/{rails_app → basepack_test_app}/spec/spec_helper.rb +0 -0
  162. data/test/{rails_app → basepack_test_app}/test/performance/browsing_test.rb +0 -0
  163. data/test/{rails_app → basepack_test_app}/test/test_helper.rb +0 -0
  164. data/test/{rails_app → basepack_test_app}/vendor/plugins/.gitkeep +0 -0
  165. metadata +198 -207
  166. data/test/rails_app/app/components/book_presentation.rb +0 -18
  167. data/test/rails_app/app/controllers/components_controller.rb +0 -6
  168. data/test/rails_app/app/controllers/welcome_controller.rb +0 -5
  169. data/test/rails_app/app/helpers/application_helper.rb +0 -2
data/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,11 @@
1
+ = 0.7.1 - 2011-09-04
2
+ * bug fix
3
+ * fixing the netzke_load endpoint when association fields are present
4
+ * dates were not displayed in date fields, and submitting a form with date fields might result in erasing those fields
5
+
6
+ * Rails 3.1 compatibility
7
+ * no meta_where dependencies (searching and filtering done with Arel)
8
+
1
9
  = 0.7.0 - 2011-08-09
2
10
  * Core 0.7.0 and Ext 4 compatibility
3
11
  * API changes
@@ -6,7 +14,7 @@
6
14
  = v0.6.5 - to be released
7
15
  * enhancements
8
16
  * When columns states are saved in the persistent storage, adding/removing columns (e.g. in the code) will reset the saved states
9
- * Moved features and specs to test/rails_app
17
+ * Moved features and specs to test/basepack_test_app
10
18
  * bug fix
11
19
  * FormPanel with multiple association fields wouldn't submit data correctly
12
20
  * GridPanel's forms take over the +text+ configuration option for columns as +fieldLabel+ for default fields
data/README.md CHANGED
@@ -24,7 +24,7 @@ Embed a basepack component into a view as any other Netzke component, e.g.:
24
24
 
25
25
  <%= netzke :books, :class_name => 'Netzke::Basepack::GridPanel', :model => 'Book' %>
26
26
 
27
- For more examples, see http://demo.netzke.com, and look into test/rails_app.
27
+ For more examples, see http://demo.netzke.com, and look into test/basepack_test_app.
28
28
 
29
29
  ## Testing and playing with Netzke Basepack
30
30
 
@@ -32,13 +32,9 @@ Netzke Basepack is bundled with Cucumber and RSpec tests. If you would like to c
32
32
 
33
33
  Besides, the bundled test application is a convenient [playground](https://github.com/skozlov/netzke-core/wiki/Playground) for those who search to experiment with the framework.
34
34
 
35
- After setting up the test application, you can access the test components (from test/rails_app/app/components) like this:
35
+ After starting up the test app, you can see the list of functional test components on the index page (along with links to the source code):
36
36
 
37
- http://localhost:3000/components/<name_of_the_test_component_class>
38
-
39
- e.g.:
40
-
41
- http://localhost:3000/components/UserGrid
37
+ http://localhost:3000/
42
38
 
43
39
  ## Icons support
44
40
  Netzke Basepack can make use of FamFamFam Silk icon set (http://www.famfamfam.com/archive/silk-icons-thats-your-lot/). To enable this, download the icons and put the "icons" folder into your app's public/images folder. Then restart your application.
@@ -55,9 +51,10 @@ Official project site: http://netzke.org
55
51
  Twitter:
56
52
 
57
53
  * latest news about Netzke: http://twitter.com/netzke
58
- * author's rambling about osx, productivity and what not: http://twitter.com/nomadcoder
54
+ * author's tweets on osx, productivity and what not: http://twitter.com/nomadcoder
59
55
 
60
56
  Many (if a bit outdated) tutorials: http://blog.writelesscode.com
61
57
 
62
58
  ---
63
59
  Copyright (c) 2008-2011 NomadCoder, released under the MIT license
60
+ Note, that Ext JS itself is licensed [differently](http://www.sencha.com/products/extjs/license/)
data/Rakefile CHANGED
@@ -10,7 +10,6 @@ begin
10
10
  gemspec.homepage = "http://netzke.org"
11
11
  gemspec.authors = ["Sergei Kozlov"]
12
12
  gemspec.add_dependency("netzke-core", "~>0.7.0")
13
- gemspec.add_dependency("meta_where", "~>1.0.0")
14
13
  gemspec.add_dependency("will_paginate", "~>3.0.0")
15
14
  gemspec.add_dependency("acts_as_list", "~>0.1.4")
16
15
  gemspec.post_install_message = <<-MESSAGE
@@ -104,10 +104,10 @@ module Netzke
104
104
  c = {:name => name, :attr_type => columns_hash[name].type}
105
105
 
106
106
  # If it's named as foreign key of some association, then it's an association column
107
- assoc = reflect_on_all_associations.detect{|a| a.primary_key_name == c[:name]}
107
+ assoc = reflect_on_all_associations.detect { |a| foreign_key_for_assoc(a) == c[:name] }
108
108
 
109
109
  if assoc && !assoc.options[:polymorphic]
110
- candidates = %w{name title label} << assoc.primary_key_name
110
+ candidates = %w{name title label} << foreign_key_for_assoc(assoc)
111
111
  assoc_method = candidates.detect{|m| (assoc.klass.instance_methods.map(&:to_s) + assoc.klass.column_names).include?(m) }
112
112
  c[:name] = "#{assoc.name}__#{assoc_method}"
113
113
  c[:attr_type] = assoc.klass.columns_hash[assoc_method].try(:type) || :string # when it's an instance method rather than a column, fall back to :string
@@ -127,6 +127,11 @@ module Netzke
127
127
  ).reject { |attr| netzke_excluded_attributes.include?(attr[:name]) }
128
128
  end
129
129
 
130
+ # Returns foreign key for given association (Rails >= 3.0)
131
+ def foreign_key_for_assoc(assoc)
132
+ assoc.respond_to?(:foreign_key) ? assoc.foreign_key : assoc.primary_key_name
133
+ end
134
+
130
135
  def association_attr?(attr_name)
131
136
  !!attr_name.index("__") # probably we can't do much better than this, as we don't know at this moment if the associated model has a specific attribute, and we don't really want to find it out
132
137
  end
@@ -169,7 +174,7 @@ module Netzke
169
174
  if r.respond_to?(m)
170
175
  r.send(m)
171
176
  else
172
- logger.debug "!!! Netzke::Basepack: Wrong attribute name: #{a[:name]}" unless r.nil?
177
+ logger.debug "Netzke::Basepack: Wrong attribute name: #{a[:name]}" unless r.nil?
173
178
  nil
174
179
  end
175
180
  end
@@ -180,11 +185,14 @@ module Netzke
180
185
 
181
186
  # a work-around for to_json not taking the current timezone into account when serializing ActiveSupport::TimeWithZone
182
187
  v = v.to_datetime.to_s(:db) if v.is_a?(ActiveSupport::TimeWithZone)
188
+
183
189
  v
184
190
  end
185
191
 
186
192
  # Assigns new value to an (association) attribute
187
193
  def set_value_for_attribute(a, v)
194
+ v = v.to_time_in_current_zone if v.is_a?(Date) # convert Date to Time
195
+
188
196
  if a[:setter]
189
197
  a[:setter].call(self, v)
190
198
  elsif respond_to?("#{a[:name]}=")
@@ -215,10 +223,10 @@ module Netzke
215
223
  self.send("#{assoc.options[:foreign_key] || assoc.name.to_s.foreign_key}=", v)
216
224
  end
217
225
  else
218
- logger.debug "!!! Netzke::Basepack: Association #{assoc} is not known for class #{self.class.name}"
226
+ logger.debug "Netzke::Basepack: Association #{assoc} is not known for class #{self.class.name}"
219
227
  end
220
228
  else
221
- logger.debug "!!! Netzke::Basepack: Wrong attribute name: #{a[:name]}"
229
+ logger.debug "Netzke::Basepack: Wrong attribute name: #{a[:name]}"
222
230
  end
223
231
  end
224
232
  end
@@ -2,7 +2,6 @@ require 'netzke/basepack/version'
2
2
 
3
3
  if defined? ActiveRecord
4
4
  require 'netzke/active_record'
5
- require 'meta_where'
6
5
  end
7
6
 
8
7
  # will_paginate supports more than just ActiveRecord
@@ -108,57 +108,116 @@ module Netzke
108
108
  end
109
109
 
110
110
  # An ActiveRecord::Relation instance encapsulating all the necessary conditions.
111
- # Using the meta_where magic.
112
111
  def get_relation(params = {})
113
- # make params coming from Ext grid filters understandable by meta_where
114
- conditions = params[:filter] && convert_filters(params[:filter]) || {}
112
+ @arel = data_class.arel_table
115
113
 
116
- relation = data_class.where(conditions)
114
+ relation = data_class.scoped
115
+
116
+ relation = apply_column_filters(relation, params[:filter]) if params[:filter]
117
117
 
118
118
  if params[:extra_conditions]
119
119
  extra_conditions = normalize_extra_conditions(ActiveSupport::JSON.decode(params[:extra_conditions]))
120
120
  relation = relation.extend_with_netzke_conditions(extra_conditions) if params[:extra_conditions]
121
121
  end
122
122
 
123
- if params[:query]
123
+ query = params[:query] && ActiveSupport::JSON.decode(params[:query])
124
+
125
+ if query.present?
124
126
  # array of arrays of conditions that should be joined by OR
125
- query = ActiveSupport::JSON.decode(params[:query])
126
- meta_where = query.map do |conditions|
127
- normalize_and_conditions(conditions)
127
+ and_predicates = query.map do |conditions|
128
+ predicates_for_and_conditions(conditions)
128
129
  end
129
130
 
130
131
  # join them by OR
131
- meta_where = meta_where.inject(meta_where.first){ |r,c| r | c } if meta_where.present?
132
+ predicates = and_predicates[1..-1].inject(and_predicates.first){ |r,c| r.or(c) }
132
133
  end
133
134
 
134
- relation = relation.where(meta_where)
135
+ relation = relation.where(predicates)
135
136
 
136
137
  relation = relation.extend_with(config[:scope]) if config[:scope]
137
138
 
138
139
  relation
139
140
  end
140
141
 
142
+ # Parses and applies grid column filters, calling consequent "where" methods on the passed relation.
143
+ # Returns the updated relation.
144
+ #
145
+ # Example column grid data:
146
+ #
147
+ # {"0" => {
148
+ # "data" => {
149
+ # "type" => "numeric",
150
+ # "comparison" => "gt",
151
+ # "value" => 10 },
152
+ # "field" => "id"
153
+ # },
154
+ # "1" => {
155
+ # "data" => {
156
+ # "type" => "string",
157
+ # "value" => "pizza"
158
+ # },
159
+ # "field" => "food_name"
160
+ # }}
161
+ #
162
+ # This will result in:
163
+ #
164
+ # relation.where(["id > ?", 10]).where(["food_name like ?", "%pizza%"])
165
+ def apply_column_filters(relation, column_filter)
166
+ res = relation
167
+ operator_map = {"lt" => "<", "gt" => ">"}
168
+
169
+ # these are still JSON-encoded due to the migration to Ext.direct
170
+ column_filter=JSON.parse(column_filter)
171
+ column_filter.each do |v|
172
+ assoc, method = v["field"].split('__')
173
+ if method
174
+ assoc = data_class.reflect_on_association(assoc.to_sym)
175
+ field = [assoc.klass.table_name, method].join('.').to_sym
176
+ else
177
+ field = assoc.to_sym
178
+ end
179
+
180
+ value = v["value"]
181
+
182
+ op = operator_map[v['comparison']]
183
+
184
+ case v["type"]
185
+ when "string"
186
+ res = res.where(["#{field} like ?", "%#{value}%"])
187
+ when "numeric", "date"
188
+ res = res.where(["#{field} #{op} ?", value])
189
+ else
190
+ res = res.where(["#{field} = ?", value])
191
+ end
192
+ end
193
+
194
+ res
195
+ end
196
+
197
+
141
198
  protected
142
199
 
143
- def normalize_and_conditions(conditions)
144
- and_conditions = conditions.map do |q|
200
+ def predicates_for_and_conditions(conditions)
201
+ return nil if conditions.empty?
202
+
203
+ predicates = conditions.map do |q|
145
204
  value = q["value"]
146
205
  case q["operator"]
147
206
  when "contains"
148
- q["attr"].to_sym.matches % %Q{%#{value}%}
207
+ @arel[q["attr"]].matches "%#{value}%"
149
208
  else
150
209
  if value == false || value == true
151
- q["attr"].to_sym.eq % (value ? 1 : 0)
210
+ @arel[q["attr"]].eq(value ? 1 : 0)
152
211
  else
153
- q["attr"].to_sym.send(q["operator"]) % value
212
+ @arel[q["attr"]].send(q["operator"], value)
154
213
  end
155
214
  end
156
215
  end
157
216
 
158
217
  # join them by AND
159
- and_conditions.inject(and_conditions.first){ |r,c| r & c } if and_conditions.present?
218
+ predicates[1..-1].inject(predicates.first){ |r,p| r.and(p) }
160
219
  end
161
220
 
162
221
  end
163
222
  end
164
- end
223
+ end
@@ -6,7 +6,8 @@ module Netzke
6
6
  module Basepack
7
7
  # Ext.form.Panel-based component
8
8
  #
9
- # == Configuration
9
+ # == Netzke-specific config options
10
+ #
10
11
  # * +model+ - name of the ActiveRecord model that provides data to this GridPanel.
11
12
  # * +record+ - record to be displayd in the form. Takes precedence over +:record_id+
12
13
  # * +record_id+ - id of the record to be displayd in the form. Also see +:record+
@@ -14,10 +15,20 @@ module Netzke
14
15
  # * +mode+ - render mode, accepted options:
15
16
  # * +lockable+ - makes the form panel load initially in "display mode", then lets "unlock" it, change the values, and "lock" it again, while updating the values on the server
16
17
  # * +updateMask+ - +Ext.LoadMask+ config options for the mask shown while the form is submitting its values
17
- # Besides, FormPanel can accept any meaninful :
18
18
  #
19
19
  # === Layout configuration
20
+ #
20
21
  # The layout of the form is configured by supplying the +item+ config option, same way it would be configured in Ext (thus allowing for complex form layouts). FormPanel will expand fields by looking at their names (unless +no_binding+ set to +true+ is specified for a specific field).
22
+ #
23
+ # == Endpoints
24
+ # FormPanel implements the following endpoints:
25
+ #
26
+ # * +netzke_load+ - loads a record with a given id from the server, e.g.:
27
+ #
28
+ # someFormPanel.netzkeLoad({id: 100});
29
+ #
30
+ # * +netzke_submit+ - gets called when the form gets submitted (e.g. by pressing the Apply button, or by calling onApply)
31
+ # * +get_combobox_options+ - gets called when a 'remote' combobox field gets expanded
21
32
  class FormPanel < Netzke::Base
22
33
 
23
34
  js_base_class "Ext.form.Panel"
@@ -94,44 +105,22 @@ module Netzke
94
105
 
95
106
  # A hash of record data including the meta field
96
107
  def js_record_data
97
- record.to_hash(fields).merge(:_meta => meta_field).literalize_keys
108
+ hsh = record.to_hash(fields).merge(:_meta => meta_field).literalize_keys
109
+
110
+ # HACK: a dirty hack cutting off the time part from the datetime string to please the form's datefield - until we have a real datetimefield
111
+ hsh.each_pair do |k,v|
112
+ if v && [:datetime, :date].include?(fields[k.to_sym].try(:fetch, :attr_type, nil))
113
+ hsh[k] = v.split.first
114
+ end
115
+ end
116
+
117
+ hsh
98
118
  end
99
119
 
100
120
  def record
101
121
  @record ||= config[:record] || config[:record_id] && data_class && data_class.where(data_class.primary_key => config[:record_id]).first
102
122
  end
103
123
 
104
- # def configuration_components
105
- # res = []
106
- #
107
- # res << {
108
- # :name => 'fields',
109
- # :class_name => "FieldsConfigurator",
110
- # :active => true,
111
- # :owner => self,
112
- # :persistent_config => true
113
- # }
114
- #
115
- # res << {
116
- # :name => 'general',
117
- # :class_name => "PropertyEditor",
118
- # :component => self,
119
- # :title => false
120
- # }
121
- #
122
- # res
123
- # end
124
-
125
- def self.property_fields
126
- res = [
127
- {:name => "ext_config__title", :attr_type => :string},
128
- {:name => "ext_config__header", :attr_type => :boolean, :default => true},
129
- {:name => "ext_config__bbar", :attr_type => :json}
130
- ]
131
-
132
- res
133
- end
134
-
135
124
  private
136
125
 
137
126
  def self.server_side_config_options
@@ -100,6 +100,12 @@ module Netzke
100
100
  set_default_field_xtype(field) if field[:xtype].nil?
101
101
  set_default_read_only(field)
102
102
 
103
+ # temporal datetime setup, while we don't have real datetime field
104
+ if field[:attr_type] == :datetime || field[:attr_type] == :date
105
+ field[:format] ||= "Y-m-d" # needed for
106
+ field[:submit_format] = "Y-m-d"
107
+ end
108
+
103
109
  # provide our special combobox with our id
104
110
  field[:parent_id] = self.global_id if field[:xtype] == :netzkeremotecombo
105
111
 
@@ -183,6 +189,7 @@ module Netzke
183
189
  :date => :datefield,
184
190
  # WIP: waiting for datetime.js implementation for ExtJS 4
185
191
  # :datetime => :datetimefield,
192
+ :datetime => :datefield,
186
193
 
187
194
  :text => :textarea,
188
195
  :json => :jsonfield,
@@ -8,14 +8,18 @@ module Netzke
8
8
 
9
9
  #
10
10
  # Endpoints
11
- #
11
+
12
+ # Called when the form gets submitted (e.g. by pressing the Apply button)
12
13
  endpoint :netzke_submit, :pre => true do |params|
13
14
  netzke_submit(params)
14
15
  end
15
16
 
17
+ # Can be called when the form needs to load a record with given ID. E.g.:
18
+ #
19
+ # someForm.netzkeLoad({id: 100});
16
20
  endpoint :netzke_load do |params|
17
21
  @record = data_class && data_class.find_by_id(params[:id])
18
- {:set_form_values => @record.to_hash(fields)}
22
+ {:set_form_values => js_record_data}
19
23
  end
20
24
 
21
25
  # Returns options for a combobox
@@ -98,7 +102,6 @@ module Netzke
98
102
 
99
103
  # Creates/updates a record from hash
100
104
  def create_or_update_record(hsh)
101
-
102
105
  hsh.merge!(config[:strong_default_attrs]) if config[:strong_default_attrs]
103
106
  @record ||= data_class.find(:first, :conditions => {data_class.primary_key => hsh.delete(data_class.primary_key)}) # only pick up the record specified in the params if it was not provided in the configuration
104
107
  success = true
@@ -214,10 +214,10 @@ module Netzke
214
214
  relation = relation.send(column[:sorting_scope].to_sym, dir.to_sym)
215
215
  else
216
216
  relation = if method.nil?
217
- relation.order(assoc.to_sym.send(dir))
217
+ relation.order("#{assoc} #{dir}")
218
218
  else
219
219
  assoc = data_class.reflect_on_association(assoc.to_sym)
220
- relation.order(assoc.klass.table_name.to_sym => method.to_sym.send(dir)).joins(assoc.name)
220
+ relation.joins(assoc.name).order("#{assoc.klass.table_name}.#{method} #{dir}")
221
221
  end
222
222
  end
223
223
  end
@@ -298,53 +298,6 @@ module Netzke
298
298
  mod_records
299
299
  end
300
300
 
301
- # Converts Ext.ux.grid.GridFilters filters to searchlogic conditions, e.g.
302
- # {"0" => {
303
- # "data" => {
304
- # "type" => "numeric",
305
- # "comparison" => "gt",
306
- # "value" => 10 },
307
- # "field" => "id"
308
- # },
309
- # "1" => {
310
- # "data" => {
311
- # "type" => "string",
312
- # "value" => "pizza"
313
- # },
314
- # "field" => "food_name"
315
- # }}
316
- #
317
- # =>
318
- #
319
- # metawhere: :id.gt => 100, :food_name.matches => '%pizza%'
320
- def convert_filters(column_filter)
321
- # these are still JSON-encoded due to the migration to Ext.direct
322
- column_filter=JSON.parse(column_filter)
323
- res = {}
324
- column_filter.each do |v|
325
- assoc, method = v["field"].split('__')
326
- if method
327
- assoc = data_class.reflect_on_association(assoc.to_sym)
328
- field = [assoc.klass.table_name, method].join('.').to_sym
329
- else
330
- field = assoc.to_sym
331
- end
332
-
333
- value = v["value"]
334
-
335
- case v["type"]
336
- when "string"
337
- op = v['comparison'] && (v['comparison'] == 'like' ? :matches : :does_not_match) || :matches
338
- field = field.send(op)
339
- value = "%#{value}%"
340
- when "numeric", "date"
341
- field = field.send :"#{v['comparison']}"
342
- end
343
- res.merge!({field => value})
344
- end
345
- res
346
- end
347
-
348
301
  def normalize_extra_conditions(conditions)
349
302
  conditions.each_pair do |k,v|
350
303
  conditions[k] = "%#{v}%" if ["like", "matches"].include?(k.to_s.split("__").last)