netzke-basepack 0.6.4 → 0.6.5
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +10 -0
- data/README.rdoc +1 -1
- data/Rakefile +1 -1
- data/javascripts/basepack.js +4 -108
- data/javascripts/feedback_ghost.js +34 -0
- data/lib/netzke/basepack.rb +1 -0
- data/lib/netzke/basepack/form_panel.rb +7 -6
- data/lib/netzke/basepack/form_panel/fields.rb +6 -14
- data/lib/netzke/basepack/form_panel/javascripts/form_panel.js +53 -27
- data/lib/netzke/basepack/form_panel/javascripts/misc.js +4 -0
- data/lib/netzke/basepack/form_panel/javascripts/readonly_mode.js +4 -21
- data/lib/netzke/basepack/form_panel/services.rb +10 -3
- data/lib/netzke/basepack/grid_panel.rb +40 -26
- data/lib/netzke/basepack/grid_panel/columns.rb +25 -0
- data/lib/netzke/basepack/grid_panel/javascripts/grid_panel.js +4 -2
- data/lib/netzke/basepack/grid_panel/services.rb +10 -33
- data/lib/netzke/basepack/search_window.rb +2 -2
- data/lib/netzke/basepack/version.rb +1 -1
- data/netzke-basepack.gemspec +44 -145
- data/test/rails_app/Gemfile +3 -5
- data/test/rails_app/Gemfile.lock +78 -84
- data/test/rails_app/app/components/book_form.rb +12 -0
- data/test/rails_app/app/components/book_grid_with_scoped_authors.rb +8 -0
- data/test/rails_app/app/components/book_paging_form_panel.rb +3 -2
- data/test/rails_app/app/components/form_without_model.rb +2 -1
- data/test/rails_app/app/views/components/loadable_window.html.erb +9 -0
- data/test/rails_app/app/views/layouts/application.html.erb +1 -1
- data/test/rails_app/config/cucumber.yml +8 -0
- data/test/rails_app/config/{database.yml → database.yml.sample} +4 -1
- data/test/rails_app/config/locales/es.yml +4 -1
- data/{features → test/rails_app/features}/accordion_panel.feature +1 -4
- data/{features → test/rails_app/features}/components_in_view.feature +0 -0
- data/{features → test/rails_app/features}/form_panel.feature +18 -13
- data/{features → test/rails_app/features}/grid_panel.feature +0 -0
- data/test/rails_app/features/i18n.feature +18 -0
- data/{features → test/rails_app/features}/nested_attributes.feature +0 -0
- data/{features → test/rails_app/features}/paging_form_panel.feature +13 -1
- data/{features → test/rails_app/features}/search_in_grid.feature +0 -0
- data/{features → test/rails_app/features}/simple_app.feature +0 -0
- data/{features → test/rails_app/features}/simple_panel.feature +1 -5
- data/{features → test/rails_app/features}/step_definitions/accordion_steps.rb +0 -0
- data/{features → test/rails_app/features}/step_definitions/form_panel_steps.rb +1 -1
- data/{features → test/rails_app/features}/step_definitions/generic_steps.rb +0 -0
- data/{features → test/rails_app/features}/step_definitions/grid_panel_steps.rb +0 -0
- data/{features → test/rails_app/features}/step_definitions/pickle_steps.rb +0 -0
- data/{features → test/rails_app/features}/step_definitions/web_steps.rb +0 -0
- data/{features → test/rails_app/features}/support/env.rb +14 -13
- data/test/rails_app/features/support/paths.rb +24 -6
- data/{features → test/rails_app/features}/support/pickle.rb +0 -0
- data/test/rails_app/features/support/selectors.rb +39 -0
- data/{features → test/rails_app/features}/tab_panel.feature +1 -4
- data/{features → test/rails_app/features}/validations_in_grid.feature +0 -0
- data/{features → test/rails_app/features}/virtual_attributes.feature +0 -0
- data/{features → test/rails_app/features}/window.feature +0 -0
- data/test/rails_app/lib/tasks/cucumber.rake +71 -0
- data/test/rails_app/script/cucumber +10 -0
- data/{spec → test/rails_app/spec}/active_record/attributes_spec.rb +0 -0
- data/{spec → test/rails_app/spec}/active_record/relation_extensions_spec.rb +0 -0
- data/{spec → test/rails_app/spec}/components/form_panel_spec.rb +0 -0
- data/{spec → test/rails_app/spec}/components/grid_panel_spec.rb +0 -0
- data/{spec → test/rails_app/spec}/factories.rb +0 -0
- data/{spec → test/rails_app/spec}/spec_helper.rb +1 -6
- metadata +43 -141
- data/autotest/discover.rb +0 -3
- data/config/database.yml +0 -2
- data/features/i18n.feature +0 -18
- data/features/support/paths.rb +0 -65
- data/lib/netzke/basepack/form_panel/javascripts/display_mode.js +0 -68
- data/lib/netzke/basepack/form_panel/javascripts/netzkefileupload.js +0 -5
- data/test/rails_app/spec/controllers/embedded_components_controller_spec.rb +0 -12
- data/test/rails_app/spec/helpers/embedded_components_helper_spec.rb +0 -15
- data/test/rails_app/spec/models/address_spec.rb +0 -5
- data/test/rails_app/spec/models/author_spec.rb +0 -5
- data/test/rails_app/spec/models/book_spec.rb +0 -5
- data/test/rails_app/spec/models/role_spec.rb +0 -5
- data/test/rails_app/spec/models/user_spec.rb +0 -5
- data/test/rails_app/spec/views/embedded_components/index.html.erb_spec.rb +0 -5
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
= v0.6.5 - 2011-08-16
|
2
|
+
* changes
|
3
|
+
* Replaced tri-state checkbox with combobox in the multi-edit form and search form
|
4
|
+
* enhancements
|
5
|
+
* When columns states are saved in the persistent storage, adding/removing columns (e.g. in the code) will reset the saved states
|
6
|
+
* Moved features and specs to test/rails_app
|
7
|
+
* bug fix
|
8
|
+
* FormPanel with multiple association fields wouldn't submit data correctly
|
9
|
+
* Fixed an old bug where tri-checkbox set to 'unchecked' had no effect in multi-edit
|
10
|
+
|
1
11
|
= v0.6.4 - 2011-02-26
|
2
12
|
* API changes
|
3
13
|
* The combo field able to talk to the server has changed its xtype from combobox to netzkeremotecombo. When getting values from the server via AJAX, it expects a 2-dimensional array now, where the first value is the real value (which gets submitted), and the second value is the display value.
|
data/README.rdoc
CHANGED
@@ -35,7 +35,7 @@ For more examples, see http://demo.netzke.com, and look into test/rails_app
|
|
35
35
|
|
36
36
|
Netzke-basepack is bundled with automated tests. To run them, you need to set up test/rails_app a similar way as you did with your own Rails app that is using Netzke, i.e.: 1) link Ext JS into the "public" folder, 2) link your copy of netzke-core and netzke-basepack into vendor/gems, 3) run migrations and clone the development database structure into the test database.
|
37
37
|
|
38
|
-
After this you may run (*from
|
38
|
+
After this you may run (*from test/rails_app*):
|
39
39
|
|
40
40
|
cucumber features
|
41
41
|
|
data/Rakefile
CHANGED
@@ -9,7 +9,7 @@ begin
|
|
9
9
|
gemspec.email = "sergei@playcode.nl"
|
10
10
|
gemspec.homepage = "http://netzke.org"
|
11
11
|
gemspec.authors = ["Sergei Kozlov"]
|
12
|
-
gemspec.add_dependency("netzke-core", "~>0.6.
|
12
|
+
gemspec.add_dependency("netzke-core", "~>0.6.7")
|
13
13
|
gemspec.add_dependency("meta_where", ">=0.9.3")
|
14
14
|
gemspec.add_dependency("will_paginate", "~>3.0.pre2")
|
15
15
|
gemspec.add_dependency("acts_as_list")
|
data/javascripts/basepack.js
CHANGED
@@ -108,114 +108,10 @@ Ext.grid.HeaderDropZone.prototype.onNodeDrop = function(n, dd, e, data){
|
|
108
108
|
|
109
109
|
|
110
110
|
Ext.ns('Ext.ux.form');
|
111
|
-
Ext.ux.form.TriCheckbox = Ext.extend(Ext.form.
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
overClass: 'x-form-check-over',
|
116
|
-
clickClass: 'x-form-check-down',
|
117
|
-
triState: true,
|
118
|
-
defaultAutoCreate: {tag: 'input', type: 'hidden', autocomplete: 'off'},
|
119
|
-
initComponent: function() {
|
120
|
-
this.value = this.checked;
|
121
|
-
Ext.ux.form.TriCheckbox.superclass.initComponent.apply(this, arguments);
|
122
|
-
// make a copy before modifying valueList and stateClassList arrays
|
123
|
-
this.vList = this.valueList.slice(0);
|
124
|
-
this.cList = this.stateClassList.slice(0);
|
125
|
-
if(this.triState !== true) {
|
126
|
-
// consider 'undefined' value and its class go first in arrays
|
127
|
-
this.vList.shift();
|
128
|
-
this.cList.shift();
|
129
|
-
}
|
130
|
-
if(this.overCls !== undefined) {
|
131
|
-
this.overClass = this.overCls;
|
132
|
-
delete this.overCls;
|
133
|
-
}
|
134
|
-
this.value = this.normalizeValue(this.value);
|
135
|
-
},
|
136
|
-
onRender : function(ct, position){
|
137
|
-
Ext.form.Checkbox.superclass.onRender.call(this, ct, position);
|
138
|
-
|
139
|
-
this.innerWrap = this.el.wrap({tag: 'span', cls: 'x-form-check-innerwrap'});
|
140
|
-
this.wrap = this.innerWrap.wrap({cls: 'x-form-check-wrap'});
|
141
|
-
|
142
|
-
this.currCls = this.getCls(this.value);
|
143
|
-
this.wrap.addClass(this.currCls);
|
144
|
-
if(this.clickClass && !this.disabled && !this.readOnly)
|
145
|
-
this.innerWrap.addClassOnClick(this.clickClass);
|
146
|
-
if(this.overClass && !this.disabled && !this.readOnly)
|
147
|
-
this.innerWrap.addClassOnOver(this.overClass);
|
148
|
-
|
149
|
-
this.imageEl = this.innerWrap.createChild({
|
150
|
-
tag: 'img',
|
151
|
-
src: Ext.BLANK_IMAGE_URL,
|
152
|
-
cls: 'x-form-tscheckbox'
|
153
|
-
}, this.el);
|
154
|
-
if(this.fieldClass) this.imageEl.addClass(this.fieldClass);
|
155
|
-
|
156
|
-
if(this.boxLabel){
|
157
|
-
this.innerWrap.createChild({
|
158
|
-
tag: 'label',
|
159
|
-
htmlFor: this.el.id,
|
160
|
-
cls: 'x-form-cb-label',
|
161
|
-
html: this.boxLabel
|
162
|
-
});
|
163
|
-
}
|
164
|
-
|
165
|
-
// Need to repaint for IE, otherwise positioning is broken
|
166
|
-
if(Ext.isIE){
|
167
|
-
this.wrap.repaint();
|
168
|
-
}
|
169
|
-
this.resizeEl = this.positionEl = this.wrap;
|
170
|
-
},
|
171
|
-
onResize : function(){
|
172
|
-
Ext.form.Checkbox.superclass.onResize.apply(this, arguments);
|
173
|
-
if(!this.boxLabel && !this.fieldLabel && this.imageEl){
|
174
|
-
this.imageEl.alignTo(this.wrap, 'c-c');
|
175
|
-
}
|
176
|
-
},
|
177
|
-
initEvents : function(){
|
178
|
-
Ext.form.Checkbox.superclass.initEvents.call(this);
|
179
|
-
this.mon(this.innerWrap, {
|
180
|
-
scope: this,
|
181
|
-
click: this.onClick
|
182
|
-
});
|
183
|
-
},
|
184
|
-
onClick : function(){
|
185
|
-
if (!this.disabled && !this.readOnly) {
|
186
|
-
this.setValue(this.vList[(this.vList.indexOf(this.value) + 1) % this.vList.length]);
|
187
|
-
}
|
188
|
-
},
|
189
|
-
getValue : function(){
|
190
|
-
return this.value;
|
191
|
-
},
|
192
|
-
setValue : function(v){
|
193
|
-
var value = this.value;
|
194
|
-
this.value = this.normalizeValue(v);
|
195
|
-
if(this.rendered) this.el.dom.value = this.value;
|
196
|
-
|
197
|
-
if(value !== this.value){
|
198
|
-
this.updateView();
|
199
|
-
this.fireEvent('check', this, this.value);
|
200
|
-
if(this.handler) this.handler.call(this.scope || this, this, this.value);
|
201
|
-
}
|
202
|
-
return this;
|
203
|
-
},
|
204
|
-
normalizeValue: function(v) {
|
205
|
-
return (v === null || v === undefined) && this.triState ? null :
|
206
|
-
(v === true || (['true', 'yes', 'on', '1']).indexOf(String(v).toLowerCase()) != -1);
|
207
|
-
},
|
208
|
-
getCls: function(v) {
|
209
|
-
var idx = this.vList.indexOf(this.value);
|
210
|
-
return idx > -1 ? this.cList[idx] : undefined;
|
211
|
-
},
|
212
|
-
updateView: function() {
|
213
|
-
var cls = this.getCls(this.value);
|
214
|
-
if (!this.wrap || cls === undefined) return;
|
215
|
-
|
216
|
-
this.wrap.replaceClass(this.currCls, cls);
|
217
|
-
this.currCls = cls;
|
218
|
-
}
|
111
|
+
Ext.ux.form.TriCheckbox = Ext.extend(Ext.form.ComboBox, {
|
112
|
+
store: [[true, "true"], [false, "false"]],
|
113
|
+
forceSelection: true,
|
114
|
+
triggerAction: 'all'
|
219
115
|
});
|
220
116
|
Ext.reg('tricheckbox', Ext.ux.form.TriCheckbox);
|
221
117
|
|
@@ -0,0 +1,34 @@
|
|
1
|
+
// Feedback Ghost
|
2
|
+
Netzke.FeedbackGhost = function(){};
|
3
|
+
Ext.apply(Netzke.FeedbackGhost.prototype, {
|
4
|
+
showFeedback: function(msg){
|
5
|
+
var createBox = function(s, l){
|
6
|
+
return ['<div class="msg">',
|
7
|
+
'<div class="x-box-tl"><div class="x-box-tr"><div class="x-box-tc"></div></div></div>',
|
8
|
+
'<div class="x-box-ml"><div class="x-box-mr"><div class="x-box-mc">', s, '</div></div></div>',
|
9
|
+
'<div class="x-box-bl"><div class="x-box-br"><div class="x-box-bc"></div></div></div>',
|
10
|
+
'</div>'].join('');
|
11
|
+
}
|
12
|
+
|
13
|
+
var showBox = function(msg, lvl){
|
14
|
+
if (!lvl) {lvl = 'notice'};
|
15
|
+
|
16
|
+
var msgCt = Ext.get('netzke-feedback') || Ext.DomHelper.insertFirst(document.body, {id: 'netzke-feedback', 'class':'netzke-feedback'}, true);
|
17
|
+
|
18
|
+
var m = Ext.DomHelper.append(msgCt, {html:createBox(msg,lvl)}, true);
|
19
|
+
m.slideIn('t').pause(2).ghost("b", {remove:true});
|
20
|
+
}
|
21
|
+
|
22
|
+
if (typeof msg != 'string') {
|
23
|
+
var compoundMsg = "";
|
24
|
+
Ext.each(msg, function(m){
|
25
|
+
compoundMsg += m.msg + '<br>';
|
26
|
+
});
|
27
|
+
if (compoundMsg != "") showBox(compoundMsg, null); // the second parameter will be level
|
28
|
+
} else {
|
29
|
+
showBox(msg);
|
30
|
+
}
|
31
|
+
}
|
32
|
+
});
|
33
|
+
|
34
|
+
Netzke.componentMixin.feedbackGhost = new Netzke.FeedbackGhost();
|
data/lib/netzke/basepack.rb
CHANGED
@@ -11,6 +11,7 @@ module Netzke
|
|
11
11
|
|
12
12
|
# Called from netzke-basepack.rb
|
13
13
|
def init
|
14
|
+
Netzke::Core.ext_javascripts << "#{File.dirname(__FILE__)}/../../javascripts/feedback_ghost.js"
|
14
15
|
Netzke::Core.ext_javascripts << "#{File.dirname(__FILE__)}/../../javascripts/datetimefield.js"
|
15
16
|
Netzke::Core.ext_javascripts << "#{File.dirname(__FILE__)}/../../javascripts/basepack.js"
|
16
17
|
|
@@ -71,16 +71,17 @@ module Netzke
|
|
71
71
|
c[:bbar] = [:apply.action] if c[:bbar].nil?
|
72
72
|
end
|
73
73
|
|
74
|
-
# Extra
|
74
|
+
# Extra JavaScripts and stylesheets
|
75
75
|
js_mixin :form_panel
|
76
76
|
js_include :comma_list_cbg
|
77
|
-
js_include :n_radio_group, :
|
78
|
-
# Netzke::Base.config[:ext_location] + "/examples/ux/fileuploadfield/FileUploadField.js",
|
79
|
-
# "#{File.dirname(__FILE__)}/form_panel/javascripts/netzkefileupload.js"
|
80
|
-
|
81
|
-
# Extra CSS
|
77
|
+
js_include :n_radio_group, :readonly_mode
|
82
78
|
css_include :readonly_mode
|
83
79
|
|
80
|
+
js_include Netzke::Core.ext_location.join("examples/ux/fileuploadfield/FileUploadField.js")
|
81
|
+
css_include Netzke::Core.ext_location.join("examples/ux/fileuploadfield/css/fileuploadfield.css")
|
82
|
+
|
83
|
+
js_include :misc
|
84
|
+
|
84
85
|
def js_config
|
85
86
|
super.tap do |res|
|
86
87
|
res[:pri] = data_class && data_class.primary_key
|
@@ -98,11 +98,8 @@ module Netzke
|
|
98
98
|
detect_association_with_method(field) # xtype for an association field
|
99
99
|
set_default_field_label(field)
|
100
100
|
set_default_field_xtype(field) if field[:xtype].nil?
|
101
|
-
# set_default_field_value(field) if self.record
|
102
101
|
set_default_read_only(field)
|
103
102
|
|
104
|
-
field[:display_mode] = config[:display_mode] if config[:display_mode]
|
105
|
-
|
106
103
|
# provide our special combobox with our id
|
107
104
|
field[:parent_id] = self.global_id if field[:xtype] == :netzkeremotecombo
|
108
105
|
|
@@ -153,17 +150,6 @@ module Netzke
|
|
153
150
|
item.is_a?(String) || item.is_a?(Symbol) || item[:name] # && !is_component_config?(item)
|
154
151
|
end
|
155
152
|
|
156
|
-
def set_default_field_label(c)
|
157
|
-
# multiple spaces (in case of association attrs) get replaced with one
|
158
|
-
c[:field_label] ||= data_class ? data_class.human_attribute_name(c[:name]) : c[:name].humanize
|
159
|
-
c[:field_label].gsub!(/\s+/, " ")
|
160
|
-
end
|
161
|
-
|
162
|
-
# def set_default_field_value(field)
|
163
|
-
# value = record.value_for_attribute(field)
|
164
|
-
# field[:value] ||= value unless value.nil?
|
165
|
-
# end
|
166
|
-
|
167
153
|
# Deeply merges only those key/values at the top level that are already there
|
168
154
|
def deep_merge_existing_fields(dest, src)
|
169
155
|
dest.each_pair do |k,v|
|
@@ -171,6 +157,12 @@ module Netzke
|
|
171
157
|
end
|
172
158
|
end
|
173
159
|
|
160
|
+
def set_default_field_label(c)
|
161
|
+
# multiple spaces (in case of association attrs) get replaced with one
|
162
|
+
c[:field_label] ||= data_class ? data_class.human_attribute_name(c[:name]) : c[:name].humanize
|
163
|
+
c[:field_label].gsub!(/\s+/, " ")
|
164
|
+
end
|
165
|
+
|
174
166
|
def set_default_field_xtype(field)
|
175
167
|
field[:xtype] = xtype_for_attr_type(field[:attr_type]) unless xtype_for_attr_type(field[:attr_type]).nil?
|
176
168
|
end
|
@@ -19,6 +19,19 @@
|
|
19
19
|
initComponent: function(){
|
20
20
|
if (!this.bbar) this.bbar = {xtype: 'toolbar'}; // an empty bbar by default, so that we can dynamically add buttons
|
21
21
|
|
22
|
+
// 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.
|
23
|
+
ErrorReader = function(){};
|
24
|
+
|
25
|
+
ErrorReader.prototype.read = function(xhr) {
|
26
|
+
var unescapeHTML = function(str) {
|
27
|
+
return str.replace(/</g,'<').replace(/>/g,'>').replace(/&/g,'&');
|
28
|
+
}
|
29
|
+
xhr.responseText = unescapeHTML(xhr.responseText.replace(/<pre.*?>/, "").replace("</pre>", ""));
|
30
|
+
return {records: [], success: true};
|
31
|
+
};
|
32
|
+
|
33
|
+
this.initialConfig.errorReader = new ErrorReader();
|
34
|
+
|
22
35
|
// Now let Ext.form.FormPanel do the rest
|
23
36
|
Netzke.classes.Basepack.FormPanel.superclass.initComponent.call(this);
|
24
37
|
|
@@ -73,40 +86,63 @@
|
|
73
86
|
tbar.doLayout();
|
74
87
|
},
|
75
88
|
|
76
|
-
|
77
89
|
onApply: function() {
|
78
90
|
if (this.fireEvent('apply', this)) {
|
79
91
|
var values = this.getForm().getFieldValues();
|
80
92
|
|
81
|
-
// do not send values from disabled fields and empty values
|
82
93
|
for (var fieldName in values) {
|
83
94
|
var field = this.getForm().findField(fieldName);
|
95
|
+
|
96
|
+
// TODO: move the following checks to the server side (through the :display_only option)
|
97
|
+
|
98
|
+
// do not submit values from disabled fields
|
84
99
|
if (!field || field.disabled) delete values[fieldName];
|
100
|
+
|
101
|
+
// do not submit values from read-only association fields
|
102
|
+
if (field
|
103
|
+
&& field.name.indexOf("__") !== -1
|
104
|
+
&& (field.readOnly || !field.getStore)
|
105
|
+
&& (!field.nestedAttribute) // except for "nested attributes"
|
106
|
+
) delete values[fieldName];
|
107
|
+
|
108
|
+
// do not submit values from displayfields
|
109
|
+
if (field.isXType('displayfield')) delete values[fieldName];
|
110
|
+
|
111
|
+
// do not submit displayOnly fields
|
112
|
+
if (field.displayOnly) delete values[fieldName];
|
85
113
|
}
|
86
114
|
|
115
|
+
// apply mask
|
87
116
|
if (!this.applyMaskCmp) this.applyMaskCmp = new Ext.LoadMask(this.bwrap, this.applyMask);
|
88
|
-
|
89
117
|
this.applyMaskCmp.show();
|
90
118
|
|
119
|
+
// We must use a different approach when the form is multipart, as we can't use the endpoint
|
91
120
|
if (this.fileUpload) {
|
92
|
-
//
|
93
|
-
|
94
|
-
api: {submit: Netzke.providers[this.parentId].netzkeSubmit},
|
121
|
+
this.getForm().submit({ // normal submit
|
122
|
+
url: this.endpointUrl("netzke_submit"),
|
95
123
|
params: {
|
96
|
-
data: Ext.encode(values)
|
124
|
+
data: Ext.encode(values) // here are the correct values that may be different from display values
|
97
125
|
},
|
98
126
|
failure: function(form, action){
|
99
|
-
|
100
|
-
|
101
|
-
|
127
|
+
if (this.applyMaskCmp) this.applyMaskCmp.hide();
|
128
|
+
},
|
129
|
+
success: function(form, action) {
|
130
|
+
try {
|
131
|
+
var respObj = Ext.decode(action.response.responseText);
|
132
|
+
delete respObj.success;
|
133
|
+
this.bulkExecute(respObj);
|
134
|
+
this.fireEvent('submitsuccess');
|
135
|
+
}
|
136
|
+
catch(e) {
|
137
|
+
Ext.Msg.alert('File upload error', action.response.responseText);
|
138
|
+
}
|
102
139
|
if (this.applyMaskCmp) this.applyMaskCmp.hide();
|
103
140
|
},
|
104
141
|
scope: this
|
105
142
|
});
|
106
143
|
} else {
|
107
|
-
|
108
|
-
|
109
|
-
if (result === "ok") {
|
144
|
+
this.netzkeSubmit(Ext.apply((this.baseParams || {}), {data:Ext.encode(values)}), function(success){
|
145
|
+
if (success) {
|
110
146
|
this.fireEvent("submitsuccess");
|
111
147
|
if (this.mode == "lockable") this.setReadonlyMode(true);
|
112
148
|
};
|
@@ -120,28 +156,18 @@
|
|
120
156
|
var assocValues = values._meta.associationValues || {};
|
121
157
|
for (var assocFieldName in assocValues) {
|
122
158
|
var assocField = this.find('name', assocFieldName)[0];
|
123
|
-
if (
|
124
|
-
assocField.origValue = values[assocFieldName];
|
125
|
-
assocField.setValue(assocValues[assocFieldName]);
|
126
|
-
delete values[assocFieldName]; // we don't want this to be set once more below with setValues()
|
127
|
-
} else {
|
159
|
+
if (assocField.getStore) {
|
128
160
|
assocField.getStore().loadData({data: [[values[assocFieldName], assocValues[assocFieldName]]]});
|
129
161
|
delete assocField.lastQuery; // force loading the store next time user clicks the trigger
|
162
|
+
} else {
|
163
|
+
assocField.setValue(assocValues[assocFieldName]);
|
164
|
+
delete values[assocFieldName]; // we don't want this to be set once more below with setValues()
|
130
165
|
}
|
131
166
|
}
|
132
167
|
|
133
168
|
this.getForm().setValues(values);
|
134
169
|
},
|
135
170
|
|
136
|
-
setDisplayMode: function(onOff, cancel){
|
137
|
-
if (this.inDisplayMode == onOff) return;
|
138
|
-
this.getForm().items.each(function(i){i.setDisplayMode(onOff);});
|
139
|
-
this.getForm().cleanDestroyed(); // because fields inside of composite fields are not auto-cleaned!
|
140
|
-
this.doLayout();
|
141
|
-
this.inDisplayMode = onOff;
|
142
|
-
this.updateToolbar();
|
143
|
-
},
|
144
|
-
|
145
171
|
setReadonlyMode: function(onOff, cancel){
|
146
172
|
if (this.inReadonlyMode == onOff) return;
|
147
173
|
this.getForm().items.each(function(i){i.setReadonlyMode(onOff);});
|
@@ -4,7 +4,9 @@ Ext.override(Ext.form.Field, {
|
|
4
4
|
setReadonlyMode: function(onOff){
|
5
5
|
if (this.hidden) return;
|
6
6
|
|
7
|
-
this.
|
7
|
+
if (!this.initialConfig.readOnly) {
|
8
|
+
this.setReadOnly(onOff);
|
9
|
+
}
|
8
10
|
|
9
11
|
if (onOff) {
|
10
12
|
this.addClass("readonly");
|
@@ -13,26 +15,7 @@ Ext.override(Ext.form.Field, {
|
|
13
15
|
this.removeClass("readonly");
|
14
16
|
if (this.label) this.label.removeClass("readonly");
|
15
17
|
}
|
16
|
-
|
17
|
-
// var newConfig = this.readonlyModeConfig(onOff);
|
18
|
-
//
|
19
|
-
// var idx = this.removeSelf();
|
20
|
-
// owner.insert(idx, newConfig);
|
21
|
-
//
|
22
|
-
// this.destroy();
|
23
|
-
},
|
24
|
-
|
25
|
-
// Remove self from the container
|
26
|
-
// removeSelf: function(){
|
27
|
-
// var idx = this.ownerCt.items.indexOf(this);
|
28
|
-
// this.ownerCt.remove(this);
|
29
|
-
// return idx;
|
30
|
-
// },
|
31
|
-
|
32
|
-
// Config for creating an instance in "displayMode" (if onOff is true), or normal mode (if onOff is false)
|
33
|
-
// displayModeConfig: function(onOff){
|
34
|
-
// return Ext.apply(this.initialConfig, onOff ? {xtype: 'displayfield', origXtype: this.xtype, value: this.getValue()} : {xtype: this.origXtype, value: this.getValue()});
|
35
|
-
// }
|
18
|
+
}
|
36
19
|
|
37
20
|
});
|
38
21
|
|
@@ -9,7 +9,7 @@ module Netzke
|
|
9
9
|
#
|
10
10
|
# Endpoints
|
11
11
|
#
|
12
|
-
endpoint :netzke_submit do |params|
|
12
|
+
endpoint :netzke_submit, :pre => true do |params|
|
13
13
|
netzke_submit(params)
|
14
14
|
end
|
15
15
|
|
@@ -48,16 +48,23 @@ module Netzke
|
|
48
48
|
# Implementation for the "netzke_submit" endpoint (for backward compatibility)
|
49
49
|
def netzke_submit(params)
|
50
50
|
data = ActiveSupport::JSON.decode(params[:data])
|
51
|
+
|
52
|
+
# File uploads are in raw params instead of "data" hash, so, mix them in into "data"
|
53
|
+
if config[:file_upload]
|
54
|
+
Netzke::Core.controller.params.each_pair do |k,v|
|
55
|
+
data[k] = v if v.is_a?(ActionDispatch::Http::UploadedFile)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
51
59
|
success = create_or_update_record(data)
|
52
60
|
|
53
61
|
if success
|
54
|
-
{:set_form_values => js_record_data, :set_result =>
|
62
|
+
{:set_form_values => js_record_data, :set_result => true}
|
55
63
|
else
|
56
64
|
# flash eventual errors
|
57
65
|
@record.errors.to_a.each do |msg|
|
58
66
|
flash :error => msg
|
59
67
|
end
|
60
|
-
# {:feedback => @flash}
|
61
68
|
{:feedback => @flash, :apply_form_errors => build_form_errors(record)}
|
62
69
|
end
|
63
70
|
end
|