netzke-basepack-zh 0.7.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (268) hide show
  1. data/.autotest +1 -0
  2. data/.travis.yml +11 -0
  3. data/CHANGELOG.rdoc +445 -0
  4. data/LICENSE +1 -0
  5. data/README.md +94 -0
  6. data/Rakefile +44 -0
  7. data/TODO.rdoc +8 -0
  8. data/config/ci/before-travis.sh +28 -0
  9. data/init.rb +1 -0
  10. data/install.rb +1 -0
  11. data/javascripts/basepack.js +139 -0
  12. data/javascripts/xdatetime.js +196 -0
  13. data/lib/generators/netzke/basepack_generator.rb +10 -0
  14. data/lib/generators/netzke/templates/assets/ts-checkbox.gif +0 -0
  15. data/lib/generators/netzke/templates/create_netzke_field_lists.rb +18 -0
  16. data/lib/netzke-basepack.rb +26 -0
  17. data/lib/netzke/active_record.rb +20 -0
  18. data/lib/netzke/active_record/attributes.rb +256 -0
  19. data/lib/netzke/active_record/combobox_options.rb +16 -0
  20. data/lib/netzke/active_record/relation_extensions.rb +37 -0
  21. data/lib/netzke/basepack.rb +45 -0
  22. data/lib/netzke/basepack/accordion_panel.rb +39 -0
  23. data/lib/netzke/basepack/action_column.rb +68 -0
  24. data/lib/netzke/basepack/action_column/javascripts/action_column.js +61 -0
  25. data/lib/netzke/basepack/auth_app.rb +159 -0
  26. data/lib/netzke/basepack/basic_app.rb +7 -0
  27. data/lib/netzke/basepack/border_layout_panel.rb +53 -0
  28. data/lib/netzke/basepack/border_layout_panel/javascripts/border_layout_panel.js +40 -0
  29. data/lib/netzke/basepack/data_accessor.rb +53 -0
  30. data/lib/netzke/basepack/data_adapters/abstract_adapter.rb +164 -0
  31. data/lib/netzke/basepack/data_adapters/active_record_adapter.rb +279 -0
  32. data/lib/netzke/basepack/data_adapters/data_mapper_adapter.rb +264 -0
  33. data/lib/netzke/basepack/data_adapters/sequel_adapter.rb +260 -0
  34. data/lib/netzke/basepack/form_panel.rb +144 -0
  35. data/lib/netzke/basepack/form_panel/fields.rb +208 -0
  36. data/lib/netzke/basepack/form_panel/javascripts/comma_list_cbg.js +51 -0
  37. data/lib/netzke/basepack/form_panel/javascripts/form_panel.js +225 -0
  38. data/lib/netzke/basepack/form_panel/javascripts/misc.js +4 -0
  39. data/lib/netzke/basepack/form_panel/javascripts/n_radio_group.js +43 -0
  40. data/lib/netzke/basepack/form_panel/javascripts/readonly_mode.js +35 -0
  41. data/lib/netzke/basepack/form_panel/services.rb +142 -0
  42. data/lib/netzke/basepack/form_panel/stylesheets/readonly_mode.css +14 -0
  43. data/lib/netzke/basepack/grid_panel.rb +440 -0
  44. data/lib/netzke/basepack/grid_panel/columns.rb +394 -0
  45. data/lib/netzke/basepack/grid_panel/javascripts/advanced_search.js +27 -0
  46. data/lib/netzke/basepack/grid_panel/javascripts/check_column_fix.js +6 -0
  47. data/lib/netzke/basepack/grid_panel/javascripts/edit_in_form.js +51 -0
  48. data/lib/netzke/basepack/grid_panel/javascripts/event_handling.js +179 -0
  49. data/lib/netzke/basepack/grid_panel/javascripts/grid_panel.js +438 -0
  50. data/lib/netzke/basepack/grid_panel/javascripts/misc.js +4 -0
  51. data/lib/netzke/basepack/grid_panel/javascripts/rows-dd.js +281 -0
  52. data/lib/netzke/basepack/grid_panel/record_form_window.rb +41 -0
  53. data/lib/netzke/basepack/grid_panel/services.rb +235 -0
  54. data/lib/netzke/basepack/paging_form_panel.rb +72 -0
  55. data/lib/netzke/basepack/paging_form_panel/javascripts/paging_form_panel.js +76 -0
  56. data/lib/netzke/basepack/panel.rb +11 -0
  57. data/lib/netzke/basepack/query_builder.rb +107 -0
  58. data/lib/netzke/basepack/query_builder/javascripts/query_builder.js +153 -0
  59. data/lib/netzke/basepack/search_panel.rb +79 -0
  60. data/lib/netzke/basepack/search_panel/javascripts/condition_field.js +160 -0
  61. data/lib/netzke/basepack/search_panel/javascripts/search_panel.js +65 -0
  62. data/lib/netzke/basepack/search_window.rb +66 -0
  63. data/lib/netzke/basepack/simple_app.rb +104 -0
  64. data/lib/netzke/basepack/simple_app/javascripts/simple_app.js +64 -0
  65. data/lib/netzke/basepack/simple_app/javascripts/statusbar_ext.js +8 -0
  66. data/lib/netzke/basepack/tab_panel.rb +21 -0
  67. data/lib/netzke/basepack/tab_panel/javascripts/tab_panel.js +11 -0
  68. data/lib/netzke/basepack/version.rb +11 -0
  69. data/lib/netzke/basepack/window.rb +29 -0
  70. data/lib/netzke/basepack/window/javascripts/window.js +20 -0
  71. data/lib/netzke/basepack/wrap_lazy_loaded.rb +28 -0
  72. data/lib/netzke/basepack/wrapper.rb +28 -0
  73. data/lib/netzke/data_mapper.rb +18 -0
  74. data/lib/netzke/data_mapper/attributes.rb +273 -0
  75. data/lib/netzke/data_mapper/combobox_options.rb +11 -0
  76. data/lib/netzke/data_mapper/relation_extensions.rb +38 -0
  77. data/lib/netzke/sequel.rb +18 -0
  78. data/lib/netzke/sequel/attributes.rb +274 -0
  79. data/lib/netzke/sequel/combobox_options.rb +10 -0
  80. data/lib/netzke/sequel/relation_extensions.rb +40 -0
  81. data/lib/tasks/netzke_basepack_tasks.rake +4 -0
  82. data/locales/de.yml +79 -0
  83. data/locales/en.yml +79 -0
  84. data/netzke-basepack.gemspec +306 -0
  85. data/stylesheets/basepack.css +72 -0
  86. data/stylesheets/datetimefield.css +54 -0
  87. data/test/basepack_test_app/.gitignore +6 -0
  88. data/test/basepack_test_app/.rvmrc +1 -0
  89. data/test/basepack_test_app/Gemfile +59 -0
  90. data/test/basepack_test_app/Gemfile.lock +196 -0
  91. data/test/basepack_test_app/Guardfile +46 -0
  92. data/test/basepack_test_app/README +1 -0
  93. data/test/basepack_test_app/Rakefile +7 -0
  94. data/test/basepack_test_app/app/components/author_form.rb +32 -0
  95. data/test/basepack_test_app/app/components/author_grid.rb +3 -0
  96. data/test/basepack_test_app/app/components/book_form.rb +38 -0
  97. data/test/basepack_test_app/app/components/book_form_with_custom_fields.rb +21 -0
  98. data/test/basepack_test_app/app/components/book_form_with_defaults.rb +8 -0
  99. data/test/basepack_test_app/app/components/book_form_with_nested_attributes.rb +18 -0
  100. data/test/basepack_test_app/app/components/book_grid.rb +12 -0
  101. data/test/basepack_test_app/app/components/book_grid_filtering.rb +10 -0
  102. data/test/basepack_test_app/app/components/book_grid_loader.rb +24 -0
  103. data/test/basepack_test_app/app/components/book_grid_with_column_actions.rb +15 -0
  104. data/test/basepack_test_app/app/components/book_grid_with_custom_columns.rb +27 -0
  105. data/test/basepack_test_app/app/components/book_grid_with_default_values.rb +9 -0
  106. data/test/basepack_test_app/app/components/book_grid_with_extra_feedback.rb +8 -0
  107. data/test/basepack_test_app/app/components/book_grid_with_extra_filters.rb +14 -0
  108. data/test/basepack_test_app/app/components/book_grid_with_nested_attributes.rb +13 -0
  109. data/test/basepack_test_app/app/components/book_grid_with_overridden_columns.rb +15 -0
  110. data/test/basepack_test_app/app/components/book_grid_with_paging.rb +10 -0
  111. data/test/basepack_test_app/app/components/book_grid_with_persistence.rb +8 -0
  112. data/test/basepack_test_app/app/components/book_grid_with_scoped_authors.rb +8 -0
  113. data/test/basepack_test_app/app/components/book_grid_with_virtual_attributes.rb +21 -0
  114. data/test/basepack_test_app/app/components/book_paging_form_panel.rb +22 -0
  115. data/test/basepack_test_app/app/components/book_query_builder.rb +8 -0
  116. data/test/basepack_test_app/app/components/book_search_panel.rb +5 -0
  117. data/test/basepack_test_app/app/components/book_search_panel/javascripts/i18n_de.js +6 -0
  118. data/test/basepack_test_app/app/components/book_with_custom_primary_key_grid.rb +10 -0
  119. data/test/basepack_test_app/app/components/books_bound_to_author.rb +10 -0
  120. data/test/basepack_test_app/app/components/double_book_grid.rb +18 -0
  121. data/test/basepack_test_app/app/components/extras/book_presentation.rb +27 -0
  122. data/test/basepack_test_app/app/components/form_without_model.rb +21 -0
  123. data/test/basepack_test_app/app/components/generic_user_form.rb +12 -0
  124. data/test/basepack_test_app/app/components/lockable_book_form.rb +17 -0
  125. data/test/basepack_test_app/app/components/lockable_user_form.rb +7 -0
  126. data/test/basepack_test_app/app/components/paging_form_with_search.rb +40 -0
  127. data/test/basepack_test_app/app/components/simple_accordion.rb +11 -0
  128. data/test/basepack_test_app/app/components/simple_panel.rb +17 -0
  129. data/test/basepack_test_app/app/components/simple_tab_panel.rb +11 -0
  130. data/test/basepack_test_app/app/components/simple_window.rb +10 -0
  131. data/test/basepack_test_app/app/components/simple_wrapper.rb +7 -0
  132. data/test/basepack_test_app/app/components/some_accordion_panel.rb +22 -0
  133. data/test/basepack_test_app/app/components/some_auth_app.rb +32 -0
  134. data/test/basepack_test_app/app/components/some_border_layout.rb +28 -0
  135. data/test/basepack_test_app/app/components/some_simple_app.rb +35 -0
  136. data/test/basepack_test_app/app/components/some_tab_panel.rb +20 -0
  137. data/test/basepack_test_app/app/components/user_form.rb +25 -0
  138. data/test/basepack_test_app/app/components/user_form_with_default_fields.rb +8 -0
  139. data/test/basepack_test_app/app/components/user_grid.rb +8 -0
  140. data/test/basepack_test_app/app/components/user_grid_with_customized_form_fields.rb +18 -0
  141. data/test/basepack_test_app/app/components/window_component_loader.rb +27 -0
  142. data/test/basepack_test_app/app/controllers/application_controller.rb +9 -0
  143. data/test/basepack_test_app/app/controllers/components_controller.rb +10 -0
  144. data/test/basepack_test_app/app/controllers/welcome_controller.rb +9 -0
  145. data/test/basepack_test_app/app/helpers/application_helper.rb +8 -0
  146. data/test/basepack_test_app/app/helpers/embedded_components_helper.rb +2 -0
  147. data/test/basepack_test_app/app/models/address.rb +29 -0
  148. data/test/basepack_test_app/app/models/author.rb +38 -0
  149. data/test/basepack_test_app/app/models/book.rb +49 -0
  150. data/test/basepack_test_app/app/models/book_with_custom_primary_key.rb +26 -0
  151. data/test/basepack_test_app/app/models/role.rb +24 -0
  152. data/test/basepack_test_app/app/models/user.rb +29 -0
  153. data/test/basepack_test_app/app/presenters/forms/generic_user.rb +6 -0
  154. data/test/basepack_test_app/app/views/components/loadable_window.html.erb +9 -0
  155. data/test/basepack_test_app/app/views/components/simple_panel.html.erb +1 -0
  156. data/test/basepack_test_app/app/views/layouts/application.html.erb +12 -0
  157. data/test/basepack_test_app/app/views/layouts/components.html.erb +13 -0
  158. data/test/basepack_test_app/app/views/layouts/nested.html.erb +5 -0
  159. data/test/basepack_test_app/app/views/welcome/index.html.erb +10 -0
  160. data/test/basepack_test_app/config.ru +4 -0
  161. data/test/basepack_test_app/config/application.rb +57 -0
  162. data/test/basepack_test_app/config/boot.rb +13 -0
  163. data/test/basepack_test_app/config/cucumber.yml +8 -0
  164. data/test/basepack_test_app/config/database.yml.sample +41 -0
  165. data/test/basepack_test_app/config/database.yml.travis +15 -0
  166. data/test/basepack_test_app/config/environment.rb +6 -0
  167. data/test/basepack_test_app/config/environments/development.rb +22 -0
  168. data/test/basepack_test_app/config/environments/production.rb +49 -0
  169. data/test/basepack_test_app/config/environments/test.rb +35 -0
  170. data/test/basepack_test_app/config/initializers/backtrace_silencers.rb +7 -0
  171. data/test/basepack_test_app/config/initializers/data_mapper_logging.rb +3 -0
  172. data/test/basepack_test_app/config/initializers/inflections.rb +10 -0
  173. data/test/basepack_test_app/config/initializers/mime_types.rb +5 -0
  174. data/test/basepack_test_app/config/initializers/netzke.rb +9 -0
  175. data/test/basepack_test_app/config/initializers/secret_token.rb +7 -0
  176. data/test/basepack_test_app/config/initializers/sequel.rb +26 -0
  177. data/test/basepack_test_app/config/initializers/session_store.rb +8 -0
  178. data/test/basepack_test_app/config/locales/de.yml +35 -0
  179. data/test/basepack_test_app/config/locales/es.yml +96 -0
  180. data/test/basepack_test_app/config/routes.rb +68 -0
  181. data/test/basepack_test_app/db/development_structure.sql +88 -0
  182. data/test/basepack_test_app/db/migrate/20100914104207_create_users.rb +15 -0
  183. data/test/basepack_test_app/db/migrate/20100914104236_create_roles.rb +13 -0
  184. data/test/basepack_test_app/db/migrate/20101026185816_create_authors.rb +14 -0
  185. data/test/basepack_test_app/db/migrate/20101026190021_create_books.rb +19 -0
  186. data/test/basepack_test_app/db/migrate/20110101143818_create_addresses.rb +17 -0
  187. data/test/basepack_test_app/db/migrate/20110213213050_create_netzke_component_states.rb +20 -0
  188. data/test/basepack_test_app/db/migrate/20110701070052_create_book_with_custom_primary_keys.rb +15 -0
  189. data/test/basepack_test_app/db/migrate/20110901114016_add_last_read_at_to_books.rb +9 -0
  190. data/test/basepack_test_app/db/migrate/20110909071740_add_published_on_to_books.rb +5 -0
  191. data/test/basepack_test_app/db/schema.rb +81 -0
  192. data/test/basepack_test_app/db/seeds.rb +44 -0
  193. data/test/basepack_test_app/features/accordion_panel.feature +12 -0
  194. data/test/basepack_test_app/features/components_in_view.feature +11 -0
  195. data/test/basepack_test_app/features/form_panel.feature +142 -0
  196. data/test/basepack_test_app/features/grid_panel.feature +277 -0
  197. data/test/basepack_test_app/features/grid_panel_filters.feature +73 -0
  198. data/test/basepack_test_app/features/grid_panel_with_custom_primary_key.feature +15 -0
  199. data/test/basepack_test_app/features/grid_sorting.feature +47 -0
  200. data/test/basepack_test_app/features/i18n.feature +18 -0
  201. data/test/basepack_test_app/features/nested_attributes.feature +26 -0
  202. data/test/basepack_test_app/features/paging_form_panel.feature +43 -0
  203. data/test/basepack_test_app/features/search_in_grid.feature +49 -0
  204. data/test/basepack_test_app/features/simple_app.feature +15 -0
  205. data/test/basepack_test_app/features/simple_panel.feature +11 -0
  206. data/test/basepack_test_app/features/step_definitions/accordion_steps.rb +5 -0
  207. data/test/basepack_test_app/features/step_definitions/ext_steps.rb +16 -0
  208. data/test/basepack_test_app/features/step_definitions/form_panel_steps.rb +46 -0
  209. data/test/basepack_test_app/features/step_definitions/generic_steps.rb +44 -0
  210. data/test/basepack_test_app/features/step_definitions/grid_panel_steps.rb +186 -0
  211. data/test/basepack_test_app/features/step_definitions/pickle_steps.rb +100 -0
  212. data/test/basepack_test_app/features/step_definitions/web_steps.rb +219 -0
  213. data/test/basepack_test_app/features/support/env.rb +81 -0
  214. data/test/basepack_test_app/features/support/paths.rb +65 -0
  215. data/test/basepack_test_app/features/support/pickle.rb +24 -0
  216. data/test/basepack_test_app/features/support/selectors.rb +39 -0
  217. data/test/basepack_test_app/features/tab_panel.feature +12 -0
  218. data/test/basepack_test_app/features/validations_in_grid.feature +13 -0
  219. data/test/basepack_test_app/features/virtual_attributes.feature +16 -0
  220. data/test/basepack_test_app/features/window.feature +11 -0
  221. data/test/basepack_test_app/lib/tasks/.gitkeep +0 -0
  222. data/test/basepack_test_app/lib/tasks/cucumber.rake +71 -0
  223. data/test/basepack_test_app/lib/tasks/travis.rake +7 -0
  224. data/test/basepack_test_app/public/404.html +26 -0
  225. data/test/basepack_test_app/public/422.html +26 -0
  226. data/test/basepack_test_app/public/500.html +26 -0
  227. data/test/basepack_test_app/public/favicon.ico +0 -0
  228. data/test/basepack_test_app/public/images/header-deco.gif +0 -0
  229. data/test/basepack_test_app/public/images/rails.png +0 -0
  230. data/test/basepack_test_app/public/javascripts/application.js +2 -0
  231. data/test/basepack_test_app/public/javascripts/controls.js +965 -0
  232. data/test/basepack_test_app/public/javascripts/dragdrop.js +974 -0
  233. data/test/basepack_test_app/public/javascripts/effects.js +1123 -0
  234. data/test/basepack_test_app/public/javascripts/prototype.js +6001 -0
  235. data/test/basepack_test_app/public/javascripts/rails.js +175 -0
  236. data/test/basepack_test_app/public/robots.txt +5 -0
  237. data/test/basepack_test_app/public/stylesheets/.gitkeep +0 -0
  238. data/test/basepack_test_app/script/cucumber +10 -0
  239. data/test/basepack_test_app/script/rails +6 -0
  240. data/test/basepack_test_app/spec/components/form_panel_spec.rb +53 -0
  241. data/test/basepack_test_app/spec/components/grid_panel_spec.rb +10 -0
  242. data/test/basepack_test_app/spec/data_adapter/adapter_spec.rb +68 -0
  243. data/test/basepack_test_app/spec/data_adapter/attributes_spec.rb +56 -0
  244. data/test/basepack_test_app/spec/data_adapter/relation_extensions_spec.rb +125 -0
  245. data/test/basepack_test_app/spec/factories.rb +28 -0
  246. data/test/basepack_test_app/spec/spec_helper.rb +39 -0
  247. data/test/basepack_test_app/test/performance/browsing_test.rb +9 -0
  248. data/test/basepack_test_app/test/test_helper.rb +13 -0
  249. data/test/basepack_test_app/vendor/plugins/.gitkeep +0 -0
  250. data/test/console_with_fixtures.rb +4 -0
  251. data/test/fixtures/books.yml +11 -0
  252. data/test/fixtures/categories.yml +7 -0
  253. data/test/fixtures/cities.yml +21 -0
  254. data/test/fixtures/continents.yml +7 -0
  255. data/test/fixtures/countries.yml +9 -0
  256. data/test/fixtures/genres.yml +9 -0
  257. data/test/fixtures/roles.yml +8 -0
  258. data/test/fixtures/users.yml +11 -0
  259. data/test/schema.rb +10 -0
  260. data/test/test_helper.rb +21 -0
  261. data/test/unit/accordion_panel_test.rb +20 -0
  262. data/test/unit/active_record_basepack_test.rb +54 -0
  263. data/test/unit/fields_configuration_test.rb +18 -0
  264. data/test/unit/grid_panel_test.rb +52 -0
  265. data/test/unit/netzke_basepack_test.rb +4 -0
  266. data/test/unit/tab_panel_test.rb +21 -0
  267. data/uninstall.rb +1 -0
  268. metadata +332 -0
@@ -0,0 +1,179 @@
1
+ {
2
+ // Handler for the 'add' button
3
+ onAddInline: function(){
4
+ // Note: default values are taken from the model's field's defaultValue property
5
+ var r = Ext.ModelManager.create({}, this.id);
6
+
7
+ r.isNew = true; // to distinguish new records
8
+
9
+ this.getStore().add(r);
10
+
11
+ this.tryStartEditing(r);
12
+ },
13
+
14
+ onDel: function() {
15
+ Ext.Msg.confirm(this.i18n.confirmation, this.i18n.areYouSure, function(btn){
16
+ if (btn == 'yes') {
17
+ var records = [];
18
+ this.getSelectionModel().selected.each(function(r){
19
+ if (r.isNew) {
20
+ // this record is not know to server - simply remove from store
21
+ this.store.remove(r);
22
+ } else {
23
+ records.push(r.getId());
24
+ }
25
+ }, this);
26
+
27
+ if (records.length > 0){
28
+ if (!this.deleteMask) this.deleteMask = new Ext.LoadMask(this.getEl(), {msg: this.deleteMaskMsg});
29
+ this.deleteMask.show();
30
+ // call API
31
+ this.deleteData({records: Ext.encode(records)}, function(){
32
+ this.deleteMask.hide();
33
+ }, this);
34
+ }
35
+ }
36
+ }, this);
37
+ },
38
+
39
+ onApply: function(){
40
+ if (this.fireEvent('apply')) {
41
+ var newRecords = [],
42
+ updatedRecords = [],
43
+ store = this.getStore();
44
+
45
+ Ext.each(store.getUpdatedRecords().concat(store.getNewRecords()),
46
+ function(r) {
47
+ if (r.isNew) {
48
+ newRecords.push(r.data); // HACK: r.data seems private
49
+ } else {
50
+ updatedRecords.push(Ext.apply(r.getChanges(), {id:r.getId()}));
51
+ }
52
+ },
53
+ this);
54
+
55
+ if (newRecords.length > 0 || updatedRecords.length > 0) {
56
+ var params = {};
57
+
58
+ if (newRecords.length > 0) {
59
+ params.created_records = Ext.encode(newRecords);
60
+ }
61
+
62
+ if (updatedRecords.length > 0) {
63
+ params.updated_records = Ext.encode(updatedRecords);
64
+ }
65
+
66
+ if (this.getStore().getProxy().extraParams !== {}) {
67
+ params.base_params = Ext.encode(this.getStore().getProxy().extraParams);
68
+ }
69
+
70
+ this.postData(params);
71
+ }
72
+ }
73
+ this.fireEvent('afterApply', this);
74
+ },
75
+
76
+ // Handlers for tools
77
+ //
78
+
79
+ onRefresh: function() {
80
+ if (this.fireEvent('refresh', this) !== false) {
81
+ this.store.load();
82
+ }
83
+ },
84
+
85
+ // Event handlers
86
+ //
87
+
88
+ onColumnResize: function(ct, cl, width){
89
+ var index = ct.items.findIndex('id', cl.id);
90
+
91
+ this.resizeColumn({
92
+ index: index,
93
+ size: width
94
+ });
95
+ },
96
+
97
+ onColumnHide: function(ct, cl){
98
+ var index = ct.items.findIndex('id', cl.id);
99
+
100
+ this.hideColumn({
101
+ index:index,
102
+ hidden:true
103
+ });
104
+ },
105
+
106
+ onColumnShow: function(ct, cl){
107
+ var index = ct.items.findIndex('id', cl.id);
108
+
109
+ this.hideColumn({
110
+ index:index,
111
+ hidden:false
112
+ });
113
+ },
114
+
115
+ onColumnMove: function(ct, cl, oldIndex, newIndex){
116
+ this.moveColumn({
117
+ old_index: oldIndex,
118
+ new_index: newIndex
119
+ });
120
+ },
121
+
122
+ onItemContextMenu: function(grid, record, item, rowIndex, e){
123
+ e.stopEvent();
124
+ var coords = e.getXY();
125
+
126
+ if (!grid.getSelectionModel().isSelected(rowIndex)) {
127
+ grid.getSelectionModel().selectRow(rowIndex);
128
+ }
129
+
130
+ var menu = new Ext.menu.Menu({
131
+ items: this.contextMenu
132
+ });
133
+
134
+ menu.showAt(coords);
135
+ },
136
+
137
+ onAfterRowMove: function(dt, oldIndex, newIndex, records){
138
+ var ids = [];
139
+ // collect records ids
140
+ Ext.each(records, function(r){ids.push(r.id)});
141
+ // call GridPanel's API
142
+ this.moveRows({ids: Ext.encode(ids), new_index: newIndex});
143
+ },
144
+
145
+ // Other methods. TODO: revise
146
+ //
147
+
148
+ /* Exception handler. TODO: will responses with status 200 land here? */
149
+ loadExceptionHandler: function(proxy, response, operation){
150
+ this.netzkeFeedback(response.message);
151
+ // if (response.status == 200 && (responseObject = Ext.decode(response.responseText)) && responseObject.flash){
152
+ // this.feedback(responseObject.flash);
153
+ // } else {
154
+ // if (error){
155
+ // this.feedback(error.message);
156
+ // } else {
157
+ // this.feedback(response.statusText);
158
+ // }
159
+ // }
160
+ },
161
+
162
+ // Inline editing of 1 row
163
+ onEdit: function(){
164
+ var row = this.getSelectionModel().selected.first();
165
+ if (row){
166
+ this.tryStartEditing(row);
167
+ }
168
+ },
169
+
170
+ // Not a very clean approach to clean-up. The problem is that this way the advanced search functionality stops being really pluggable. With Ext JS 4 find the way to make it truely so.
171
+ onDestroy: function(){
172
+ Netzke.classes.Basepack.GridPanel.superclass.onDestroy.call(this);
173
+
174
+ // Destroy the search window (here's the problem: we are not supposed to know it exists)
175
+ if (this.searchWindow) {
176
+ this.searchWindow.destroy();
177
+ }
178
+ }
179
+ }
@@ -0,0 +1,438 @@
1
+ {
2
+ trackMouseOver: true,
3
+ loadMask: true,
4
+ autoScroll: true,
5
+
6
+ componentLoadMask: {msg: "Loading..."},
7
+ deleteMaskMsg: "Deleting...",
8
+ multiSelect: true,
9
+
10
+ initComponent: function(){
11
+ var metaColumn;
12
+ var fields = []; // field configs for the underlying data model
13
+
14
+ this.plugins = this.plugins || [];
15
+ this.features = this.features || [];
16
+
17
+ // Enable filters feature
18
+ this.features.push({
19
+ encode: true,
20
+ ftype: 'filters'
21
+ });
22
+
23
+ // Run through columns and set up different configuration for each
24
+ Ext.each(this.columns, function(c, i){
25
+
26
+ this.normalizeRenderer(c);
27
+
28
+ // Build the field configuration for this column
29
+ var fieldConfig = {name: c.name, defaultValue: c.defaultValue};
30
+
31
+ if (c.name !== '_meta') fieldConfig.type = this.fieldTypeForAttrType(c.attrType); // field type (grid editors need this to function well)
32
+
33
+ if (c.attrType == 'datetime') {
34
+ fieldConfig.dateFormat = 'Y-m-d H:i:s'; // set the format in which we receive datetime from the server (so that the model can parse it)
35
+
36
+ // While for 'date' columns the renderer is set up automatically (through using column's xtype), there's no appropriate xtype for our custom datetime column.
37
+ // Thus, we need to set the renderer manually.
38
+ // NOTE: for Ext there's no distinction b/w date and datetime; date fields can include time.
39
+ if (!c.renderer) {
40
+ // format in which the data will be rendered; if c.format is nil, Ext.Date.defaultFormat extended with time will be used
41
+ c.renderer = Ext.util.Format.dateRenderer(c.format || Ext.Date.defaultFormat + " H:i:s");
42
+ }
43
+ };
44
+
45
+ fields.push(fieldConfig);
46
+
47
+ // We will not use meta columns as actual columns (not even hidden) - only to create the records
48
+ if (c.meta) {
49
+ metaColumn = c;
50
+ return;
51
+ }
52
+
53
+ // if comboboxOptions are provided, we render a combobox instead of textfield
54
+ // if (c.comboboxOptions && c.editor.xtype === "textfield") {
55
+ // c.editor = {xtype: "combobox", options: c.comboboxOptions.split('\\n')}
56
+ // }
57
+
58
+
59
+ // Set rendeder for association columns (the one displaying associations by the specified method instead of id)
60
+ if (c.assoc) {
61
+ c.emptyText = c.emptyText || "---";
62
+
63
+ // Editor for association column
64
+ c.editor = Ext.apply({
65
+ parentId: this.id,
66
+ emptyText: c.emptyText,
67
+ name: c.name
68
+ }, c.editor);
69
+
70
+ // Renderer for association column
71
+ this.normalizeAssociationRenderer(c);
72
+ }
73
+
74
+ if (c.editor) {
75
+ Ext.applyIf(c.editor, {selectOnFocus: true});
76
+ }
77
+
78
+ // Setting the default filter type
79
+ if (c.filterable && !c.filter) {
80
+ c.filter = {type: this.fieldTypeForAttrType(c.attrType)};
81
+ }
82
+
83
+ // setting dataIndex
84
+ c.dataIndex = c.name;
85
+
86
+ }, this);
87
+
88
+ /* ... and done with the columns */
89
+
90
+ // Define the model
91
+ Ext.define(this.id, {
92
+ extend: 'Ext.data.Model',
93
+ idProperty: this.pri, // Primary key
94
+ fields: fields
95
+ });
96
+
97
+ // After we created the record (model), we can get rid of the meta column
98
+ Ext.Array.remove(this.columns, metaColumn);
99
+
100
+ // Prepare column model config with columns in the correct order; columns out of order go to the end.
101
+ var colModelConfig = [];
102
+ var columns = this.columns;
103
+
104
+ Ext.each(this.columnsOrder, function(c) {
105
+ var mainColConfig;
106
+ Ext.each(this.columns, function(oc) {
107
+ if (c.name === oc.name) {
108
+ mainColConfig = Ext.apply({}, oc);
109
+ return false;
110
+ }
111
+ });
112
+
113
+ colModelConfig.push(Ext.apply(mainColConfig, c));
114
+ }, this);
115
+
116
+ // We don't need original columns any longer
117
+ delete this.columns;
118
+
119
+ // ... instead, define own column model
120
+ this.columns = colModelConfig;
121
+
122
+ var reader = Ext.create('Ext.data.reader.Array', {root: 'data', totalProperty: 'total'});
123
+
124
+ // DirectProxy that uses our Ext.direct provider
125
+ var proxy = Ext.create('Ext.data.proxy.Direct', {
126
+ directFn: Netzke.providers[this.id].getData,
127
+ reader: reader,
128
+ listeners: {
129
+ exception: {
130
+ fn: this.loadExceptionHandler,
131
+ scope: this
132
+ },
133
+ load: { // Netzke-introduced event; this will also be fired when an exception occurs.
134
+ fn: function(proxy, response, operation) {
135
+ // besides getting data into the store, we may also get commands to execute
136
+ response = response.result;
137
+ if (response) { // or did we have an exception?
138
+ Ext.each(['data', 'total', 'success'], function(property){delete response[property];});
139
+ this.bulkExecute(response);
140
+ }
141
+ },
142
+ scope: this
143
+ }
144
+ }
145
+ });
146
+
147
+ this.store = Ext.create('Ext.data.Store', {
148
+ model: this.id,
149
+ proxy: proxy,
150
+ pruneModifiedRecords: true,
151
+ remoteSort: true,
152
+ pageSize: this.rowsPerPage
153
+ });
154
+
155
+ if (this.inlineData) this.store.loadRawData(this.inlineData);
156
+
157
+ // Drag'n'Drop
158
+ if (this.enableRowsReordering){
159
+ this.ddPlugin = new Ext.ux.dd.GridDragDropRowOrder({
160
+ scrollable: true // enable scrolling support (default is false)
161
+ });
162
+ this.plugins.push(this.ddPlugin);
163
+ }
164
+
165
+ // Cell editing
166
+ if (!this.prohibitUpdate) {
167
+ this.plugins.push(Ext.create('Ext.grid.plugin.CellEditing', {pluginId: 'celleditor'}));
168
+ }
169
+
170
+ // Toolbar
171
+ this.dockedItems = this.dockedItems || [];
172
+ if (this.enablePagination) {
173
+ this.dockedItems.push({
174
+ xtype: 'pagingtoolbar',
175
+ dock: 'bottom',
176
+ store: this.store,
177
+ items: this.bbar && ["-"].concat(this.bbar) // append the old bbar
178
+ });
179
+ } else if (this.bbar) {
180
+ this.dockedItems.push({
181
+ xtype: 'toolbar',
182
+ dock: 'bottom',
183
+ items: this.bbar
184
+ });
185
+ }
186
+
187
+
188
+ delete this.bbar;
189
+
190
+ // Now let Ext.grid.EditorGridPanel do the rest (original initComponent)
191
+ this.callParent();
192
+
193
+ // Context menu
194
+ if (this.contextMenu) {
195
+ this.on('itemcontextmenu', this.onItemContextMenu, this);
196
+ }
197
+
198
+ // Disabling/enabling editInForm button according to current selection
199
+ if (this.enableEditInForm && !this.prohibitUpdate) {
200
+ this.getSelectionModel().on('selectionchange', function(selModel, selected){
201
+ var disabled;
202
+ if (selected.length === 0) { // empty?
203
+ disabled = true;
204
+ } else {
205
+ // Disable "edit in form" button if new record is present in selection
206
+ Ext.each(selected, function(r){
207
+ if (r.isNew) { disabled = true; return false; }
208
+ });
209
+ };
210
+ this.actions.editInForm.setDisabled(disabled);
211
+ }, this);
212
+ }
213
+
214
+ // Process selectionchange event to enable/disable actions
215
+ this.getSelectionModel().on('selectionchange', function(selModel){
216
+ if (this.actions.del) this.actions.del.setDisabled(!selModel.hasSelection() || this.prohibitDelete);
217
+ if (this.actions.edit) this.actions.edit.setDisabled(selModel.getCount() != 1 || this.prohibitUpdate);
218
+ }, this);
219
+
220
+ // Drag n Drop event
221
+ if (this.enableRowsReordering){
222
+ this.ddPlugin.on('afterrowmove', this.onAfterRowMove, this);
223
+ }
224
+
225
+ // WIP: GridView
226
+ this.getView().getRowClass = this.defaultGetRowClass;
227
+
228
+ // this.on('edit', function(editor, e) {
229
+ // if (e.column.assoc && e.record.get('_meta')) {
230
+ // console.log("editor:", editor);
231
+ // editor.setRawValue("");
232
+ // }
233
+ // });
234
+
235
+ // When starting editing as assocition column, pre-load the combobox store from the meta column, so that we don't see the real value of this cell (the id of the associated record), but rather the associated record by the configured method.
236
+ this.on('beforeedit', function(editor, e){
237
+ if (e.column.assoc && e.record.get('_meta')) {
238
+ var c = e.column,
239
+ combo = c.getEditor(),
240
+ store = combo.store,
241
+ id = e.record.get(e.field);
242
+
243
+ if (id === 0 && -1 == store.find('field1', 0)) store.loadData([[0, c.emptyText]], true);
244
+
245
+ if (id && -1 == store.find('field1', id)) {
246
+ store.loadData([[e.record.get(e.field), e.record.get('_meta').associationValues[e.field]]], true);
247
+ }
248
+
249
+ }
250
+ }, this);
251
+
252
+ this.on('afterrender', function() {
253
+ // Persistence-related events (afterrender to avoid blank event firing on render)
254
+ if (this.persistence) {
255
+ // Inform the server part about column operations
256
+ this.on('columnresize', this.onColumnResize, this);
257
+ this.on('columnmove', this.onColumnMove, this);
258
+ this.on('columnhide', this.onColumnHide, this);
259
+ this.on('columnshow', this.onColumnShow, this);
260
+ }
261
+ }, this);
262
+ },
263
+
264
+ fieldTypeForAttrType: function(attrType){
265
+ var map = {
266
+ integer : 'int',
267
+ decimal : 'float',
268
+ datetime : 'date',
269
+ date : 'date',
270
+ string : 'string',
271
+ text : 'string',
272
+ 'boolean' : 'boolean'
273
+ };
274
+ return map[attrType] || 'string';
275
+ },
276
+
277
+ update: function(){
278
+ this.store.load();
279
+ },
280
+
281
+ loadStoreData: function(data){
282
+ var dataRecords = this.getStore().getProxy().getReader().read(data);
283
+ this.getStore().loadData(dataRecords.records);
284
+ Ext.each(['data', 'total', 'success'], function(property){delete data[property];}, this);
285
+ this.bulkExecute(data);
286
+ },
287
+
288
+ // Tries editing the first editable (i.e. not hidden, not read-only) sell
289
+ tryStartEditing: function(r){
290
+ var editableIndex = 0;
291
+ Ext.each(this.initialConfig.columns, function(c){
292
+ // skip columns that cannot be edited
293
+ if (!(c.hidden == true || c.editable == false || !c.editor || c.attrType == 'boolean')) {
294
+ return false;
295
+ }
296
+ editableIndex++;
297
+ });
298
+
299
+ if (editableIndex < this.initialConfig.columns.length) {this.getPlugin('celleditor').startEdit(r, this.columns[editableIndex]);}
300
+ },
301
+
302
+ // Called by the server side to update newly created records
303
+ updateNewRecords: function(records){
304
+ this.updateRecords(records);
305
+ },
306
+
307
+ // Called by the server side to update modified records
308
+ updateModRecords: function(records){
309
+ this.updateRecords(records, true);
310
+ },
311
+
312
+ // Updates modified or newly created records, by record ID
313
+ // Example of the records argument (updated columns):
314
+ // {1098 => [1, 'value1', 'value2'], 1099 => [2, 'value1', 'value2']}
315
+ // Example of the records argument (new columns, id autogenerated by Ext):
316
+ // {"ext-record-200" => [1, 'value1', 'value2']}
317
+ updateRecords: function(records, mod){
318
+ if (!mod) {mod = false;}
319
+ var modRecordsInGrid = [].concat(this.store.getUpdatedRecords()); // there must be a better way to clone an array...
320
+ // replace arrays of data in the args object with Ext.data.Record objects
321
+ for (var k in records){
322
+ records[k] = this.getStore().getProxy().getReader().read({data:[records[k]]}).records[0];
323
+ }
324
+ // for each new record write the data returned by the server, and commit the record
325
+ Ext.each(modRecordsInGrid, function(recordInGrid){
326
+ if (mod ^ recordInGrid.isNew) {
327
+ // if record is new, we access its id by "id", otherwise, the id is in the primary key column
328
+ var recordId = recordInGrid.getId();
329
+ // new data that the server sent us to update this record (identified by the id)
330
+ var newData = records[recordId];
331
+
332
+ if (newData){
333
+ for (var k in newData.data){
334
+ recordInGrid.set(k, newData.get(k));
335
+ }
336
+
337
+ recordInGrid.isNew = false;
338
+ recordInGrid.commit();
339
+ }
340
+
341
+ }
342
+ }, this);
343
+
344
+ // clear the selections
345
+ this.getSelectionModel().clearSelections();
346
+
347
+ // check if there are still records with errors
348
+ var modRecords = this.store.getUpdatedRecords();
349
+ if (modRecords.length == 0) {
350
+ // if all records are accepted, reload the grid (so that eventual order/filtering is correct)
351
+ this.store.load();
352
+
353
+ // ... and set default getRowClass function
354
+ this.getView().getRowClass = this.defaultGetRowClass;
355
+ } else {
356
+ this.getView().getRowClass = function(r){
357
+ return r.dirty ? "grid-dirty-record" : ""
358
+ }
359
+ }
360
+
361
+ this.getView().refresh();
362
+ this.getSelectionModel().fireEvent('selectionchange', this.getSelectionModel());
363
+ },
364
+
365
+ defaultGetRowClass: function(r){
366
+ return r.isNew ? "grid-dirty-record" : ""
367
+ },
368
+
369
+ selectFirstRow: function(){
370
+ this.getSelectionModel().suspendEvents();
371
+ this.getSelectionModel().selectRow(0);
372
+ this.getSelectionModel().resumeEvents();
373
+ },
374
+
375
+ // Normalizes the renderer for a column.
376
+ // Renderer may be:
377
+ // 1) a string that contains the name of the function to be used as renderer.
378
+ // 2) an array, where the first element is the function name, and the rest - the arguments
379
+ // that will be passed to that function along with the value to be rendered.
380
+ // The function is searched in the following objects: 1) Ext.util.Format, 2) this.
381
+ // If not found, it is simply evaluated. Handy, when as renderer we receive an inline JS function,
382
+ // or reference to a function in some other scope.
383
+ // So, these will work:
384
+ // * "uppercase"
385
+ // * ["ellipsis", 10]
386
+ // * ["substr", 3, 5]
387
+ // * "myRenderer" (if this.myRenderer is a function)
388
+ // * ["Some.scope.Format.customRenderer", 10, 20, 30] (if Some.scope.Format.customRenderer is a function)
389
+ // * "function(v){ return 'Value: ' + v; }"
390
+ normalizeRenderer: function(c) {
391
+ if (!c.renderer) return;
392
+
393
+ var name, args = [];
394
+
395
+ if ('string' === typeof c.renderer) {
396
+ name = c.renderer.camelize(true);
397
+ } else {
398
+ name = c.renderer[0];
399
+ args = c.renderer.slice(1);
400
+ }
401
+
402
+ // First check whether Ext.util.Format has it
403
+ if (Ext.isFunction(Ext.util.Format[name])) {
404
+ c.renderer = Ext.Function.bind(Ext.util.Format[name], this, args, 1);
405
+ } else if (Ext.isFunction(this[name])) {
406
+ // ... then if our own class has it
407
+ c.renderer = Ext.Function.bind(this[name], this, args, 1);
408
+ } else {
409
+ // ... and, as last resort, evaluate it (allows passing inline javascript function as renderer)
410
+ eval("c.renderer = " + c.renderer + ";");
411
+ }
412
+ },
413
+
414
+ /*
415
+ Set a renderer that displayes association values instead of association record ID.
416
+ The association values are passed in the meta-column under associationValues hash.
417
+ */
418
+ normalizeAssociationRenderer: function(c) {
419
+ c.scope = this;
420
+ var passedRenderer = c.renderer; // renderer we got from normalizeRenderer
421
+ c.renderer = function(value, a, r, ri, ci){
422
+ var column = this.headerCt.items.getAt(ci),
423
+ editor = column.getEditor && column.getEditor(),
424
+ recordFromStore = editor && editor.isXType('combobox') && editor.getStore().findRecord('field1', value),
425
+ renderedValue;
426
+
427
+ if (recordFromStore) {
428
+ renderedValue = recordFromStore.get('field2');
429
+ } else if (c.assoc && r.get('_meta')) {
430
+ renderedValue = r.get('_meta').associationValues[c.name] || c.emptyText;
431
+ } else {
432
+ renderedValue = value;
433
+ }
434
+
435
+ return passedRenderer ? passedRenderer.call(this, renderedValue) : renderedValue;
436
+ };
437
+ }
438
+ }