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.
- data/CHANGELOG.rdoc +14 -6
- data/README.rdoc +16 -31
- data/Rakefile +22 -16
- data/TODO.rdoc +1 -1
- data/app/models/netzke_field_list.rb +29 -29
- data/app/models/netzke_model_attr_list.rb +4 -4
- data/app/models/netzke_persistent_array_auto_model.rb +9 -9
- data/config/database.yml +2 -35
- data/features/accordion_panel.feature +1 -1
- data/features/form_panel.feature +2 -2
- data/features/grid_panel.feature +15 -3
- data/features/search_in_grid.feature +4 -4
- data/features/simple_panel.feature +4 -4
- data/features/step_definitions/pickle_steps.rb +2 -2
- data/features/step_definitions/web_steps.rb +5 -5
- data/features/support/env.rb +6 -6
- data/features/tab_panel.feature +1 -1
- data/javascripts/basepack.js +28 -28
- data/lib/netzke-basepack.rb +5 -5
- data/lib/netzke/active_record.rb +1 -1
- data/lib/netzke/active_record/association_attributes.rb +9 -9
- data/lib/netzke/active_record/attributes.rb +24 -23
- data/lib/netzke/active_record/combobox_options.rb +3 -3
- data/lib/netzke/active_record/relation_extensions.rb +4 -4
- data/lib/netzke/basepack.rb +4 -4
- data/{app/components → lib}/netzke/basepack/accordion_panel.rb +7 -7
- data/{app/components → lib}/netzke/basepack/basic_app.rb +18 -18
- data/{app/components → lib}/netzke/basepack/basic_app/statusbar_ext.js +0 -0
- data/lib/netzke/basepack/border_layout_panel.rb +101 -0
- data/{app/components → lib}/netzke/basepack/form_panel.rb +21 -21
- data/{app/components → lib}/netzke/basepack/form_panel/fields.rb +29 -36
- data/{app/components → lib}/netzke/basepack/form_panel/javascripts/netzkefileupload.js +0 -0
- data/{app/components → lib}/netzke/basepack/form_panel/javascripts/pre.js +9 -9
- data/{app/components → lib}/netzke/basepack/form_panel/javascripts/xcheckbox.js +1 -1
- data/{app/components → lib}/netzke/basepack/form_panel/services.rb +11 -11
- data/{app/components → lib}/netzke/basepack/grid_panel.rb +74 -92
- data/{app/components → lib}/netzke/basepack/grid_panel/columns.rb +34 -36
- data/{app/components → lib}/netzke/basepack/grid_panel/javascript.rb +7 -7
- data/{app/components → lib}/netzke/basepack/grid_panel/javascripts/advanced_search.js +10 -10
- data/{app/components → lib}/netzke/basepack/grid_panel/javascripts/edit_in_form.js +2 -2
- data/{app/components → lib}/netzke/basepack/grid_panel/javascripts/pre.js +31 -31
- data/{app/components → lib}/netzke/basepack/grid_panel/javascripts/rows-dd.js +1 -1
- data/{app/components → lib}/netzke/basepack/grid_panel/multi_edit_form.rb +2 -2
- data/{app/components → lib}/netzke/basepack/grid_panel/record_form_window.rb +3 -3
- data/{app/components → lib}/netzke/basepack/grid_panel/search_window.rb +11 -11
- data/{app/components → lib}/netzke/basepack/grid_panel/services.rb +28 -28
- data/{app/components → lib}/netzke/basepack/panel.rb +0 -0
- data/{app/components → lib}/netzke/basepack/search_panel.rb +11 -11
- data/{app/components → lib}/netzke/basepack/tab_panel.rb +7 -7
- data/lib/netzke/basepack/version.rb +1 -1
- data/{app/components → lib}/netzke/basepack/window.rb +14 -14
- data/{app/components → lib}/netzke/basepack/wrapper.rb +6 -6
- data/lib/netzke/data_accessor.rb +18 -18
- data/lib/netzke/fields_configurator.rb +30 -30
- data/lib/netzke/json_array_editor.rb +9 -9
- data/lib/netzke/masquerade_selector.rb +5 -5
- data/locale/en.yml +1 -1
- data/netzke-basepack.gemspec +252 -240
- data/spec/active_record/attributes_spec.rb +6 -1
- data/spec/active_record/relation_extensions_spec.rb +11 -11
- data/spec/components/form_panel_spec.rb +13 -19
- data/spec/components/grid_panel_spec.rb +1 -1
- data/test/rails_app/Gemfile +4 -3
- data/test/rails_app/Gemfile.lock +42 -50
- data/test/rails_app/app/components/book_grid.rb +4 -0
- data/test/rails_app/app/components/generic_user_form.rb +2 -2
- data/test/rails_app/app/components/simple_basic_app.rb +3 -3
- data/test/rails_app/app/components/simple_panel.rb +1 -1
- data/test/rails_app/app/components/some_border_layout.rb +12 -11
- data/test/rails_app/app/components/some_search_panel.rb +5 -5
- data/test/rails_app/app/components/user_form.rb +1 -1
- data/test/rails_app/app/components/window_component_loader.rb +2 -2
- data/test/rails_app/app/models/author.rb +7 -0
- data/test/rails_app/app/models/book.rb +3 -0
- data/test/rails_app/app/models/user.rb +1 -1
- data/test/rails_app/config/locales/es.yml +0 -1
- data/test/rails_app/config/routes.rb +2 -2
- data/test/rails_app/db/development_structure.sql +28 -3
- data/test/rails_app/db/migrate/20101026185816_create_authors.rb +14 -0
- data/test/rails_app/db/migrate/20101026190021_create_books.rb +17 -0
- data/test/rails_app/db/schema.rb +18 -1
- data/test/rails_app/public/javascripts/effects.js +1 -1
- data/test/rails_app/spec/models/author_spec.rb +5 -0
- data/test/rails_app/spec/models/book_spec.rb +5 -0
- data/test/test_helper.rb +1 -1
- data/test/unit/accordion_panel_test.rb +2 -2
- data/test/unit/active_record_basepack_test.rb +9 -9
- data/test/unit/fields_configuration_test.rb +4 -4
- data/test/unit/grid_panel_test.rb +8 -8
- data/test/unit/tab_panel_test.rb +2 -2
- metadata +49 -36
- data/.gitignore +0 -10
- 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].
|
|
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
|
|
File without changes
|
|
@@ -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
|
-
#
|
|
10
|
-
#
|
|
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
|
|
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
|
-
#
|
|
26
|
-
#
|
|
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
|
|
32
|
-
#
|
|
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>:
|
|
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
|
-
:
|
|
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
|