netzke-basepack 0.6.0 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
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