netzke-core 0.3.1 → 0.4.2
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/.autotest +1 -0
- data/.gitignore +4 -0
- data/CHANGELOG +21 -0
- data/Manifest +9 -11
- data/README.rdoc +12 -0
- data/Rakefile +17 -13
- data/TODO +2 -1
- data/VERSION +1 -0
- data/generators/netzke_core/templates/create_netzke_preferences.rb +1 -1
- data/javascripts/core.js +271 -113
- data/lib/app/controllers/netzke_controller.rb +66 -9
- data/lib/app/models/netzke_preference.rb +39 -32
- data/lib/netzke-core.rb +0 -3
- data/lib/netzke/base.rb +318 -140
- data/lib/netzke/base_js.rb +249 -0
- data/lib/netzke/controller_extensions.rb +29 -40
- data/lib/netzke/core_ext.rb +40 -18
- data/lib/netzke/feedback_ghost.rb +2 -2
- data/netzke-core.gemspec +90 -11
- data/test/unit/core_ext_test.rb +28 -7
- data/test/unit/netzke_core_test.rb +57 -29
- data/test/unit/netzke_preference_test.rb +7 -7
- metadata +35 -38
- data/README.mdown +0 -15
- data/lib/netzke/base_extras/interface.rb +0 -20
- data/lib/netzke/base_extras/js_builder.rb +0 -271
- data/lib/vendor/facets/hash/recursive_merge.rb +0 -28
data/.autotest
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'autotest/redgreen'
|
data/.gitignore
ADDED
data/CHANGELOG
CHANGED
@@ -1,4 +1,25 @@
|
|
1
|
+
v0.4.2
|
2
|
+
2009-09-11
|
3
|
+
Fix: the API call (at the JavaScript side) was ignoring the callback parameter.
|
4
|
+
Impr: if the array of API points is empty, it's not added into js_config anymore.
|
5
|
+
New: new testing widgets in netzke_controller.
|
6
|
+
Fix: extra CSS includes now take effect.
|
7
|
+
New: Support for masquerading as "World". In this mode all the "touched" persistent preferences will be overwritten for all roles and users.
|
8
|
+
|
9
|
+
v0.4.1
|
10
|
+
2009-09-06
|
11
|
+
Version bumb to force github rebuild the gem (Manifest is now included)
|
12
|
+
|
13
|
+
v0.4.0
|
14
|
+
2009-09-05
|
15
|
+
Major refactoring.
|
16
|
+
|
17
|
+
v0.3.2
|
18
|
+
2009-06-05
|
19
|
+
Netzke doesn't overwrite session[:user] anymore to not cause authentication-related problems.
|
20
|
+
|
1
21
|
v0.3.1
|
22
|
+
2009-05-07
|
2
23
|
Fix: persistent_config_manager can now be set to nil, and it will work fine
|
3
24
|
|
4
25
|
v0.3.0
|
data/Manifest
CHANGED
@@ -1,28 +1,27 @@
|
|
1
|
-
autotest/discover.rb
|
2
1
|
CHANGELOG
|
2
|
+
LICENSE
|
3
|
+
Manifest
|
4
|
+
README.rdoc
|
5
|
+
Rakefile
|
6
|
+
TODO
|
7
|
+
autotest/discover.rb
|
8
|
+
generators/netzke_core/USAGE
|
3
9
|
generators/netzke_core/netzke_core_generator.rb
|
4
10
|
generators/netzke_core/templates/create_netzke_preferences.rb
|
5
|
-
generators/netzke_core/USAGE
|
6
11
|
init.rb
|
7
12
|
install.rb
|
8
13
|
javascripts/core.js
|
9
14
|
lib/app/controllers/netzke_controller.rb
|
10
15
|
lib/app/models/netzke_preference.rb
|
16
|
+
lib/netzke-core.rb
|
11
17
|
lib/netzke/action_view_ext.rb
|
12
18
|
lib/netzke/base.rb
|
13
|
-
lib/netzke/
|
14
|
-
lib/netzke/base_extras/js_builder.rb
|
19
|
+
lib/netzke/base_js.rb
|
15
20
|
lib/netzke/controller_extensions.rb
|
16
21
|
lib/netzke/core_ext.rb
|
17
22
|
lib/netzke/feedback_ghost.rb
|
18
23
|
lib/netzke/routing.rb
|
19
|
-
lib/netzke-core.rb
|
20
|
-
lib/vendor/facets/hash/recursive_merge.rb
|
21
|
-
LICENSE
|
22
|
-
Manifest
|
23
24
|
netzke-core.gemspec
|
24
|
-
Rakefile
|
25
|
-
README.mdown
|
26
25
|
stylesheets/core.css
|
27
26
|
tasks/netzke_core_tasks.rake
|
28
27
|
test/app_root/app/controllers/application_controller.rb
|
@@ -48,5 +47,4 @@ test/test_helper.rb
|
|
48
47
|
test/unit/core_ext_test.rb
|
49
48
|
test/unit/netzke_core_test.rb
|
50
49
|
test/unit/netzke_preference_test.rb
|
51
|
-
TODO
|
52
50
|
uninstall.rb
|
data/README.rdoc
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
= netzke-core
|
2
|
+
Create Ext JS + Rails reusable components (widgets) with minimum effort.
|
3
|
+
|
4
|
+
Introduction to Netzke framework: http://github.com/skozlov/netzke/tree/master
|
5
|
+
|
6
|
+
Tutorials: http://blog.writelesscode.com
|
7
|
+
|
8
|
+
Live-demo: http://netzke-demo.writelesscode.com
|
9
|
+
|
10
|
+
Also see netzke-basepack (pre-programmed widgets) project: http://github.com/skozlov/netzke-basepack/tree/master
|
11
|
+
|
12
|
+
Copyright (c) 2009 Sergei Kozlov, released under the MIT license
|
data/Rakefile
CHANGED
@@ -1,14 +1,18 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
1
|
+
begin
|
2
|
+
require 'jeweler'
|
3
|
+
Jeweler::Tasks.new do |gemspec|
|
4
|
+
gemspec.name = "netzke-core"
|
5
|
+
gemspec.summary = "Build ExtJS/Rails widgets with minimum effort"
|
6
|
+
gemspec.description = "Build ExtJS/Rails widgets with minimum effort"
|
7
|
+
gemspec.email = "sergei@playcode.nl"
|
8
|
+
gemspec.homepage = "http://github.com/skozlov/netzke-core"
|
9
|
+
gemspec.rubyforge_project = "netzke-core"
|
10
|
+
gemspec.authors = ["Sergei Kozlov"]
|
11
|
+
end
|
12
|
+
Jeweler::RubyforgeTasks.new do |rubyforge|
|
13
|
+
rubyforge.doc_task = "rdoc"
|
14
|
+
end
|
11
15
|
|
12
|
-
|
13
|
-
|
14
|
-
end
|
16
|
+
rescue LoadError
|
17
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
18
|
+
end
|
data/TODO
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
* Re-factor JS-level inheritance mechanisms
|
1
|
+
* Re-factor JS-level inheritance mechanisms (2009-07-5 why?)
|
2
|
+
* Get rid of the default_config method, because the same functionality maybe achieved by overwriting the initialize method
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.4.2
|
data/javascripts/core.js
CHANGED
@@ -9,24 +9,17 @@ Ext.netzke.cache = {};
|
|
9
9
|
|
10
10
|
Ext.QuickTips.init(); // seems obligatory in Ext v2.2.1, otherwise Ext.Component#destroy() stops working properly
|
11
11
|
|
12
|
-
//
|
12
|
+
// To comply with Rails' forgery protection
|
13
13
|
Ext.Ajax.extraParams = {
|
14
14
|
authenticity_token : Ext.authenticityToken
|
15
15
|
};
|
16
16
|
|
17
|
-
// helper method to do multiple Ext.apply's
|
18
|
-
Ext.netzke.chainApply = function(objectArray){
|
19
|
-
var res = {};
|
20
|
-
Ext.each(objectArray, function(obj){Ext.apply(res, obj)});
|
21
|
-
return res;
|
22
|
-
};
|
23
|
-
|
24
17
|
// Type detection functions
|
25
18
|
Netzke.isObject = function(o) {
|
26
19
|
return (o != null && typeof o == "object" && o.constructor.toString() == Object.toString());
|
27
20
|
}
|
28
21
|
|
29
|
-
// Some
|
22
|
+
// Some Ruby-ish String extensions
|
30
23
|
// from http://code.google.com/p/inflection-js/
|
31
24
|
String.prototype.camelize=function(lowFirstLetter)
|
32
25
|
{
|
@@ -66,7 +59,6 @@ Ext.data.ArrayReader = Ext.extend(Ext.data.JsonReader, {
|
|
66
59
|
var sid = this.meta ? this.meta.id : null;
|
67
60
|
var recordType = this.recordType, fields = recordType.prototype.fields;
|
68
61
|
var records = [];
|
69
|
-
// console.info(this.meta);
|
70
62
|
var root = o[this.meta.root] || o, totalRecords = o[this.meta.totalProperty], success = o[this.meta.successProperty];
|
71
63
|
for(var i = 0; i < root.length; i++){
|
72
64
|
var n = root[i];
|
@@ -91,8 +83,174 @@ Ext.data.ArrayReader = Ext.extend(Ext.data.JsonReader, {
|
|
91
83
|
}
|
92
84
|
});
|
93
85
|
|
94
|
-
//
|
86
|
+
// Properties/methods common to all widget classes
|
95
87
|
Ext.widgetMixIn = {
|
88
|
+
height: 400,
|
89
|
+
width: 800,
|
90
|
+
border: false,
|
91
|
+
is_netzke: true, // to distinguish Netzke components from regular Ext components
|
92
|
+
|
93
|
+
/*
|
94
|
+
Loads aggregatee into a container. Sends the widgets cache info to the server.
|
95
|
+
*/
|
96
|
+
loadAggregatee: function(params){
|
97
|
+
// build the cached widget list
|
98
|
+
var cachedWidgetNames = [];
|
99
|
+
for (name in Ext.netzke.cache) {
|
100
|
+
cachedWidgetNames.push(name);
|
101
|
+
}
|
102
|
+
|
103
|
+
params.cache = Ext.encode(cachedWidgetNames);
|
104
|
+
|
105
|
+
// remember the passed callback
|
106
|
+
if (params.callback) {
|
107
|
+
this.callbackHash[params.id] = params.callback;
|
108
|
+
delete params.callback;
|
109
|
+
delete params.scope;
|
110
|
+
}
|
111
|
+
|
112
|
+
// visually disable the container while the widget is being loaded
|
113
|
+
// Ext.getCmp(params.container).disable();
|
114
|
+
Ext.getCmp(params.container).removeChild(); // simply cleanup the area, which speaks for itself
|
115
|
+
|
116
|
+
// remote api call
|
117
|
+
this.loadAggregateeWithCache(params);
|
118
|
+
},
|
119
|
+
|
120
|
+
/*
|
121
|
+
Called by the server as callback about loaded widget
|
122
|
+
*/
|
123
|
+
widgetLoaded : function(params){
|
124
|
+
if (this.fireEvent('widgetload')) {
|
125
|
+
// Enable the container after the widget is succesfully loaded
|
126
|
+
// this.getChildWidget(params.id).ownerCt.enable();
|
127
|
+
|
128
|
+
// provide the callback to that widget that was loading the child, passing the child itself
|
129
|
+
var callbackFn = this.callbackHash[params.id.camelize(true)];
|
130
|
+
if (callbackFn) {
|
131
|
+
callbackFn.call(params.scope || this, this.getChildWidget(params.id));
|
132
|
+
delete this.callbackHash[params.id.camelize(true)];
|
133
|
+
}
|
134
|
+
}
|
135
|
+
},
|
136
|
+
|
137
|
+
/*
|
138
|
+
Returns the parent widget
|
139
|
+
*/
|
140
|
+
getParent: function(){
|
141
|
+
// simply cutting the last part of the id: some_parent__a_kid__a_great_kid => some_parent__a_kid
|
142
|
+
var idSplit = this.id.split("__");
|
143
|
+
idSplit.pop();
|
144
|
+
var parentId = idSplit.join("__");
|
145
|
+
|
146
|
+
return parentId === "" ? null : Ext.getCmp(parentId);
|
147
|
+
},
|
148
|
+
|
149
|
+
/*
|
150
|
+
Reloads current widget (calls the parent to reload it as its aggregatee)
|
151
|
+
*/
|
152
|
+
reload : function(){
|
153
|
+
var parent = this.getParent();
|
154
|
+
if (parent) {
|
155
|
+
parent.loadAggregatee({id:this.localId(parent), container:this.ownerCt.id});
|
156
|
+
} else {
|
157
|
+
window.location.reload();
|
158
|
+
}
|
159
|
+
},
|
160
|
+
|
161
|
+
/*
|
162
|
+
Gets id in the context of provided parent.
|
163
|
+
For example, the widgets "properties", being a child of "books" has global id "books__properties",
|
164
|
+
which *is* its widegt's real id. This methods, with the instance of "books" passed as parameter,
|
165
|
+
returns "properties".
|
166
|
+
*/
|
167
|
+
localId : function(parent){
|
168
|
+
return this.id.replace(parent.id + "__", "");
|
169
|
+
},
|
170
|
+
|
171
|
+
/*
|
172
|
+
Instantiates and inserts a widget into a container with layout 'fit'.
|
173
|
+
Arg: an JS object with the following keys:
|
174
|
+
- id: id of the receiving container
|
175
|
+
- config: configuration of the widget to be instantiated and inserted into the container
|
176
|
+
*/
|
177
|
+
renderWidgetInContainer : function(params){
|
178
|
+
var cont = Ext.getCmp(params.container);
|
179
|
+
cont.instantiateChild(params.config);
|
180
|
+
},
|
181
|
+
|
182
|
+
/*
|
183
|
+
Reconfigures the widget
|
184
|
+
*/
|
185
|
+
reconfigure: function(config){
|
186
|
+
this.ownerCt.instantiateChild(config)
|
187
|
+
},
|
188
|
+
|
189
|
+
/*
|
190
|
+
Evaluates CSS
|
191
|
+
*/
|
192
|
+
css : function(code){
|
193
|
+
var linkTag = document.createElement('style');
|
194
|
+
linkTag.type = 'text/css';
|
195
|
+
linkTag.innerHTML = code;
|
196
|
+
document.body.appendChild(linkTag);
|
197
|
+
},
|
198
|
+
|
199
|
+
/*
|
200
|
+
Evaluates JS
|
201
|
+
*/
|
202
|
+
js : function(code){
|
203
|
+
eval(code);
|
204
|
+
},
|
205
|
+
|
206
|
+
/*
|
207
|
+
Executes a bunch of methods. This method is called almost every time a communication to the server takes place.
|
208
|
+
Thus the server side of a widget can provide any set of commands to its client side.
|
209
|
+
Args:
|
210
|
+
- instructions: array of methods, in the order of execution.
|
211
|
+
Each item is an object in one of the following 2 formats:
|
212
|
+
1) {method1:args1, method2:args2}, where methodN is a name of a public method of this widget; these methods are called in no particular order
|
213
|
+
2) {widget:widget_id, methods:arrayOfMethods}, used for recursive call to bulkExecute on some child widget
|
214
|
+
|
215
|
+
Example:
|
216
|
+
- [
|
217
|
+
// the same as this.feedback("Your order is accepted")
|
218
|
+
{feedback: "You order is accepted"},
|
219
|
+
|
220
|
+
// the same as this.getChildWidget('users').bulkExecute([{setTitle:'Suprise!'}, {setDisabled:true}])
|
221
|
+
{widget:'users', methods:[{setTitle:'Suprise!'}, {setDisabled:true}] },
|
222
|
+
|
223
|
+
// ... etc:
|
224
|
+
{updateStore:{records:[[1, 'Name1'],[2, 'Name2']], total:10}},
|
225
|
+
{setColums:[{},{}]},
|
226
|
+
{setMenus:[{},{}]},
|
227
|
+
...
|
228
|
+
]
|
229
|
+
*/
|
230
|
+
bulkExecute : function(instructions){
|
231
|
+
if (Ext.isArray(instructions)) {
|
232
|
+
Ext.each(instructions, function(instruction){ this.bulkExecute(instruction)}, this);
|
233
|
+
} else {
|
234
|
+
for (var instr in instructions) {
|
235
|
+
if (this[instr]) {
|
236
|
+
this[instr].apply(this, [instructions[instr]]);
|
237
|
+
} else {
|
238
|
+
var childWidget = this.getChildWidget(instr);
|
239
|
+
if (childWidget) {
|
240
|
+
childWidget.bulkExecute(instructions[instr]);
|
241
|
+
} else {
|
242
|
+
throw "Unknown method or child widget '" + instr +"' in widget '" + this.id + "'"
|
243
|
+
}
|
244
|
+
}
|
245
|
+
}
|
246
|
+
}
|
247
|
+
},
|
248
|
+
|
249
|
+
// Get the child widget
|
250
|
+
getChildWidget : function(id){
|
251
|
+
return id === 'parent' ? this.getParent() : Ext.getCmp(this.id+"__"+id);
|
252
|
+
},
|
253
|
+
|
96
254
|
// Common handler for actions
|
97
255
|
actionHandler : function(action){
|
98
256
|
// If firing corresponding event doesn't return false, call the handler
|
@@ -109,11 +267,72 @@ Ext.widgetMixIn = {
|
|
109
267
|
}
|
110
268
|
},
|
111
269
|
|
112
|
-
|
270
|
+
// Does the call to the server and processes the response
|
271
|
+
callServer : function(intp, params, callback, scope){
|
272
|
+
if (!params) params = {};
|
273
|
+
Ext.Ajax.request({
|
274
|
+
params : params,
|
275
|
+
url : this.id + "__" + intp,
|
276
|
+
callback : function(options, success, response){
|
277
|
+
if (success) {
|
278
|
+
// execute commands from server
|
279
|
+
this.bulkExecute(Ext.decode(response.responseText));
|
280
|
+
|
281
|
+
// provade callback if needed
|
282
|
+
if (typeof callback == 'function') {
|
283
|
+
if (!scope) scope = this;
|
284
|
+
callback.apply(scope);
|
285
|
+
}
|
286
|
+
}
|
287
|
+
},
|
288
|
+
scope : this
|
289
|
+
});
|
290
|
+
},
|
291
|
+
|
292
|
+
/* Parse the bbar and tbar (both Arrays), replacing the strings with the corresponding methods. For example:
|
293
|
+
replaceStringsWithActions( ['add', {text:'Menu', menu:['edit', 'delete']}] )
|
294
|
+
=> [scope.actions['add'], {text:'Menu', menu:[scope.actions['edit'], scope.actions['delete']]}]
|
295
|
+
*/
|
296
|
+
normalizeMenuItems: function(arry, scope){
|
297
|
+
var res = []; // new array
|
298
|
+
Ext.each(arry, function(o){
|
299
|
+
if (typeof o === "string") {
|
300
|
+
var camelized = o.camelize(true);
|
301
|
+
if (scope.actions[camelized]){
|
302
|
+
res.push(scope.actions[camelized]);
|
303
|
+
} else {
|
304
|
+
// if there's no action with this name, maybe it's a separator or something
|
305
|
+
res.push(o);
|
306
|
+
}
|
307
|
+
} else if (Netzke.isObject(o)) {
|
308
|
+
// look inside the objects...
|
309
|
+
for (var key in o) {
|
310
|
+
if (Ext.isArray(o[key])) {
|
311
|
+
// ... and recursively process inner arrays found
|
312
|
+
o[key] = this.normalizeMenuItems(o[key], scope);
|
313
|
+
}
|
314
|
+
}
|
315
|
+
res.push(o);
|
316
|
+
}
|
317
|
+
}, this);
|
318
|
+
return res;
|
319
|
+
},
|
320
|
+
|
321
|
+
|
322
|
+
// Every Netzke widget
|
323
|
+
commonBeforeConstructor : function(config){
|
113
324
|
this.actions = {};
|
114
325
|
|
326
|
+
// Generate methods for api points
|
327
|
+
if (!config.api) { config.api = []; }
|
328
|
+
config.api.push('load_aggregatee_with_cache'); // all netzke widgets get this API
|
329
|
+
Ext.each(config.api, function(intp){
|
330
|
+
this[intp.camelize(true)] = function(args, callback, scope){ this.callServer(intp, args, callback, scope); }
|
331
|
+
}, this);
|
332
|
+
|
115
333
|
// Create Ext.Actions based on config.actions
|
116
334
|
if (config.actions) {
|
335
|
+
this.testActions = {};
|
117
336
|
for (var name in config.actions) {
|
118
337
|
// Create an event for each action (so that higher-level widgets could interfere)
|
119
338
|
this.addEvents(name+'click');
|
@@ -125,37 +344,13 @@ Ext.widgetMixIn = {
|
|
125
344
|
this.actions[name] = new Ext.Action(actionConfig);
|
126
345
|
}
|
127
346
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
if (typeof o === "string") {
|
136
|
-
var camelized = o.camelize(true);
|
137
|
-
if (scope.actions[camelized]){
|
138
|
-
res.push(scope.actions[camelized]);
|
139
|
-
} else {
|
140
|
-
// if there's no action with this name, maybe it's a separator or something
|
141
|
-
res.push(o);
|
142
|
-
}
|
143
|
-
} else if (Netzke.isObject(o)) {
|
144
|
-
// look inside the objects...
|
145
|
-
for (var key in o) {
|
146
|
-
if (Ext.isArray(o[key])) {
|
147
|
-
// ... and recursively process inner arrays found
|
148
|
-
o[key] = replaceStringsWithActions(o[key], scope);
|
149
|
-
}
|
150
|
-
}
|
151
|
-
res.push(o);
|
152
|
-
}
|
153
|
-
});
|
154
|
-
return res;
|
155
|
-
}
|
156
|
-
config.bbar = config.bbar && replaceStringsWithActions(config.bbar, this);
|
157
|
-
config.tbar = config.tbar && replaceStringsWithActions(config.tbar, this);
|
158
|
-
config.menu = config.menu && replaceStringsWithActions(config.menu, this);
|
347
|
+
config.bbar = config.bbar && this.normalizeMenuItems(config.bbar, this);
|
348
|
+
config.tbar = config.tbar && this.normalizeMenuItems(config.tbar, this);
|
349
|
+
config.menu = config.menu && this.normalizeMenuItems(config.menu, this);
|
350
|
+
config.contextMenu = config.contextMenu && this.normalizeMenuItems(config.contextMenu, this);
|
351
|
+
|
352
|
+
// TODO: need to rethink this action related stuff
|
353
|
+
config.actions = this.actions;
|
159
354
|
|
160
355
|
}
|
161
356
|
|
@@ -172,22 +367,31 @@ Ext.widgetMixIn = {
|
|
172
367
|
config.tools = normTools;
|
173
368
|
}
|
174
369
|
|
370
|
+
// Set title
|
371
|
+
if (!config.title) config.title = config.id.humanize();
|
175
372
|
},
|
176
373
|
|
177
|
-
|
374
|
+
// At this moment component is fully initializied
|
375
|
+
commonAfterConstructor : function(config){
|
376
|
+
// From everywhere accessible FeedbackGhost
|
178
377
|
this.feedbackGhost = Ext.getCmp('feedback_ghost');
|
179
378
|
|
180
|
-
//
|
379
|
+
// Add the menus
|
380
|
+
if (this.initialConfig.menu) {this.addMenu(this.initialConfig.menu, this);}
|
381
|
+
|
382
|
+
// generic events
|
383
|
+
this.addEvents(
|
384
|
+
'widgetload' // fired when a child is dynamically loaded
|
385
|
+
);
|
386
|
+
|
387
|
+
// Cleaning up on destroy
|
181
388
|
this.on('beforedestroy', function(){
|
182
|
-
this.cleanUpMenu(
|
389
|
+
this.cleanUpMenu();
|
183
390
|
}, this);
|
184
391
|
|
185
|
-
|
186
|
-
this.on('render', function(){
|
187
|
-
if (this.initialConfig.menu) {this.addMenu(this.initialConfig.menu);}
|
188
|
-
}, this);
|
392
|
+
this.callbackHash = {};
|
189
393
|
|
190
|
-
this.
|
394
|
+
if (this.afterConstructor) this.afterConstructor(config);
|
191
395
|
},
|
192
396
|
|
193
397
|
feedback:function(msg){
|
@@ -247,7 +451,7 @@ Ext.widgetMixIn = {
|
|
247
451
|
// Netzke extensions for Ext.Container
|
248
452
|
Ext.override(Ext.Container, {
|
249
453
|
/**
|
250
|
-
Get Netzke widget that this Ext.Container is part of
|
454
|
+
Get Netzke widget that this Ext.Container is part of (*not* the parent widget, for which call getParent)
|
251
455
|
It searches up the Ext.Container hierarchy until it finds a Container that has isNetzke property set to true
|
252
456
|
(or until it reaches the top).
|
253
457
|
*/
|
@@ -261,70 +465,24 @@ Ext.override(Ext.Container, {
|
|
261
465
|
return null
|
262
466
|
}
|
263
467
|
}
|
264
|
-
}
|
265
|
-
|
266
|
-
|
267
|
-
// Make Panel with layout 'fit' capable of dynamic widgets loading
|
268
|
-
Ext.override(Ext.Panel, {
|
468
|
+
},
|
469
|
+
|
470
|
+
// Get the widget that we are hosting
|
269
471
|
getWidget: function(){
|
270
|
-
return this.items.get(0);
|
472
|
+
return this.items ? this.items.get(0) : null; // need this check in case when the container is not yet rendered, like an inactive tab in the TabPanel
|
271
473
|
},
|
272
474
|
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
475
|
+
removeChild : function(){
|
476
|
+
this.remove(this.getWidget());
|
477
|
+
},
|
478
|
+
|
479
|
+
instantiateChild : function(config){
|
278
480
|
this.remove(this.getWidget()); // first delete previous widget
|
279
|
-
|
280
|
-
if (!url) return false; // don't load any widget if the url is null
|
281
481
|
|
282
|
-
|
283
|
-
var cachedComponentNames = [];
|
284
|
-
for (name in Ext.netzke.cache) {
|
285
|
-
cachedComponentNames.push(name);
|
286
|
-
}
|
287
|
-
|
288
|
-
this.disable(); // to visually emphasize loading
|
289
|
-
|
290
|
-
Ext.Ajax.request({
|
291
|
-
url:url,
|
292
|
-
params:Ext.apply(params, {components_cache:Ext.encode(cachedComponentNames)}),
|
293
|
-
script:false,
|
294
|
-
callback:function(panel, success, response){
|
295
|
-
var responseObj = Ext.decode(response.responseText);
|
296
|
-
if (responseObj.config) {
|
297
|
-
// we got a normal response
|
298
|
-
|
299
|
-
// evaluate widget's stylesheets
|
300
|
-
if (responseObj.css){
|
301
|
-
var linkTag = document.createElement('style');
|
302
|
-
linkTag.type = 'text/css';
|
303
|
-
linkTag.innerHTML = responseObj.css;
|
304
|
-
document.body.appendChild(linkTag);
|
305
|
-
}
|
306
|
-
|
307
|
-
// evaluate widget's javascript
|
308
|
-
if (responseObj.js) {
|
309
|
-
eval(responseObj.js);
|
310
|
-
}
|
311
|
-
|
312
|
-
responseObj.config.ownerWidget = this.getOwnerWidget();
|
313
|
-
var instance = new Ext.netzke.cache[responseObj.config.widgetClassName](responseObj.config)
|
314
|
-
|
315
|
-
this.add(instance);
|
316
|
-
this.doLayout();
|
317
|
-
|
318
|
-
} else {
|
319
|
-
// we didn't get normal response - desplay the flash with eventual errors
|
320
|
-
this.getOwnerWidget().feedback(responseObj.flash);
|
321
|
-
}
|
322
|
-
|
323
|
-
// reenable the panel
|
324
|
-
this.enable();
|
325
|
-
},
|
326
|
-
scope:this
|
327
|
-
})
|
328
|
-
}
|
329
|
-
});
|
482
|
+
if (!config) return false; // simply remove current widget if null is passed
|
330
483
|
|
484
|
+
var instance = new Ext.netzke.cache[config.widgetClassName](config);
|
485
|
+
this.add(instance);
|
486
|
+
this.doLayout();
|
487
|
+
}
|
488
|
+
});
|