netzke-basepack 0.6.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. data/CHANGELOG.rdoc +14 -6
  2. data/README.rdoc +16 -31
  3. data/Rakefile +22 -16
  4. data/TODO.rdoc +1 -1
  5. data/app/models/netzke_field_list.rb +29 -29
  6. data/app/models/netzke_model_attr_list.rb +4 -4
  7. data/app/models/netzke_persistent_array_auto_model.rb +9 -9
  8. data/config/database.yml +2 -35
  9. data/features/accordion_panel.feature +1 -1
  10. data/features/form_panel.feature +2 -2
  11. data/features/grid_panel.feature +15 -3
  12. data/features/search_in_grid.feature +4 -4
  13. data/features/simple_panel.feature +4 -4
  14. data/features/step_definitions/pickle_steps.rb +2 -2
  15. data/features/step_definitions/web_steps.rb +5 -5
  16. data/features/support/env.rb +6 -6
  17. data/features/tab_panel.feature +1 -1
  18. data/javascripts/basepack.js +28 -28
  19. data/lib/netzke-basepack.rb +5 -5
  20. data/lib/netzke/active_record.rb +1 -1
  21. data/lib/netzke/active_record/association_attributes.rb +9 -9
  22. data/lib/netzke/active_record/attributes.rb +24 -23
  23. data/lib/netzke/active_record/combobox_options.rb +3 -3
  24. data/lib/netzke/active_record/relation_extensions.rb +4 -4
  25. data/lib/netzke/basepack.rb +4 -4
  26. data/{app/components → lib}/netzke/basepack/accordion_panel.rb +7 -7
  27. data/{app/components → lib}/netzke/basepack/basic_app.rb +18 -18
  28. data/{app/components → lib}/netzke/basepack/basic_app/statusbar_ext.js +0 -0
  29. data/lib/netzke/basepack/border_layout_panel.rb +101 -0
  30. data/{app/components → lib}/netzke/basepack/form_panel.rb +21 -21
  31. data/{app/components → lib}/netzke/basepack/form_panel/fields.rb +29 -36
  32. data/{app/components → lib}/netzke/basepack/form_panel/javascripts/netzkefileupload.js +0 -0
  33. data/{app/components → lib}/netzke/basepack/form_panel/javascripts/pre.js +9 -9
  34. data/{app/components → lib}/netzke/basepack/form_panel/javascripts/xcheckbox.js +1 -1
  35. data/{app/components → lib}/netzke/basepack/form_panel/services.rb +11 -11
  36. data/{app/components → lib}/netzke/basepack/grid_panel.rb +74 -92
  37. data/{app/components → lib}/netzke/basepack/grid_panel/columns.rb +34 -36
  38. data/{app/components → lib}/netzke/basepack/grid_panel/javascript.rb +7 -7
  39. data/{app/components → lib}/netzke/basepack/grid_panel/javascripts/advanced_search.js +10 -10
  40. data/{app/components → lib}/netzke/basepack/grid_panel/javascripts/edit_in_form.js +2 -2
  41. data/{app/components → lib}/netzke/basepack/grid_panel/javascripts/pre.js +31 -31
  42. data/{app/components → lib}/netzke/basepack/grid_panel/javascripts/rows-dd.js +1 -1
  43. data/{app/components → lib}/netzke/basepack/grid_panel/multi_edit_form.rb +2 -2
  44. data/{app/components → lib}/netzke/basepack/grid_panel/record_form_window.rb +3 -3
  45. data/{app/components → lib}/netzke/basepack/grid_panel/search_window.rb +11 -11
  46. data/{app/components → lib}/netzke/basepack/grid_panel/services.rb +28 -28
  47. data/{app/components → lib}/netzke/basepack/panel.rb +0 -0
  48. data/{app/components → lib}/netzke/basepack/search_panel.rb +11 -11
  49. data/{app/components → lib}/netzke/basepack/tab_panel.rb +7 -7
  50. data/lib/netzke/basepack/version.rb +1 -1
  51. data/{app/components → lib}/netzke/basepack/window.rb +14 -14
  52. data/{app/components → lib}/netzke/basepack/wrapper.rb +6 -6
  53. data/lib/netzke/data_accessor.rb +18 -18
  54. data/lib/netzke/fields_configurator.rb +30 -30
  55. data/lib/netzke/json_array_editor.rb +9 -9
  56. data/lib/netzke/masquerade_selector.rb +5 -5
  57. data/locale/en.yml +1 -1
  58. data/netzke-basepack.gemspec +252 -240
  59. data/spec/active_record/attributes_spec.rb +6 -1
  60. data/spec/active_record/relation_extensions_spec.rb +11 -11
  61. data/spec/components/form_panel_spec.rb +13 -19
  62. data/spec/components/grid_panel_spec.rb +1 -1
  63. data/test/rails_app/Gemfile +4 -3
  64. data/test/rails_app/Gemfile.lock +42 -50
  65. data/test/rails_app/app/components/book_grid.rb +4 -0
  66. data/test/rails_app/app/components/generic_user_form.rb +2 -2
  67. data/test/rails_app/app/components/simple_basic_app.rb +3 -3
  68. data/test/rails_app/app/components/simple_panel.rb +1 -1
  69. data/test/rails_app/app/components/some_border_layout.rb +12 -11
  70. data/test/rails_app/app/components/some_search_panel.rb +5 -5
  71. data/test/rails_app/app/components/user_form.rb +1 -1
  72. data/test/rails_app/app/components/window_component_loader.rb +2 -2
  73. data/test/rails_app/app/models/author.rb +7 -0
  74. data/test/rails_app/app/models/book.rb +3 -0
  75. data/test/rails_app/app/models/user.rb +1 -1
  76. data/test/rails_app/config/locales/es.yml +0 -1
  77. data/test/rails_app/config/routes.rb +2 -2
  78. data/test/rails_app/db/development_structure.sql +28 -3
  79. data/test/rails_app/db/migrate/20101026185816_create_authors.rb +14 -0
  80. data/test/rails_app/db/migrate/20101026190021_create_books.rb +17 -0
  81. data/test/rails_app/db/schema.rb +18 -1
  82. data/test/rails_app/public/javascripts/effects.js +1 -1
  83. data/test/rails_app/spec/models/author_spec.rb +5 -0
  84. data/test/rails_app/spec/models/book_spec.rb +5 -0
  85. data/test/test_helper.rb +1 -1
  86. data/test/unit/accordion_panel_test.rb +2 -2
  87. data/test/unit/active_record_basepack_test.rb +9 -9
  88. data/test/unit/fields_configuration_test.rb +4 -4
  89. data/test/unit/grid_panel_test.rb +8 -8
  90. data/test/unit/tab_panel_test.rb +2 -2
  91. metadata +49 -36
  92. data/.gitignore +0 -10
  93. data/app/components/netzke/basepack/border_layout_panel.rb +0 -39
@@ -6,9 +6,9 @@ require "netzke/basepack/form_panel/services"
6
6
  module Netzke
7
7
  module Basepack
8
8
  # = FormPanel
9
- #
9
+ #
10
10
  # Represents Ext.form.FormPanel
11
- #
11
+ #
12
12
  # == Configuration
13
13
  # * <tt>:model</tt> - name of the ActiveRecord model that provides data to this GridPanel.
14
14
  # * <tt>:record</tt> - record to be displayd in the form. Takes precedence over <tt>:record_id</tt>
@@ -17,49 +17,49 @@ module Netzke
17
17
  # Class-level configuration
18
18
  class_attribute :config_tool_available
19
19
  self.config_tool_available = true
20
-
20
+
21
21
  class_attribute :default_config
22
22
  self.default_config = {} # To be filled in
23
-
23
+
24
24
  include self::Services
25
25
  include self::Fields
26
-
27
- include Netzke::DataAccessor
28
-
26
+
27
+ include Netzke::DataAccessor
28
+
29
29
  js_base_class "Netzke.pre.FormPanel"
30
-
30
+
31
31
  js_property :bbar, [:apply.action]
32
-
32
+
33
33
  # def initial_config
34
34
  # res = super
35
35
  # res[:bbar] = default_bbar if res[:bbar].nil?
36
36
  # res
37
37
  # end
38
- #
38
+ #
39
39
  # def default_bbar
40
40
  # [:apply.action]
41
41
  # end
42
-
42
+
43
43
  # Extra javascripts
44
44
  js_include "#{File.dirname(__FILE__)}/form_panel/javascripts/pre.js",
45
45
  "#{File.dirname(__FILE__)}/form_panel/javascripts/xcheckbox.js"
46
46
  # Netzke::Base.config[:ext_location] + "/examples/ux/fileuploadfield/FileUploadField.js",
47
47
  # "#{File.dirname(__FILE__)}/form_panel/javascripts/netzkefileupload.js"
48
-
48
+
49
49
  def js_config
50
50
  super.merge(
51
51
  # :fields => fields,
52
52
  :pri => data_class && data_class.primary_key
53
53
  )
54
54
  end
55
-
55
+
56
56
  def record
57
57
  @record ||= config[:record] || config[:record_id] && data_class && data_class.where(data_class.primary_key => config[:record_id]).first
58
58
  end
59
-
59
+
60
60
  def configuration_components
61
61
  res = []
62
-
62
+
63
63
  res << {
64
64
  :name => 'fields',
65
65
  :class_name => "FieldsConfigurator",
@@ -74,7 +74,7 @@ module Netzke
74
74
  :component => self,
75
75
  :title => false
76
76
  }
77
-
77
+
78
78
  res
79
79
  end
80
80
 
@@ -86,17 +86,17 @@ module Netzke
86
86
  # {:name => "ext_config__header", :attr_type => :boolean, :default => true},
87
87
  # {:name => "ext_config__bbar", :attr_type => :json}
88
88
  ]
89
-
89
+
90
90
  res
91
91
  end
92
-
92
+
93
93
  private
94
-
94
+
95
95
  def self.server_side_config_options
96
96
  super + [:record]
97
97
  end
98
-
99
- # include ::Netzke::Plugins::ConfigurationTool if config_tool_available # it will load ConfigurationPanel into a modal window
98
+
99
+ # include ::Netzke::Plugins::ConfigurationTool if config_tool_available # it will load ConfigurationPanel into a modal window
100
100
  end
101
101
  end
102
102
  end
@@ -4,13 +4,13 @@ module Netzke
4
4
  # Because FormPanel allows for arbitrary layout of fields, we need to have all fields configured in one place (the +fields+ method), and then have references to those fields from +items+.
5
5
  module Fields
6
6
  extend ActiveSupport::Concern
7
-
7
+
8
8
  # Items with normalized fields (i.e. containing all the necessary attributes needed by Ext.form.FormPanel to render
9
9
  # a field)
10
10
  def items
11
11
  @form_panel_items ||= begin
12
12
  res = normalize_fields(super || data_class && data_class.netzke_attributes || []) # take netzke_attributes as default items
13
-
13
+
14
14
  # if primary key isn't there, insert it as first
15
15
  if data_class && res.first && res.first[:name] != [data_class.primary_key]
16
16
  primary_key_item = normalize_field(data_class.primary_key.to_sym)
@@ -21,7 +21,7 @@ module Netzke
21
21
  res
22
22
  end
23
23
  end
24
-
24
+
25
25
  # Hash of fully configured fields, that are referenced in the items. E.g.:
26
26
  # {
27
27
  # :role__name => {:xtype => 'combobox', :disabled => true, :value => "admin"},
@@ -41,19 +41,19 @@ module Netzke
41
41
  flds
42
42
  end
43
43
  end
44
-
44
+
45
45
  # The array of fields as specified on the model level (using +netzke_attribute+ and alike)
46
46
  def fields_array_from_model
47
47
  data_class && data_class.netzke_attributes
48
48
  end
49
-
49
+
50
50
  # Hash of fields as specified on the model level
51
51
  def fields_from_model
52
52
  @fields_from_model ||= fields_array_from_model && fields_array_from_model.inject({}){ |hsh, f| hsh.merge(f[:name].to_sym => f) }
53
53
  end
54
-
54
+
55
55
  # Hash of normalized field configs extracted from :items, e.g.:
56
- #
56
+ #
57
57
  # {:role__name => {:xtype => "combobox"}, :password => {:xtype => "passwordfield"}}
58
58
  def fields_from_config
59
59
  items if @fields_from_config.nil? # by calling +items+ we initiate building of @fields_from_config
@@ -72,12 +72,12 @@ module Netzke
72
72
  ]
73
73
  end
74
74
  end
75
-
75
+
76
76
  private
77
77
  def load_persistent_fields
78
78
  # NetzkeFieldList.read_list(global_id) if persistent_config_enabled?
79
79
  end
80
-
80
+
81
81
  def load_model_level_attrs
82
82
  # NetzkeModelAttrList.read_list(data_class.name) if persistent_config_enabled? && data_class
83
83
  end
@@ -91,45 +91,38 @@ module Netzke
91
91
  else
92
92
  field = {:name => field.to_s}
93
93
  end
94
-
94
+
95
95
  field.merge!(fields_from_model[field[:name].to_sym]) unless fields_from_model[field[:name].to_sym].nil?
96
-
96
+
97
97
  detect_association_with_method(field) # xtype for an association field
98
98
 
99
99
  set_default_field_label(field)
100
100
 
101
101
  set_default_field_xtype(field) if field[:xtype].nil?
102
-
102
+
103
103
  set_default_field_value(field) if self.record
104
-
104
+
105
105
  # provide our special combobox with our id
106
106
  field[:parent_id] = self.global_id if field[:xtype] == :combobox
107
-
107
+
108
108
  field[:hidden] = field[:hide_label] = true if field[:hidden].nil? && primary_key_attr?(field)
109
-
109
+
110
110
  field[:checked] = field[:value] if field[:attr_type] == "boolean"
111
-
111
+
112
112
  field
113
113
  end
114
-
114
+
115
115
  # Sets the proper xtype of an asociation field
116
116
  def detect_association_with_method(c)
117
- if c[:name].to_s.index('__')
117
+ if c[:name].index('__')
118
118
  assoc_name, method = c[:name].split('__').map(&:to_sym)
119
- if assoc = data_class.reflect_on_association(assoc_name)
119
+ if method && assoc = data_class.reflect_on_association(assoc_name)
120
120
  assoc_column = assoc.klass.columns_hash[method.to_s]
121
121
  assoc_method_type = assoc_column.try(:type)
122
122
  if assoc_method_type
123
123
  c[:xtype] ||= assoc_method_type == :boolean ? xtype_for_attr_type(assoc_method_type) : xtype_for_association
124
124
  end
125
125
  end
126
- else
127
- # are we reflecting some association's foreign key (e.g. :category_id)?
128
- if assoc = data_class.reflect_on_all_associations.detect{|a| a.primary_key_name == c[:name]}
129
- c[:xtype] ||= xtype_for_association
130
- assoc_method = (%w{name title label} << assoc.primary_key_name).detect{|m| (assoc.klass.instance_methods + assoc.klass.column_names).include?(m) } || assoc.klass.primary_key
131
- c[:name] = "#{assoc.name}__#{assoc_method}"
132
- end
133
126
  end
134
127
  end
135
128
 
@@ -150,31 +143,31 @@ module Netzke
150
143
  end
151
144
  end
152
145
  end
153
-
146
+
154
147
  def is_field_config?(item)
155
148
  item.is_a?(String) || item.is_a?(Symbol) || item[:name] # && !is_component_config?(item)
156
149
  end
157
-
150
+
158
151
  def set_default_field_label(c)
159
152
  c[:field_label] ||= c[:name].humanize.sub(/\s+/, " ") # multiple spaces get replaced with one
160
153
  end
161
-
154
+
162
155
  def set_default_field_value(field)
163
156
  value = record.value_for_attribute(field)
164
157
  field[:value] ||= value unless value.nil?
165
158
  end
166
-
159
+
167
160
  # Deeply merges only those key/values at the top level that are already there
168
161
  def deep_merge_existing_fields(dest, src)
169
162
  dest.each_pair do |k,v|
170
163
  v.deep_merge!(src[k] || {})
171
164
  end
172
165
  end
173
-
166
+
174
167
  def set_default_field_xtype(field)
175
168
  field[:xtype] = xtype_for_attr_type(field[:attr_type]) unless xtype_for_attr_type(field[:attr_type]).nil?
176
169
  end
177
-
170
+
178
171
  def attr_type_to_xtype_map
179
172
  {
180
173
  :integer => :numberfield,
@@ -186,20 +179,20 @@ module Netzke
186
179
  :string => :textfield
187
180
  }
188
181
  end
189
-
182
+
190
183
  def xtype_for_attr_type(type)
191
184
  attr_type_to_xtype_map[type]
192
185
  end
193
-
186
+
194
187
  def xtype_for_association
195
188
  :combobox
196
189
  end
197
-
190
+
198
191
  # Are we provided with a static field layout?
199
192
  def static_layout?
200
193
  !!config[:items]
201
194
  end
202
-
195
+
203
196
  end
204
197
  end
205
198
  end
@@ -1,11 +1,11 @@
1
- /*
1
+ /*
2
2
  Static part of FormPanel's JavaScript class.
3
3
  */
4
4
  Netzke.pre.FormPanel = Ext.extend(Ext.form.FormPanel, {
5
5
  bodyStyle : 'padding:5px 5px 0',
6
6
  autoScroll : true,
7
7
  labelWidth : 150,
8
-
8
+
9
9
  defaults : {
10
10
  anchor : '-20', // to leave some space for the scrollbar
11
11
  listeners : {
@@ -17,14 +17,14 @@ Netzke.pre.FormPanel = Ext.extend(Ext.form.FormPanel, {
17
17
  }
18
18
  }
19
19
  },
20
-
20
+
21
21
  initComponent : function(){
22
22
  this.recordFields = []; // Record
23
23
  this.recordIndex = 0;
24
-
24
+
25
25
  var Record = Ext.data.Record.create(this.recordFields);
26
26
  this.reader = new Ext.data.RecordArrayReader({root:"data"}, Record);
27
-
27
+
28
28
  // Now let Ext.form.FormPanel do the rest
29
29
  Netzke.pre.FormPanel.superclass.initComponent.call(this);
30
30
 
@@ -35,13 +35,13 @@ Netzke.pre.FormPanel = Ext.extend(Ext.form.FormPanel, {
35
35
  onApply : function() {
36
36
  if (this.fireEvent('apply', this)) {
37
37
  var values = this.getForm().getValues();
38
-
38
+
39
39
  // do not send values from disabled fields and empty values
40
40
  for (var fieldName in values) {
41
41
  var field = this.getForm().findField(fieldName);
42
42
  if (!field || field.disabled) delete values[fieldName];
43
43
  }
44
-
44
+
45
45
  if (this.fileUpload) {
46
46
  // Not a Netzke's standard endpoint call, because the form is multipart
47
47
  this.getForm().submit({
@@ -64,7 +64,7 @@ Netzke.pre.FormPanel = Ext.extend(Ext.form.FormPanel, {
64
64
  }
65
65
  }
66
66
  },
67
-
67
+
68
68
  setFormValues : function(values){
69
69
  var normValues = {};
70
70
  for (var key in values) {
@@ -72,5 +72,5 @@ Netzke.pre.FormPanel = Ext.extend(Ext.form.FormPanel, {
72
72
  }
73
73
  this.getForm().setValues(normValues);
74
74
  }
75
-
75
+
76
76
  });
@@ -10,7 +10,7 @@
10
10
  * the Open Source LGPL 3.0 license. Commercial use is permitted to the extent
11
11
  * that the code/component(s) do NOT become part of another Open Source or Commercially
12
12
  * licensed development library or toolkit without explicit permission.
13
- *
13
+ *
14
14
  * License details: http://www.gnu.org/licenses/lgpl.html
15
15
  */
16
16
 
@@ -3,12 +3,12 @@ module Netzke
3
3
  class FormPanel < Netzke::Base
4
4
  module Services
5
5
  extend ActiveSupport::Concern
6
-
6
+
7
7
  included do
8
-
8
+
9
9
  #
10
10
  # Endpoints
11
- #
11
+ #
12
12
  endpoint :netzke_submit do |params|
13
13
  data = ActiveSupport::JSON.decode(params[:data])
14
14
  success = create_or_update_record(data)
@@ -23,12 +23,12 @@ module Netzke
23
23
  {:feedback => @flash}
24
24
  end
25
25
  end
26
-
26
+
27
27
  endpoint :netzke_load do |params|
28
28
  @record = data_class && data_class.find_by_id(params[:id])
29
29
  {:set_form_values => @record.to_hash(fields)}
30
30
  end
31
-
31
+
32
32
  # Returns options for a combobox
33
33
  endpoint :get_combobox_options do |params|
34
34
  query = params[:query]
@@ -39,7 +39,7 @@ module Netzke
39
39
 
40
40
  {:data => combobox_options_for_column(field, :query => query, :scope => scope, :record_id => params[:id])}
41
41
  end
42
-
42
+
43
43
  end
44
44
 
45
45
  # Overriding configuration_panel's get_combobox_options endpoint call
@@ -47,18 +47,18 @@ module Netzke
47
47
  query = params[:query]
48
48
  {:data => (default_columns.map{ |c| c[:name].to_s }).grep(/^#{query}/).map{ |n| [n] }}.to_nifty_json
49
49
  end
50
-
50
+
51
51
  # Returns array of form values according to the configured columns
52
52
  # def array_of_values
53
53
  # @record && @record.to_array(fields)
54
54
  # end
55
-
55
+
56
56
  def values
57
57
  record && record.to_hash(fields)
58
58
  end
59
59
 
60
60
  private
61
-
61
+
62
62
  # Creates/updates a record from hash
63
63
  def create_or_update_record(hsh)
64
64
 
@@ -77,7 +77,7 @@ module Netzke
77
77
  break
78
78
  end
79
79
  end
80
-
80
+
81
81
  # did we have complete success?
82
82
  success && @record.save
83
83
  end
@@ -92,7 +92,7 @@ module Netzke
92
92
  # end
93
93
  # {:data => [array_of_values]}
94
94
  # end
95
-
95
+
96
96
  end
97
97
  end
98
98
  end
@@ -6,10 +6,10 @@ require "netzke/basepack/grid_panel/javascript"
6
6
 
7
7
  module Netzke
8
8
  module Basepack
9
- # == GridPanel
10
- # Ext.grid.EditorGridPanel + server-side code
9
+ # = GridPanel
10
+ #
11
+ # Ext.grid.EditorGridPanel-based component with the following features:
11
12
  #
12
- # == Features:
13
13
  # * multi-line CRUD operations - get, post, delete, create
14
14
  # * (multe-record) editing and adding records through a form
15
15
  # * column resize, move and hide
@@ -17,44 +17,45 @@ module Netzke
17
17
  # * sorting
18
18
  # * pagination
19
19
  # * filtering
20
- # * extended configurable search
21
- # * rows reordering (drag-n-drop)
22
- # * dynamic configuration of properties and columns
20
+ # * extended search
21
+ # * (TODO) rows reordering (drag-n-drop)
22
+ # * (TODO) dynamic configuration of properties and columns
23
23
  #
24
24
  # == Class configuration
25
- # Configuration on this level is effective during the life-time of the application. They can be put into a .rb file
26
- # inside of config/initializers like this:
27
- #
25
+ #
26
+ # Configuration on this level is effective during the life-time of the application. The right place for setting these options are in
27
+ # config/initializers, e.g.:
28
+ #
28
29
  # Netzke::GridPanel.column_filters_available = false
29
30
  # Netzke::GridPanel.default_config = {:enable_config_tool => false}
30
- #
31
- # Most of these options directly influence the amount of JavaScript code that is generated for this component's class.
32
- # The less functionality is enabled, the less code is generated.
33
- #
31
+ #
32
+ # Most of these options influence the amount of JavaScript code that is generated for this component's class, in the way that
33
+ # the less functionality is enabled, the less code is generated.
34
+ #
34
35
  # The following configuration options are available:
35
36
  # * <tt>:column_filters_available</tt> - (default is true) include code for the filters in the column's context menu
36
- # * <tt>:config_tool_available</tt> - (default is true) include code for the configuration tool that launches the configuration panel
37
+ # * (TODO)<tt>:config_tool_available</tt> - (default is true) include code for the configuration tool that launches the configuration panel
37
38
  # * <tt>:edit_in_form_available</tt> - (defaults to true) include code for (multi-record) editing and adding records through a form
38
39
  # * <tt>:extended_search_available</tt> - (defaults to true) include code for extended configurable search
39
40
  # * <tt>:default_config</tt> - a hash of default configuration options for each instance of the GridPanel component.
40
41
  # See the "Instance configuration" section below.
41
- #
42
+ #
42
43
  # == Instance configuration
43
44
  # The following config options are available:
44
45
  # * <tt>:model</tt> - name of the ActiveRecord model that provides data to this GridPanel.
45
46
  # * <tt>:strong_default_attrs</tt> - a hash of attributes to be merged atop of every created/updated record.
46
- # * <tt>:query</tt> - specifies how the data should be filtered.
47
- # When it's a symbol, it's used as a scope name.
48
- # When it's a string, it's a SQL statement (passed directly to +where+).
49
- # When it's a hash, it's a conditions hash (passed directly to +where+).
50
- # When it's an array, it's expanded into SQL statement with arguments (passed directly to +where+), e.g.:
51
- #
47
+ # * <tt>:scope</tt> - specifies how the data should be filtered.
48
+ # When it's a symbol, it's used as a scope name.
49
+ # When it's a string, it's a SQL statement (passed directly to +where+).
50
+ # When it's a hash, it's a conditions hash (passed directly to +where+).
51
+ # When it's an array, it's expanded into an SQL statement with arguments (passed directly to +where+), e.g.:
52
+ #
52
53
  # :query => ["id > ?", 100])
53
- #
54
+ #
54
55
  # When it's a Proc, it's passed the model class, and is expected to return a ActiveRecord::Relation, e.g.:
55
- #
56
- # :query => { |klass| klass.where(:id.gt => 100).order(:created_at) }
57
- #
56
+ #
57
+ # :query => { |klass| klass.where(:id.gt => 100).order(:created_at) }
58
+ #
58
59
  # * <tt>:enable_column_filters</tt> - enable filters in column's context menu
59
60
  # * <tt>:enable_edit_in_form</tt> - provide buttons into the toolbar that activate editing/adding records via a form
60
61
  # * <tt>:enable_extended_search</tt> - provide a button into the toolbar that shows configurable search form
@@ -63,66 +64,40 @@ module Netzke
63
64
  # * <tt>:enable_pagination</tt> - enable pagination; defaults to <tt>true</tt>
64
65
  # * <tt>:rows_per_page</tt> - number of rows per page (ignored when <tt>:enable_pagination</tt> is set to <tt>false</tt>)
65
66
  # * <tt>:load_inline_data</tt> - load initial data into the grid right after its instantiation (saves a request to server); defaults to <tt>true</tt>
66
- # * <tt>:mode</tt> - when set to <tt>:config</tt>, GridPanel loads in configuration mode
67
+ # * (TODO) <tt>:mode</tt> - when set to <tt>:config</tt>, GridPanel loads in configuration mode
67
68
  # * <tt>:add/edit/multi_edit/search_form_config</tt> - additional configuration for add/edit/multi_edit/search form panel
68
69
  # * <tt>:add/edit/multi_edit_form_window_config</tt> - additional configuration for the window that wrapps up add/edit/multi_edit form panel
69
- #
70
- # Additionally supports Netzke::Base config options.
71
- #
72
- # == Columns
73
- # Here's how the GridPanel decides which columns in which sequence and with which configuration to display.
74
- # First, the column configs are aquired from this GridPanel's persistent storage, as an array of hashes, each
75
- # representing a column configuration, such as:
76
- #
77
- # {:name => :created_at, :header => "Created", :tooltip => "When the record was created"}
78
- #
79
- # This hash *overrides* (deep_merge) the hard-coded configuration, an example of which can be specifying
80
- # columns for a GridPanel instance, e.g.:
81
- #
82
- # :columns => [{:name => :created_at, :sortable => false}]
83
- #
84
- # ... which in its turn overrides the defaults provided by persistent storage managed by the AttributesConfigurator
85
- # that provides *model-level* (as opposed to a component-level) configuration of a database model
86
- # (which is used by both grids and forms in Netzke).
87
- # And lastly, the defaults for AttributesConfigurator are calculated from the database model itself (extended by Netzke).
88
- # For example, in the model you can specify virtual attributes and their types that will be picked up by Netzke, the default
89
- # order of columns, or excluded columns. For details see <tt>Netzke::ActiveRecord::Attributes</tt>.
70
+ # * <tt>:columns</tt> - an array of columns to be displayed in the grid; each column may be represented by a symbol (representing the model's attribute name), or a hash (when extra configuration is needed)
90
71
  #
72
+ # == Columns
91
73
  # Each column supports the option :sorting_scope, which defines a scope used for sorting the column. This option would be
92
74
  # useful for virtual columns for example. The scope will get one parameter which contains the direction (:asc or :desc)
93
75
  # Example:
94
- # { :name => complete_user_name, :sorting_scope => :sort_user_by_full_name }
76
+ # { :name => "complete_user_name", :sorting_scope => :sort_user_by_full_name }
95
77
  # class User < ActiveRecord::Base
96
78
  # scope :sort_user_by_full_name, lambda { |dir|
97
79
  # order("users.first_name #{dir.to_s}, users.last_name #{dir.to_s}")
98
80
  # }
99
81
  # end
100
- #
101
- # The columns are displayed in the order specified by what's found first in the following sequence:
102
- # GridPanel instance's persistent storage
103
- # hardcoded config
104
- # AttributesConfigurator persistent storage
105
- # netzke_expose_attributes in the database model
106
- # database columns + (eventually) virtual attributes specified with netzke_attribute
107
82
  class GridPanel < Netzke::Base
108
83
  # Class-level configuration. These options directly influence the amount of generated
109
- # javascript code for this component's class. For example, if you don't want filters for the grid,
84
+ # javascript code for this component's class. For example, if you don't want filters for the grid,
110
85
  # set column_filters_available to false, and the javascript for the filters won't be included at all.
111
86
  class_attribute :column_filters_available
112
87
  self.column_filters_available = true
113
-
88
+
114
89
  class_attribute :config_tool_available
115
90
  self.config_tool_available = true
116
-
91
+
117
92
  class_attribute :edit_in_form_available
118
93
  self.edit_in_form_available = true
119
-
94
+
120
95
  class_attribute :extended_search_available
121
96
  self.extended_search_available = true
122
-
97
+
123
98
  class_attribute :rows_reordering_available
124
99
  self.rows_reordering_available = true
125
-
100
+
126
101
  class_attribute :default_config
127
102
  self.default_config = {
128
103
  :enable_edit_in_form => true,
@@ -134,52 +109,52 @@ module Netzke
134
109
  :rows_per_page => 25,
135
110
  :tools => %w{ refresh },
136
111
  }
137
-
112
+
138
113
  include self::Javascript
139
114
  include self::Services
140
115
  include self::Columns
141
-
116
+
142
117
  include Netzke::DataAccessor
143
-
118
+
144
119
  # def self.enforce_config_consistency
145
120
  # default_config[:enable_edit_in_form] &&= edit_in_form_available
146
121
  # default_config[:enable_extended_search] &&= extended_search_available
147
122
  # default_config[:enable_rows_reordering] &&= rows_reordering_available
148
123
  # end
149
-
124
+
150
125
  # def initialize(*args)
151
126
  # # Deprecations
152
127
  # config[:scopes] && ActiveSupport::Deprecation.warn(":scopes option is not effective any longer for GridPanel. Use :scope instead.")
153
- #
128
+ #
154
129
  # super(*args)
155
130
  # end
156
131
 
157
132
  # Include extra javascript that we depend on
158
133
  def self.include_js
159
134
  res = ["#{File.dirname(__FILE__)}/grid_panel/javascripts/pre.js"]
160
-
135
+
161
136
  # Optional edit in form functionality
162
137
  res << "#{File.dirname(__FILE__)}/grid_panel/javascripts/edit_in_form.js" if edit_in_form_available
163
-
138
+
164
139
  # Optional extended search functionality
165
140
  res << "#{File.dirname(__FILE__)}/grid_panel/javascripts/advanced_search.js" if extended_search_available
166
-
141
+
167
142
  ext_examples = Netzke::Core.ext_location.join("examples")
168
-
143
+
169
144
  # Checkcolumn
170
145
  res << ext_examples.join("ux/CheckColumn.js")
171
-
146
+
172
147
  # Filters
173
148
  if column_filters_available
174
149
  res << ext_examples + "ux/gridfilters/menu/ListMenu.js"
175
150
  res << ext_examples + "ux/gridfilters/menu/RangeMenu.js"
176
151
  res << ext_examples + "ux/gridfilters/GridFilters.js"
177
-
152
+
178
153
  %w{Boolean Date List Numeric String}.unshift("").each do |f|
179
154
  res << ext_examples + "ux/gridfilters/filter/#{f}Filter.js"
180
155
  end
181
156
  end
182
-
157
+
183
158
  # DD
184
159
  if rows_reordering_available
185
160
  res << "#{File.dirname(__FILE__)}/grid_panel/javascripts/rows-dd.js"
@@ -202,27 +177,27 @@ module Netzke
202
177
  # {:name => :ext_config__prohibit_read, :attr_type => :boolean}
203
178
  ]
204
179
  end
205
-
206
-
180
+
181
+
207
182
  def default_bbar
208
183
  res = %w{ add edit apply del }.map(&:to_sym).map(&:action)
209
184
  res << "-" << :add_in_form.action << :edit_in_form.action if config[:enable_edit_in_form]
210
185
  res << "-" << :search.action if config[:enable_extended_search]
211
186
  # config[:enable_extended_search] && res << "-" << {
212
- # :text => "Search",
213
- # :handler => :on_search,
214
- # :enable_toggle => true,
187
+ # :text => "Search",
188
+ # :handler => :on_search,
189
+ # :enable_toggle => true,
215
190
  # :icon => :find
216
191
  # }
217
192
  res
218
193
  end
219
-
194
+
220
195
  def default_context_menu
221
196
  res = %w{ edit del }.map(&:to_sym).map(&:action)
222
197
  res << "-" << :edit_in_form.action if config[:enable_edit_in_form]
223
198
  res
224
199
  end
225
-
200
+
226
201
  def configuration_components
227
202
  res = []
228
203
  res << {
@@ -244,48 +219,55 @@ module Netzke
244
219
  action :add do
245
220
  {
246
221
  :text => I18n.t('netzke.basepack.grid_panel.add', :default => "Add"),
222
+ :tooltip => I18n.t('netzke.basepack.grid_panel.add', :default => "Add"),
247
223
  :disabled => config[:prohibit_create],
248
224
  :icon => :add
249
225
  }
250
226
  end
251
-
227
+
252
228
  action :edit, {
253
229
  :text => I18n.t('netzke.basepack.grid_panel.edit', :default => "Edit"),
230
+ :tooltip => I18n.t('netzke.basepack.grid_panel.edit', :default => "Edit"),
254
231
  :disabled => true,
255
232
  :icon => :table_edit
256
233
  }
257
-
234
+
258
235
  action :del, {
259
236
  :text => I18n.t('netzke.basepack.grid_panel.delete', :default => "Delete"),
237
+ :tooltip => I18n.t('netzke.basepack.grid_panel.delete', :default => "Delete"),
260
238
  :disabled => true,
261
239
  :icon => :table_row_delete
262
240
  }
263
-
241
+
264
242
  action :apply do
265
243
  {
266
244
  :text => I18n.t('netzke.basepack.grid_panel.apply', :default => "Apply"),
245
+ :tooltip => I18n.t('netzke.basepack.grid_panel.apply', :default => "Apply"),
267
246
  :disabled => config[:prohibit_update] && config[:prohibit_create],
268
247
  :icon => :tick
269
248
  }
270
249
  end
271
-
250
+
272
251
  action :add_in_form, {
273
252
  :text => I18n.t('netzke.basepack.grid_panel.add_in_form', :default => "Add in form"),
253
+ :tooltip => I18n.t('netzke.basepack.grid_panel.add_in_form', :default => "Add in form"),
274
254
  :icon => :application_form_add
275
255
  }
276
-
256
+
277
257
  action :edit_in_form, {
278
258
  :text => I18n.t('netzke.basepack.grid_panel.edit_in_form', :default => "Edit in form"),
259
+ :tooltip => I18n.t('netzke.basepack.grid_panel.edit_in_form', :default => "Edit in form"),
279
260
  :disabled => true,
280
261
  :icon => :application_form_edit
281
262
  }
282
-
263
+
283
264
  action :search, {
284
265
  :text => I18n.t('netzke.basepack.grid_panel.search', :default => "Search"),
285
- :enable_toggle => true,
266
+ :tooltip => I18n.t('netzke.basepack.grid_panel.search', :default => "Search"),
267
+ :enable_toggle => true,
286
268
  :icon => :find
287
269
  }
288
-
270
+
289
271
  component :add_form do
290
272
  {
291
273
  :lazy_loading => true,
@@ -325,7 +307,7 @@ module Netzke
325
307
  }.deep_merge(config[:edit_form_config] || {})]
326
308
  }.deep_merge(config[:edit_form_window_config] || {})
327
309
  end
328
-
310
+
329
311
  component :multi_edit_form do
330
312
  {
331
313
  :lazy_loading => true,
@@ -352,8 +334,8 @@ module Netzke
352
334
  :fields => default_fields_for_forms
353
335
  }
354
336
  end
355
-
356
-
337
+
338
+
357
339
  # def search_panel
358
340
  # {
359
341
  # :class_name => "Basepack::FormPanel",
@@ -368,7 +350,7 @@ module Netzke
368
350
  # end
369
351
 
370
352
  # include ::Netzke::Plugins::ConfigurationTool if config_tool_available # it will load ConfigurationPanel into a modal window
371
-
353
+
372
354
  end
373
355
  end
374
356
  end