netzke-basepack 0.6.5 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +7 -4
- data/README.md +63 -0
- data/Rakefile +4 -4
- data/javascripts/basepack.js +113 -133
- data/lib/netzke-basepack.rb +9 -2
- data/lib/netzke/basepack.rb +9 -6
- data/lib/netzke/basepack/accordion_panel.rb +1 -1
- data/lib/netzke/basepack/auth_app.rb +28 -21
- data/lib/netzke/basepack/border_layout_panel.rb +9 -57
- data/lib/netzke/basepack/border_layout_panel/javascripts/border_layout_panel.js +40 -0
- data/lib/netzke/basepack/data_accessor.rb +3 -5
- data/lib/netzke/basepack/form_panel.rb +55 -52
- data/lib/netzke/basepack/form_panel/fields.rb +4 -2
- data/lib/netzke/basepack/form_panel/javascripts/comma_list_cbg.js +13 -28
- data/lib/netzke/basepack/form_panel/javascripts/form_panel.js +61 -34
- data/lib/netzke/basepack/form_panel/javascripts/n_radio_group.js +4 -3
- data/lib/netzke/basepack/form_panel/javascripts/readonly_mode.js +10 -10
- data/lib/netzke/basepack/form_panel/services.rb +1 -1
- data/lib/netzke/basepack/grid_panel.rb +23 -17
- data/lib/netzke/basepack/grid_panel/columns.rb +116 -71
- data/lib/netzke/basepack/grid_panel/javascripts/advanced_search.js +5 -7
- data/lib/netzke/basepack/grid_panel/javascripts/check_column_fix.js +6 -0
- data/lib/netzke/basepack/grid_panel/javascripts/edit_in_form.js +18 -15
- data/lib/netzke/basepack/grid_panel/javascripts/event_handling.js +178 -0
- data/lib/netzke/basepack/grid_panel/javascripts/grid_panel.js +230 -454
- data/lib/netzke/basepack/grid_panel/javascripts/rows-dd.js +1 -0
- data/lib/netzke/basepack/grid_panel/record_form_window.rb +8 -8
- data/lib/netzke/basepack/grid_panel/services.rb +12 -15
- data/lib/netzke/basepack/paging_form_panel.rb +1 -82
- data/lib/netzke/basepack/paging_form_panel/javascripts/paging_form_panel.js +76 -0
- data/lib/netzke/basepack/query_builder.rb +4 -4
- data/lib/netzke/basepack/query_builder/javascripts/query_builder.js +7 -4
- data/lib/netzke/basepack/search_panel.rb +1 -1
- data/lib/netzke/basepack/search_panel/javascripts/condition_field.js +27 -20
- data/lib/netzke/basepack/search_panel/javascripts/search_panel.js +4 -4
- data/lib/netzke/basepack/search_window.rb +4 -4
- data/lib/netzke/basepack/simple_app.rb +36 -8
- data/lib/netzke/basepack/simple_app/javascripts/simple_app.js +27 -16
- data/lib/netzke/basepack/tab_panel/javascripts/tab_panel.js +1 -1
- data/lib/netzke/basepack/version.rb +2 -2
- data/lib/netzke/basepack/window.rb +2 -45
- data/lib/netzke/basepack/window/javascripts/window.js +18 -0
- data/lib/netzke/basepack/wrap_lazy_loaded.rb +1 -1
- data/locales/de.yml +79 -0
- data/locales/en.yml +0 -10
- data/netzke-basepack.gemspec +32 -19
- data/stylesheets/basepack.css +16 -16
- data/test/rails_app/.gitignore +1 -0
- data/test/rails_app/Gemfile +9 -5
- data/test/rails_app/Gemfile.lock +51 -49
- data/test/rails_app/app/components/author_form.rb +32 -0
- data/test/rails_app/app/components/book_form.rb +6 -4
- data/test/rails_app/app/components/book_grid.rb +4 -3
- data/test/rails_app/app/components/book_grid_loader.rb +2 -2
- data/test/rails_app/app/components/book_grid_with_custom_columns.rb +11 -5
- data/test/rails_app/app/components/book_grid_with_default_values.rb +1 -1
- data/test/rails_app/app/components/book_grid_with_extra_feedback.rb +11 -0
- data/test/rails_app/app/components/book_grid_with_extra_filters.rb +14 -0
- data/test/rails_app/app/components/book_grid_with_paging.rb +10 -0
- data/test/rails_app/app/components/book_grid_with_persistence.rb +6 -0
- data/test/rails_app/app/components/book_paging_form_panel.rb +3 -3
- data/test/rails_app/app/components/book_with_custom_primary_key_grid.rb +10 -0
- data/test/rails_app/app/components/form_without_model.rb +5 -4
- data/test/rails_app/app/components/paging_form_with_search.rb +3 -2
- data/test/rails_app/app/components/some_auth_app.rb +3 -3
- data/test/rails_app/app/components/some_border_layout.rb +2 -2
- data/test/rails_app/app/components/some_simple_app.rb +6 -5
- data/test/rails_app/app/components/window_component_loader.rb +11 -2
- data/test/rails_app/app/controllers/components_controller.rb +1 -1
- data/test/rails_app/app/models/book_with_custom_primary_key.rb +4 -0
- data/test/rails_app/config/initializers/netzke.rb +6 -0
- data/test/rails_app/config/locales/es.yml +0 -10
- data/test/rails_app/db/migrate/20110701070052_create_book_with_custom_primary_keys.rb +15 -0
- data/test/rails_app/db/schema.rb +12 -2
- data/test/rails_app/db/seeds.rb +21 -1
- data/test/rails_app/features/form_panel.feature +17 -17
- data/test/rails_app/features/grid_panel.feature +20 -4
- data/test/rails_app/features/grid_panel_with_custom_primary_key.feature +15 -0
- data/test/rails_app/features/paging_form_panel.feature +14 -0
- data/test/rails_app/features/search_in_grid.feature +2 -1
- data/test/rails_app/features/simple_app.feature +5 -0
- data/test/rails_app/features/step_definitions/accordion_steps.rb +1 -5
- data/test/rails_app/features/step_definitions/ext_steps.rb +16 -0
- data/test/rails_app/features/step_definitions/form_panel_steps.rb +10 -12
- data/test/rails_app/features/step_definitions/generic_steps.rb +12 -4
- data/test/rails_app/features/step_definitions/grid_panel_steps.rb +47 -32
- data/test/rails_app/features/tab_panel.feature +2 -2
- data/test/rails_app/spec/factories.rb +4 -0
- metadata +26 -13
- data/README.rdoc +0 -67
- data/from_05_to_06.rdoc +0 -2
- data/javascripts/feedback_ghost.js +0 -34
- data/test/rails_app/public/netzke/basepack/ts-checkbox.gif +0 -0
@@ -1,6 +1,10 @@
|
|
1
1
|
module Netzke
|
2
2
|
module Basepack
|
3
|
-
# Panel with border layout
|
3
|
+
# Panel with border layout.
|
4
|
+
#
|
5
|
+
# == Features
|
6
|
+
# * When persistence enabled, remembers the sizes and collapsed/expanded states of its regions.
|
7
|
+
#
|
4
8
|
# == Example configuration:
|
5
9
|
#
|
6
10
|
# :items => [
|
@@ -8,13 +12,15 @@ module Netzke
|
|
8
12
|
# {:title => "Item Two", :class_name => "Basepack::Panel", :region => :west, :width => 300, :split => true}
|
9
13
|
# ]
|
10
14
|
class BorderLayoutPanel < Netzke::Base
|
15
|
+
js_mixin :border_layout_panel
|
16
|
+
|
11
17
|
def items
|
12
18
|
@border_layout_items ||= begin
|
13
19
|
updated_items = super
|
14
20
|
|
15
21
|
if config[:persistence]
|
16
22
|
updated_items.each do |item|
|
17
|
-
region = item[:region] || components[item[:
|
23
|
+
region = item[:region] || components[item[:netzke_component]][:region]
|
18
24
|
item.merge!({
|
19
25
|
:width => state[:"#{region}_region_width"],
|
20
26
|
:height => state[:"#{region}_region_height"],
|
@@ -22,64 +28,10 @@ module Netzke
|
|
22
28
|
})
|
23
29
|
end
|
24
30
|
end
|
25
|
-
|
31
|
+
|
26
32
|
updated_items
|
27
33
|
end
|
28
34
|
end
|
29
|
-
|
30
|
-
js_property :layout, :border
|
31
|
-
|
32
|
-
js_method :init_component, <<-JS
|
33
|
-
function(){
|
34
|
-
Ext.each(['center', 'west', 'east', 'south', 'north'], function(r){
|
35
|
-
// A function to access a region component (even if the component gets reloaded, the function will work).
|
36
|
-
// E.g.: getEastComponent()
|
37
|
-
var methodName = 'get'+r.capitalize()+'Component';
|
38
|
-
this[methodName] = function(){
|
39
|
-
Netzke.deprecationWarning("Instead of '" + methodName + "' use getChildComponent('<name of your component>').");
|
40
|
-
return this.find('region', r)[0];
|
41
|
-
}.createDelegate(this);
|
42
|
-
}, this);
|
43
|
-
|
44
|
-
// Now let Ext.Panel do the rest
|
45
|
-
#{js_full_class_name}.superclass.initComponent.call(this);
|
46
|
-
|
47
|
-
// First time on "afterlayout", set resize events
|
48
|
-
if (this.persistence) {this.on('afterlayout', this.setRegionEvents, this, {single: true});}
|
49
|
-
}
|
50
|
-
JS
|
51
|
-
|
52
|
-
js_method :set_region_events, <<-JS
|
53
|
-
function(){
|
54
|
-
this.items.each(function(item, index, length){
|
55
|
-
if (!item.oldSize) item.oldSize = item.getSize(); // remember initial size
|
56
|
-
|
57
|
-
item.on('resize', function(panel, w, h){
|
58
|
-
if (panel.region !== 'center' && w && h) {
|
59
|
-
var params = {region:panel.region};
|
60
|
-
|
61
|
-
if (panel.oldSize.width != w) {
|
62
|
-
params.width = w;
|
63
|
-
} else {
|
64
|
-
params.height = h;
|
65
|
-
}
|
66
|
-
|
67
|
-
panel.oldSize = panel.getSize();
|
68
|
-
this.regionResized(params);
|
69
|
-
}
|
70
|
-
}, this);
|
71
|
-
|
72
|
-
item.on('collapse', function(panel){
|
73
|
-
this.regionCollapsed({region: panel.region});
|
74
|
-
}, this);
|
75
|
-
|
76
|
-
item.on('expand', function(panel){
|
77
|
-
this.regionExpanded({region: panel.region});
|
78
|
-
}, this);
|
79
|
-
|
80
|
-
}, this);
|
81
|
-
}
|
82
|
-
JS
|
83
35
|
|
84
36
|
endpoint :region_resized do |params|
|
85
37
|
size_state_hash = {}
|
@@ -0,0 +1,40 @@
|
|
1
|
+
{
|
2
|
+
layout: 'border',
|
3
|
+
|
4
|
+
initComponent: function(){
|
5
|
+
this.callParent();
|
6
|
+
|
7
|
+
// First time on "afterlayout", set resize events
|
8
|
+
if (this.persistence) {this.on('afterlayout', this.setRegionEvents, this, {single: true});}
|
9
|
+
},
|
10
|
+
|
11
|
+
setRegionEvents: function(){
|
12
|
+
this.items.each(function(item, index, length){
|
13
|
+
if (!item.oldSize) item.oldSize = item.getSize(); // remember initial size
|
14
|
+
|
15
|
+
item.on('resize', function(panel, w, h){
|
16
|
+
if (panel.region !== 'center' && w && h) {
|
17
|
+
var params = {region:panel.region};
|
18
|
+
|
19
|
+
if (panel.oldSize.width != w) {
|
20
|
+
params.width = w;
|
21
|
+
} else {
|
22
|
+
params.height = h;
|
23
|
+
}
|
24
|
+
|
25
|
+
panel.oldSize = panel.getSize();
|
26
|
+
this.regionResized(params);
|
27
|
+
}
|
28
|
+
}, this);
|
29
|
+
|
30
|
+
item.on('collapse', function(panel){
|
31
|
+
this.regionCollapsed({region: panel.region});
|
32
|
+
}, this);
|
33
|
+
|
34
|
+
item.on('expand', function(panel){
|
35
|
+
this.regionExpanded({region: panel.region});
|
36
|
+
}, this);
|
37
|
+
|
38
|
+
}, this);
|
39
|
+
}
|
40
|
+
}
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'netzke/active_record'
|
2
|
-
|
3
1
|
module Netzke
|
4
2
|
module Basepack
|
5
3
|
# This module is included into such data-driven components as GridPanel, FormPanel, PagingFormPanel, etc.
|
@@ -14,7 +12,7 @@ module Netzke
|
|
14
12
|
if options
|
15
13
|
query ? options.select{ |o| o.index(/^#{query}/) }.map{ |el| [el] } : options
|
16
14
|
else
|
17
|
-
assoc, assoc_method =
|
15
|
+
assoc, assoc_method = assoc_and_assoc_method_for_attr(column)
|
18
16
|
|
19
17
|
if assoc
|
20
18
|
# Options for an asssociation attribute
|
@@ -66,7 +64,7 @@ module Netzke
|
|
66
64
|
end
|
67
65
|
|
68
66
|
# Returns association and association method for a column
|
69
|
-
def
|
67
|
+
def assoc_and_assoc_method_for_attr(c)
|
70
68
|
assoc_name, assoc_method = c[:name].split('__')
|
71
69
|
assoc = data_class.reflect_on_association(assoc_name.to_sym) if assoc_method
|
72
70
|
[assoc, assoc_method]
|
@@ -100,7 +98,7 @@ module Netzke
|
|
100
98
|
# Mark an attribute as "virtual" by default, when it doesn't reflect a model column, or a model column of an association
|
101
99
|
def set_default_virtual(c)
|
102
100
|
if c[:virtual].nil? # sometimes at maybe handy to mark a column as non-virtual forcefully
|
103
|
-
assoc, assoc_method =
|
101
|
+
assoc, assoc_method = assoc_and_assoc_method_for_attr(c)
|
104
102
|
if assoc
|
105
103
|
c[:virtual] = true if !assoc.klass.column_names.map(&:to_sym).include?(assoc_method.to_sym)
|
106
104
|
else
|
@@ -4,22 +4,23 @@ require "netzke/basepack/form_panel/services"
|
|
4
4
|
|
5
5
|
module Netzke
|
6
6
|
module Basepack
|
7
|
-
# Ext.form.
|
7
|
+
# Ext.form.Panel-based component
|
8
8
|
#
|
9
9
|
# == Configuration
|
10
|
-
# Besides all the standard +Ext.form.FormPanel+ config options, accepts:
|
11
10
|
# * +model+ - name of the ActiveRecord model that provides data to this GridPanel.
|
12
11
|
# * +record+ - record to be displayd in the form. Takes precedence over +:record_id+
|
13
12
|
# * +record_id+ - id of the record to be displayd in the form. Also see +:record+
|
13
|
+
# * +items+ - the layout of the fields as an array. See "Layout configuration".
|
14
14
|
# * +mode+ - render mode, accepted options:
|
15
15
|
# * +lockable+ - makes the form panel load initially in "display mode", then lets "unlock" it, change the values, and "lock" it again, while updating the values on the server
|
16
16
|
# * +updateMask+ - +Ext.LoadMask+ config options for the mask shown while the form is submitting its values
|
17
|
+
# Besides, FormPanel can accept any meaninful :
|
17
18
|
#
|
18
19
|
# === Layout configuration
|
19
20
|
# The layout of the form is configured by supplying the +item+ config option, same way it would be configured in Ext (thus allowing for complex form layouts). FormPanel will expand fields by looking at their names (unless +no_binding+ set to +true+ is specified for a specific field).
|
20
21
|
class FormPanel < Netzke::Base
|
21
22
|
|
22
|
-
js_base_class "Ext.form.
|
23
|
+
js_base_class "Ext.form.Panel"
|
23
24
|
|
24
25
|
# Class-level configuration
|
25
26
|
class_attribute :config_tool_available
|
@@ -77,10 +78,12 @@ module Netzke
|
|
77
78
|
js_include :n_radio_group, :readonly_mode
|
78
79
|
css_include :readonly_mode
|
79
80
|
|
80
|
-
|
81
|
-
|
81
|
+
# WIP
|
82
|
+
# js_include Netzke::Core.ext_path.join("examples/ux/fileuploadfield/FileUploadField.js")
|
83
|
+
# css_include Netzke::Core.ext_path.join("examples/ux/fileuploadfield/css/fileuploadfield.css")
|
82
84
|
|
83
|
-
|
85
|
+
# WIP: Needed for FileUploadField
|
86
|
+
# js_include :misc
|
84
87
|
|
85
88
|
def js_config
|
86
89
|
super.tap do |res|
|
@@ -98,61 +101,61 @@ module Netzke
|
|
98
101
|
@record ||= config[:record] || config[:record_id] && data_class && data_class.where(data_class.primary_key => config[:record_id]).first
|
99
102
|
end
|
100
103
|
|
101
|
-
def configuration_components
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
104
|
+
# def configuration_components
|
105
|
+
# res = []
|
106
|
+
#
|
107
|
+
# res << {
|
108
|
+
# :name => 'fields',
|
109
|
+
# :class_name => "FieldsConfigurator",
|
110
|
+
# :active => true,
|
111
|
+
# :owner => self,
|
112
|
+
# :persistent_config => true
|
113
|
+
# }
|
114
|
+
#
|
115
|
+
# res << {
|
116
|
+
# :name => 'general',
|
117
|
+
# :class_name => "PropertyEditor",
|
118
|
+
# :component => self,
|
119
|
+
# :title => false
|
120
|
+
# }
|
121
|
+
#
|
122
|
+
# res
|
123
|
+
# end
|
124
|
+
|
125
|
+
def self.property_fields
|
126
|
+
res = [
|
127
|
+
{:name => "ext_config__title", :attr_type => :string},
|
128
|
+
{:name => "ext_config__header", :attr_type => :boolean, :default => true},
|
129
|
+
{:name => "ext_config__bbar", :attr_type => :json}
|
130
|
+
]
|
131
|
+
|
132
|
+
res
|
133
|
+
end
|
121
134
|
|
122
|
-
|
123
|
-
res = [
|
124
|
-
# {:name => "ext_config__title", :attr_type => :string},
|
125
|
-
# {:name => "ext_config__header", :attr_type => :boolean, :default => true},
|
126
|
-
# {:name => "ext_config__bbar", :attr_type => :json}
|
127
|
-
]
|
135
|
+
private
|
128
136
|
|
129
|
-
|
137
|
+
def self.server_side_config_options
|
138
|
+
super + [:record, :scope]
|
130
139
|
end
|
131
140
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
141
|
+
def meta_field
|
142
|
+
{}.tap do |res|
|
143
|
+
assoc_values = get_association_values
|
144
|
+
res[:association_values] = assoc_values.literalize_keys if record && !assoc_values.empty?
|
136
145
|
end
|
146
|
+
end
|
137
147
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
148
|
+
def get_association_values
|
149
|
+
fields_that_need_associated_values = fields.select{ |k,v| k.to_s.index("__") && !fields[k][:nested_attribute] }
|
150
|
+
# Take care of Ruby 1.8.7
|
151
|
+
if fields_that_need_associated_values.is_a?(Array)
|
152
|
+
fields_that_need_associated_values = fields_that_need_associated_values.inject({}){|r,(k,v)| r.merge(k => v)}
|
143
153
|
end
|
144
154
|
|
145
|
-
|
146
|
-
|
147
|
-
# Take care of Ruby 1.8.7
|
148
|
-
if fields_that_need_associated_values.is_a?(Array)
|
149
|
-
fields_that_need_associated_values = fields_that_need_associated_values.inject({}){|r,(k,v)| r.merge(k => v)}
|
150
|
-
end
|
151
|
-
|
152
|
-
fields_that_need_associated_values.each_pair.inject({}) do |r,(k,v)|
|
153
|
-
r.merge(k => record.value_for_attribute(fields_that_need_associated_values[k], true))
|
154
|
-
end
|
155
|
+
fields_that_need_associated_values.each_pair.inject({}) do |r,(k,v)|
|
156
|
+
r.merge(k => record.value_for_attribute(fields_that_need_associated_values[k], true))
|
155
157
|
end
|
158
|
+
end
|
156
159
|
|
157
160
|
# include ::Netzke::Plugins::ConfigurationTool if config_tool_available # it will load ConfigurationPanel into a modal window
|
158
161
|
end
|
@@ -179,9 +179,11 @@ module Netzke
|
|
179
179
|
def attr_type_to_xtype_map
|
180
180
|
{
|
181
181
|
:integer => :numberfield,
|
182
|
-
:boolean => :
|
182
|
+
:boolean => :checkboxfield,
|
183
183
|
:date => :datefield,
|
184
|
-
:datetime
|
184
|
+
# WIP: waiting for datetime.js implementation for ExtJS 4
|
185
|
+
# :datetime => :datetimefield,
|
186
|
+
|
185
187
|
:text => :textarea,
|
186
188
|
:json => :jsonfield,
|
187
189
|
:string => :textfield
|
@@ -6,52 +6,38 @@ Config options:
|
|
6
6
|
* separator - separator of values in the string (defaults to ",")
|
7
7
|
* options - all checkboxes, by boxLabel, e.g.: ["Cool", "To read", "Important"]
|
8
8
|
*/
|
9
|
-
Ext.netzke.form.CommaListCbg
|
9
|
+
Ext.define('Ext.netzke.form.CommaListCbg', {
|
10
|
+
extend: 'Ext.form.CheckboxGroup',
|
11
|
+
alias: 'widget.commalistcbg',
|
10
12
|
separator: ",",
|
11
13
|
|
12
14
|
initComponent: function(){
|
13
|
-
Ext.netzke.form.CommaListCbg.superclass.initComponent.call(this);
|
14
|
-
|
15
15
|
this.items = [];
|
16
16
|
Ext.each(this.options, function(o){
|
17
|
-
this.items.push({boxLabel: o});
|
18
|
-
}, this);
|
19
|
-
|
20
|
-
this.on('change', function(el){
|
21
|
-
this.hiddenEl.dom.value = this.getValue();
|
17
|
+
this.items.push({ boxLabel: o, displayOnly:true });
|
22
18
|
}, this);
|
23
|
-
},
|
24
19
|
|
25
|
-
|
26
|
-
Ext.netzke.form.CommaListCbg.superclass.onRender.call(this, ct, position)
|
27
|
-
this.hiddenEl = Ext.DomHelper.append(ct, {tag:'input', type: 'hidden', name: this.name}, true);
|
28
|
-
|
29
|
-
// Don't submit individual checkboxes
|
30
|
-
this.items.each(function(i){
|
31
|
-
i.el.dom.removeAttribute("name");
|
32
|
-
});
|
20
|
+
this.callParent();
|
33
21
|
},
|
34
22
|
|
35
|
-
|
36
|
-
var checkedBoxes = Ext.netzke.form.CommaListCbg.superclass.getValue.call(this);
|
23
|
+
getSubmitData: function(){
|
37
24
|
var res = [];
|
38
|
-
Ext.each(
|
39
|
-
res.push(cb.boxLabel);
|
40
|
-
});
|
25
|
+
Ext.each(this.getChecked(), function( item ){ res.push( item.boxLabel ) });
|
41
26
|
res = res.join(this.separator);
|
42
|
-
|
27
|
+
var o = {};
|
28
|
+
o[this.name]=res;
|
29
|
+
return o;
|
43
30
|
},
|
44
31
|
|
45
32
|
setValue: function(v){
|
46
33
|
if (Ext.isString(v)) {
|
47
34
|
var passedValues = v.split(this.separator);
|
48
|
-
var values = [];
|
49
35
|
this.items.each(function(i){
|
50
|
-
|
36
|
+
i.setValue( passedValues.indexOf(i.boxLabel) >= 0 );
|
51
37
|
});
|
52
|
-
|
38
|
+
// we can alse set values the Ext way
|
53
39
|
} else {
|
54
|
-
|
40
|
+
this.callParent(arguments);
|
55
41
|
}
|
56
42
|
},
|
57
43
|
|
@@ -63,4 +49,3 @@ Ext.netzke.form.CommaListCbg = Ext.extend(Ext.form.CheckboxGroup, {
|
|
63
49
|
|
64
50
|
});
|
65
51
|
|
66
|
-
Ext.reg('commalistcbg', Ext.netzke.form.CommaListCbg);
|
@@ -1,8 +1,8 @@
|
|
1
1
|
{
|
2
2
|
bodyStyle : 'padding:5px 5px 0',
|
3
3
|
autoScroll : true,
|
4
|
-
labelWidth
|
5
|
-
applyMask : {msg: "Updating..."},
|
4
|
+
fieldDefaults : { labelWidth : 150 },
|
5
|
+
applyMask : { msg: "Updating..." },
|
6
6
|
|
7
7
|
defaults : {
|
8
8
|
anchor : '-20', // to leave some space for the scrollbar
|
@@ -17,6 +17,13 @@
|
|
17
17
|
},
|
18
18
|
|
19
19
|
initComponent: function(){
|
20
|
+
// passing config options to BasicForm is possible via initialConfig only
|
21
|
+
// see Ext.form.Panel documentation
|
22
|
+
this.initialConfig = {
|
23
|
+
// form tracks it's default field values so they can be reset()
|
24
|
+
trackResetOnLoad: true,
|
25
|
+
}
|
26
|
+
|
20
27
|
if (!this.bbar) this.bbar = {xtype: 'toolbar'}; // an empty bbar by default, so that we can dynamically add buttons
|
21
28
|
|
22
29
|
// Custom error reader. We don't use it to process form values, but rather to normalize the response from the server in case of "real" (iframe) form submit.
|
@@ -32,15 +39,17 @@
|
|
32
39
|
|
33
40
|
this.initialConfig.errorReader = new ErrorReader();
|
34
41
|
|
42
|
+
// this.getForm().trackResetOnLoad = true;
|
43
|
+
|
35
44
|
// Now let Ext.form.FormPanel do the rest
|
36
|
-
|
45
|
+
this.callParent(arguments);
|
37
46
|
|
38
47
|
// To inform the parent about the apply event
|
39
|
-
this.addEvents('apply');
|
48
|
+
this.addEvents('apply', 'cancel');
|
40
49
|
},
|
41
50
|
|
42
51
|
afterRender: function(){
|
43
|
-
|
52
|
+
this.callParent();
|
44
53
|
|
45
54
|
// have a record to be displayed?
|
46
55
|
if (this.record) { this.setFormValues(this.record); }
|
@@ -54,33 +63,39 @@
|
|
54
63
|
},
|
55
64
|
|
56
65
|
onCancel: function(){
|
66
|
+
this.getForm().reset();
|
57
67
|
this.setReadonlyMode(true, true);
|
58
68
|
},
|
59
69
|
|
60
70
|
updateToolbar: function(){
|
61
|
-
var tbar = this.
|
62
|
-
|
63
|
-
if (this.inReadonlyMode) {
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
71
|
+
var tbar = this.child('toolbar');
|
72
|
+
|
73
|
+
if ( this.inReadonlyMode ) {
|
74
|
+
// if the form in readonly mode, remove "Apply" and "Cancel"
|
75
|
+
// buttons from toolbar and add "Edit" button
|
76
|
+
var buttonToRemove = tbar.child("button[name='apply']");
|
77
|
+
if ( buttonToRemove ) {
|
78
|
+
tbar.remove( buttonToRemove );
|
68
79
|
}
|
69
80
|
|
70
|
-
var
|
71
|
-
|
72
|
-
|
73
|
-
tbar.remove(buttonToRemove);
|
81
|
+
var buttonToRemove = tbar.child("button[name='cancel']");
|
82
|
+
if ( buttonToRemove ) {
|
83
|
+
tbar.remove( buttonToRemove );
|
74
84
|
}
|
75
|
-
|
85
|
+
|
86
|
+
tbar.add( this.actions.edit );
|
87
|
+
|
76
88
|
} else {
|
89
|
+
// if the form editable, remove "edit" button and
|
90
|
+
// insert "apply" and "cancel" instead
|
91
|
+
|
77
92
|
var buttonIndex = tbar.items.findIndex("name", "edit");
|
78
|
-
var buttonToRemove = tbar.items.
|
93
|
+
var buttonToRemove = tbar.items.getAt(buttonIndex);
|
79
94
|
if (buttonToRemove) {
|
80
95
|
tbar.remove(buttonToRemove);
|
81
96
|
}
|
82
|
-
tbar.
|
83
|
-
tbar.
|
97
|
+
tbar.insert( buttonIndex, this.actions.cancel );
|
98
|
+
tbar.insert( buttonIndex, this.actions.apply );
|
84
99
|
}
|
85
100
|
|
86
101
|
tbar.doLayout();
|
@@ -88,33 +103,40 @@
|
|
88
103
|
|
89
104
|
onApply: function() {
|
90
105
|
if (this.fireEvent('apply', this)) {
|
91
|
-
var values = this.getForm().
|
92
|
-
|
106
|
+
var values = this.getForm().getValues();
|
93
107
|
for (var fieldName in values) {
|
94
108
|
var field = this.getForm().findField(fieldName);
|
95
109
|
|
96
110
|
// TODO: move the following checks to the server side (through the :display_only option)
|
97
111
|
|
98
112
|
// do not submit values from disabled fields
|
99
|
-
if (!field || field.disabled)
|
113
|
+
if (!field || field.disabled) {
|
114
|
+
delete values[fieldName];
|
115
|
+
}
|
100
116
|
|
101
117
|
// do not submit values from read-only association fields
|
102
118
|
if (field
|
103
119
|
&& field.name.indexOf("__") !== -1
|
104
|
-
&& (field.readOnly || !field.
|
120
|
+
&& (field.readOnly || !field.isXType('combobox'))
|
105
121
|
&& (!field.nestedAttribute) // except for "nested attributes"
|
106
|
-
)
|
122
|
+
) {
|
123
|
+
delete values[fieldName];
|
124
|
+
}
|
107
125
|
|
108
126
|
// do not submit values from displayfields
|
109
|
-
if (field.isXType('displayfield'))
|
127
|
+
if (field.isXType('displayfield')) {
|
128
|
+
delete values[fieldName];
|
129
|
+
}
|
110
130
|
|
111
131
|
// do not submit displayOnly fields
|
112
|
-
if (field.displayOnly)
|
132
|
+
if (field.displayOnly) {
|
133
|
+
delete values[fieldName];
|
134
|
+
}
|
113
135
|
}
|
114
|
-
|
136
|
+
// WIP: commented out on 2011-05-11 because of fatal errors
|
115
137
|
// apply mask
|
116
|
-
if (!this.applyMaskCmp) this.applyMaskCmp = new Ext.LoadMask(this.bwrap, this.applyMask);
|
117
|
-
this.applyMaskCmp.show();
|
138
|
+
// if (!this.applyMaskCmp) this.applyMaskCmp = new Ext.LoadMask(this.bwrap, this.applyMask);
|
139
|
+
// this.applyMaskCmp.show();
|
118
140
|
|
119
141
|
// We must use a different approach when the form is multipart, as we can't use the endpoint
|
120
142
|
if (this.fileUpload) {
|
@@ -155,9 +177,11 @@
|
|
155
177
|
setFormValues: function(values){
|
156
178
|
var assocValues = values._meta.associationValues || {};
|
157
179
|
for (var assocFieldName in assocValues) {
|
158
|
-
|
159
|
-
|
160
|
-
|
180
|
+
|
181
|
+
var assocField = this.getForm().getFields().filter('name', assocFieldName).first();
|
182
|
+
if (assocField.isXType('combobox')) {
|
183
|
+
// HACK: using private property 'store' here!
|
184
|
+
assocField.store.loadData([[values[assocFieldName], assocValues[assocFieldName]]]);
|
161
185
|
delete assocField.lastQuery; // force loading the store next time user clicks the trigger
|
162
186
|
} else {
|
163
187
|
assocField.setValue(assocValues[assocFieldName]);
|
@@ -170,7 +194,10 @@
|
|
170
194
|
|
171
195
|
setReadonlyMode: function(onOff, cancel){
|
172
196
|
if (this.inReadonlyMode == onOff) return;
|
173
|
-
this.getForm().
|
197
|
+
this.getForm().getFields().each(function(i){
|
198
|
+
if (i.setReadonlyMode) i.setReadonlyMode(onOff);
|
199
|
+
});
|
200
|
+
|
174
201
|
// this.getForm().cleanDestroyed(); // because fields inside of composite fields are not auto-cleaned!
|
175
202
|
this.doLayout();
|
176
203
|
this.inReadonlyMode = onOff;
|