View | Details | Raw Unified | Return to bug 26214 | Differences between
and this patch

Collapse All | Expand All

(-)umc/widgets/Form.js (-41 / +35 lines)
 Lines 26-44    Link Here 
26
 * /usr/share/common-licenses/AGPL-3; if not, see
26
 * /usr/share/common-licenses/AGPL-3; if not, see
27
 * <http://www.gnu.org/licenses/>.
27
 * <http://www.gnu.org/licenses/>.
28
 */
28
 */
29
/*global define */
29
/*global define require console*/
30
30
31
define([
31
define([
32
	"dojo/_base/declare",
32
	"dojo/_base/declare",
33
	"dojo/_base/lang",
33
	"dojo/_base/lang",
34
	"dojo/_base/array",
34
	"dojo/_base/array",
35
	"dojo/Deferred",
35
	"dojo/Deferred",
36
	"dojo/on",
36
	"dojo/promise/all",
37
	"dojo/dom-style",
37
	"dojo/dom-style",
38
	"dijit/form/Form",
38
	"dijit/form/Form",
39
	"umc/tools",
39
	"umc/tools",
40
	"umc/render"
40
	"umc/render"
41
], function(declare, lang, array, Deferred, on, style, Form, tools, render) {
41
], function(declare, lang, array, Deferred, all, style, Form, tools, render) {
42
42
43
	// in order to break circular dependencies (umc.dialog needs a Form and
43
	// in order to break circular dependencies (umc.dialog needs a Form and
44
	// Form needs umc/dialog), we define umc/dialog as an empty object and
44
	// Form needs umc/dialog), we define umc/dialog as an empty object and
 Lines 121-133    Link Here 
121
121
122
		//'class': 'umcNoBorder',
122
		//'class': 'umcNoBorder',
123
123
124
		_initializingElements: 0,
124
		_allReady: null,
125
125
126
		_initializedDeferred: null,
127
128
		postMixInProperties: function() {
126
		postMixInProperties: function() {
129
			this.inherited(arguments);
127
			this.inherited(arguments);
130
128
129
			// initialize with empty list
130
			this._allReady = [];
131
131
			// in case no layout is specified and no content, either, create one automatically
132
			// in case no layout is specified and no content, either, create one automatically
132
			if ((!this.layout || !this.layout.length) && !this.content) {
133
			if ((!this.layout || !this.layout.length) && !this.content) {
133
				this.layout = [];
134
				this.layout = [];
 Lines 183-190    Link Here 
183
		buildRendering: function() {
184
		buildRendering: function() {
184
			this.inherited(arguments);
185
			this.inherited(arguments);
185
186
186
			this._initializedDeferred = new Deferred();
187
188
			if (this.scrollable) {
187
			if (this.scrollable) {
189
				style.set(this.containerNode, {
188
				style.set(this.containerNode, {
190
					overflow: 'auto'
189
					overflow: 'auto'
 Lines 225-271    Link Here 
225
				}
224
				}
226
			}
225
			}
227
226
228
227
			this._updateAllReady();
229
			// send an event when all dynamic elements have been initialized
230
			this._initializingElements = 0;
231
			//console.log('# Form.buildRendering()');
232
			tools.forIn(this._widgets, function(iname, iwidget) {
233
				// only consider elements that load values dynamically
234
				//console.log('#  iwidget:', iwidget.name);
235
				if ('onValuesLoaded' in iwidget && !(iwidget._valuesLoaded && !iwidget._deferredOrValues)) {
236
					// widget values have not been loaded completely so far
237
					//console.log('#  -> has event "valuesLoaded"');
238
					++this._initializingElements;
239
					on.once(iwidget, 'valuesLoaded', lang.hitch(this, function() {
240
						//console.log('#  -> valuesLoaded:', iwidget.name, iwidget.get('value'));
241
						// decrement the internal counter
242
						--this._initializingElements;
243
						//console.log('#  _initializingElements:', this._initializingElements);
244
245
						// send event when the last element has been initialized
246
						if (0 === this._initializingElements) {
247
							this._initializedDeferred.resolve();
248
						}
249
					}));
250
				}
251
			}, this);
252
253
			// maybe all elements are already initialized
254
			if (!this._initializingElements) {
255
				this._initializedDeferred.resolve();
256
			}
257
258
		},
228
		},
259
229
260
		startup: function() {
230
		startup: function() {
231
			//console.log('### Form: startup - container:', this._container);
261
			this.inherited(arguments);
232
			this.inherited(arguments);
262
			if (this._container) {
233
			if (this._container) {
263
				// call the containers startup function if necessary
234
				// call the containers startup function if necessary
264
				this._container.startup();
235
				this._container.startup();
265
			}
236
			}
266
			this._initializedDeferred.then(lang.hitch(this, function() {
237
			this.ready().then(lang.hitch(this, function() {
238
				//console.log('### Form: all ready');
267
				this.onValuesInitialized();
239
				this.onValuesInitialized();
268
				//console.log('# valuesInitialized');
269
			}));
240
			}));
270
		},
241
		},
271
242
 Lines 553-560    Link Here 
553
					dialog.notify(error_msg);
524
					dialog.notify(error_msg);
554
				}
525
				}
555
			}));
526
			}));
556
		}
527
		},
557
528
529
		_updateAllReady: function() {
530
			// wait for all widgets to be ready
531
			this._allReady = [];
532
			//console.log('### Form: iterate over widgets.ready');
533
			tools.forIn(this._widgets, function(iname, iwidget) {
534
				//console.log('###   ' + iname + ' -> ', iwidget.ready ? iwidget.ready() : null);
535
				this._allReady.push(iwidget.ready ? iwidget.ready() : null);
536
			}, this);
537
		},
538
539
		ready: function() {
540
			// update the internal list in order to wait until everybody is ready
541
			if (!this._allReady.length) {
542
				_updateAllReady();
543
			}
544
			var ret = all(this._allReady);
545
546
			// empty list when all widgets are ready
547
			ret.then(lang.hitch(this, function() {
548
				this._allReady = [];
549
			}));
550
			return ret;
551
		}
558
	});
552
	});
559
});
553
});
560
554
(-)umc/widgets/MultiInput.js (-2 / +55 lines)
 Lines 32-44    Link Here 
32
	"dojo/_base/declare",
32
	"dojo/_base/declare",
33
	"dojo/_base/lang",
33
	"dojo/_base/lang",
34
	"dojo/_base/array",
34
	"dojo/_base/array",
35
	"dojo/Deferred",
36
	"dojo/promise/all",
35
	"dijit/form/Button",
37
	"dijit/form/Button",
36
	"umc/tools",
38
	"umc/tools",
37
	"umc/render",
39
	"umc/render",
38
	"umc/widgets/ContainerWidget",
40
	"umc/widgets/ContainerWidget",
39
	"umc/widgets/_FormWidgetMixin",
41
	"umc/widgets/_FormWidgetMixin",
40
	"umc/widgets/LabelPane"
42
	"umc/widgets/LabelPane"
41
], function(declare, lang, array, Button, tools, render, ContainerWidget, _FormWidgetMixin, LabelPane) {
43
], function(declare, lang, array, Deferred, all, Button, tools, render, ContainerWidget, _FormWidgetMixin, LabelPane) {
42
	return declare("umc.widgets.MultiInput", [ ContainerWidget, _FormWidgetMixin ], {
44
	return declare("umc.widgets.MultiInput", [ ContainerWidget, _FormWidgetMixin ], {
43
		// summary:
45
		// summary:
44
		//		Widget for a small list of simple and complex entries. An entry can be one or
46
		//		Widget for a small list of simple and complex entries. An entry can be one or
 Lines 77-82    Link Here 
77
79
78
		_lastDepends: null,
80
		_lastDepends: null,
79
81
82
		_valuesLoaded: false,
83
84
		_readyDeferred: null,
85
86
		_startupDeferred: null,
87
80
		_createHandler: function(ifunc) {
88
		_createHandler: function(ifunc) {
81
			// This handler will be called by all subwidgets of the MultiInput widget.
89
			// This handler will be called by all subwidgets of the MultiInput widget.
82
			// When the first request comes in, we will execute the function to compute
90
			// When the first request comes in, we will execute the function to compute
 Lines 106-113    Link Here 
106
		postMixInProperties: function() {
114
		postMixInProperties: function() {
107
			this.inherited(arguments);
115
			this.inherited(arguments);
108
116
117
			// delete the size class
109
			this.sizeClass = null;
118
			this.sizeClass = null;
110
119
120
			// the _readyDeferred is being resolved as soon as everything has been set up
121
			this._readyDeferred = new Deferred();
122
123
			this._startupDeferred = new Deferred();
124
111
			// check the property 'subtypes'
125
			// check the property 'subtypes'
112
			tools.assert(this.subtypes instanceof Array,
126
			tools.assert(this.subtypes instanceof Array,
113
					'umc/widgets/ContainerWidget: The property subtypes needs to be a string or an array of strings: ' + this.subtypes);
127
					'umc/widgets/ContainerWidget: The property subtypes needs to be a string or an array of strings: ' + this.subtypes);
 Lines 149-154    Link Here 
149
			this._appendElements(1);
163
			this._appendElements(1);
150
		},
164
		},
151
165
166
		startup: function() {
167
			this.inherited(arguments);
168
169
			this._startupDeferred.resolve();
170
		},
171
152
		_loadValues: function(depends) {
172
		_loadValues: function(depends) {
153
			// delegate the call to _loadValues to all widgets
173
			// delegate the call to _loadValues to all widgets
154
			this._lastDepends = depends;
174
			this._lastDepends = depends;
 Lines 316-321    Link Here 
316
				return;
336
				return;
317
			}
337
			}
318
338
339
			// initiate a new Deferred object in case there is none already pending
340
			if (this._readyDeferred.isFulfilled()) {
341
				this._readyDeferred = new Deferred();
342
			}
343
319
			// remove the 'new' button
344
			// remove the 'new' button
320
			this._removeNewButton();
345
			this._removeNewButton();
321
346
 Lines 403-409    Link Here 
403
				// add row
428
				// add row
404
				this._widgets.push(visibleWidgets);
429
				this._widgets.push(visibleWidgets);
405
				this._rowContainers.push(rowContainer);
430
				this._rowContainers.push(rowContainer);
406
				rowContainer.startup();
431
				this._startupDeferred.then(lang.hitch(rowContainer, 'startup'));
407
				this.addChild(rowContainer);
432
				this.addChild(rowContainer);
408
433
409
				// call the _loadValues method by hand
434
				// call the _loadValues method by hand
 Lines 415-420    Link Here 
415
				}, this);
440
				}, this);
416
			}
441
			}
417
442
443
			// wait for all widgets to be ready
444
			var allReady = [];
445
			var i, j;
446
			for (i = 0; i < this._widgets.length; ++i) {
447
				for (j = 0; j < this._widgets[i].length; ++j) {
448
					//console.log(lang.replace('### MultiInput: widget[{0}][{1}]: waiting -> ', [i, j]), this._widgets[i][j].ready());
449
					allReady.push(this._widgets[i][j].ready ? this._widgets[i][j].ready() : null);
450
				}
451
			}
452
			all(allReady).then(lang.hitch(this, function() {
453
				//console.log('### MultiInput: all resolved');
454
				this._readyDeferred.resolve();
455
				this.onValuesLoaded();
456
			}));
457
418
			// add the new button
458
			// add the new button
419
			if (this._nRenderedElements < this.max) {
459
			if (this._nRenderedElements < this.max) {
420
				this._addNewButton();
460
				this._addNewButton();
 Lines 494-499    Link Here 
494
			if (this._widget) {
534
			if (this._widget) {
495
				tools.delegateCall(this, arguments, this._widget);
535
				tools.delegateCall(this, arguments, this._widget);
496
			}
536
			}
537
		},
538
539
		onValuesLoaded: function(values) {
540
			// summary:
541
			//		This event is triggered when all values (static and dynamic) have been loaded.
542
			// values:
543
			//		Array containing all dynamic and static values.
544
		},
545
546
		// ready:
547
		//		Similiar to `umc/widgets/_FormWidgetMixin:ready`.
548
		ready: function() {
549
			return this._readyDeferred;
497
		}
550
		}
498
	});
551
	});
499
});
552
});
(-)umc/widgets/_SelectMixin.js (-4 / +30 lines)
 Lines 34-46    Link Here 
34
	"dojo/_base/array",
34
	"dojo/_base/array",
35
	"dojo/Deferred",
35
	"dojo/Deferred",
36
	"dojo/when",
36
	"dojo/when",
37
	"dojo/on",
38
	"dojo/json",
37
	"dojo/json",
39
	"dojo/Stateful",
38
	"dojo/Stateful",
40
	// TODO: should use dojo/store/
39
	// TODO: should use dojo/store/
41
	"dojo/data/ItemFileWriteStore",
40
	"dojo/data/ItemFileWriteStore",
42
	"umc/tools"
41
	"umc/tools"
43
], function(declare, lang, array, Deferred, when, on, json, Stateful, ItemFileWriteStore, tools) {
42
], function(declare, lang, array, Deferred, when, json, Stateful, ItemFileWriteStore, tools) {
44
	return declare("umc.widgets._SelectMixin", Stateful, {
43
	return declare("umc.widgets._SelectMixin", Stateful, {
45
		// umcpCommand:
44
		// umcpCommand:
46
		//		Reference to the umcpCommand the widget should use.
45
		//		Reference to the umcpCommand the widget should use.
 Lines 105-110    Link Here 
105
104
106
		_deferredOrValues: null,
105
		_deferredOrValues: null,
107
106
107
		_readyDeferred: null,
108
108
		_createStore: function() {
109
		_createStore: function() {
109
			return new ItemFileWriteStore({
110
			return new ItemFileWriteStore({
110
				data: {
111
				data: {
 Lines 128-133    Link Here 
128
			this.inherited(arguments);
129
			this.inherited(arguments);
129
130
130
			this._saveInitialValue();
131
			this._saveInitialValue();
132
133
			// the _readyDeferred is being resolved as soon as everything has been set up
134
			//console.log('### _SelectMixin ['+this.name+']: initiate _readyDeferred');
135
			this._readyDeferred = new Deferred();
131
		},
136
		},
132
137
133
		postCreate: function() {
138
		postCreate: function() {
 Lines 382-388    Link Here 
382
		},
387
		},
383
388
384
		_loadValues: function(/*Object?*/ _dependValues) {
389
		_loadValues: function(/*Object?*/ _dependValues) {
385
			//console.log('###', this.name, ' _loadValues(', _dependValues, ')');
390
			//console.log('### _SelectMixin ['+this.name+']: _loadValues');
386
			this._valuesLoaded = true;
391
			this._valuesLoaded = true;
387
392
388
			// unify `depends` property to be an array
393
			// unify `depends` property to be an array
 Lines 404-409    Link Here 
404
409
405
			// only load dynamic values in case all dependencies are fullfilled
410
			// only load dynamic values in case all dependencies are fullfilled
406
			if (dependList.length != nDepValues) {
411
			if (dependList.length != nDepValues) {
412
				//console.log('### _SelectMixin ['+this.name+']: return');
407
				return;
413
				return;
408
			}
414
			}
409
415
 Lines 420-428    Link Here 
420
			// block concurrent events for value loading
426
			// block concurrent events for value loading
421
			if (this._deferredOrValues) {
427
			if (this._deferredOrValues) {
422
				// another request is pending
428
				// another request is pending
429
				//console.log('### _SelectMixin ['+this.name+']: return (2)');
423
				return;
430
				return;
424
			}
431
			}
425
432
433
			// initiate a new Deferred object in case there is none already pending
434
			if (this._readyDeferred.isFulfilled()) {
435
				//console.log('### _SelectMixin ['+this.name+']: re-initiate _readyDeferred');
436
				this._readyDeferred = new Deferred();
437
			}
438
426
			// get dynamic values
439
			// get dynamic values
427
			var func = tools.stringOrFunction(this.dynamicValues, this.umcpCommand);
440
			var func = tools.stringOrFunction(this.dynamicValues, this.umcpCommand);
428
			var deferredOrValues = func(params);
441
			var deferredOrValues = func(params);
 Lines 439-447    Link Here 
439
					this._clearValues();
452
					this._clearValues();
440
					this._setStaticValues();
453
					this._setStaticValues();
441
					this._setDynamicValues(res);
454
					this._setDynamicValues(res);
442
					this.onDynamicValuesLoaded(res);
443
455
444
					// values have been loaded
456
					// values have been loaded
457
					//console.log('### _SelectMixin ['+this.name+']: resolved _readyDeferred');
458
					this._readyDeferred.resolve(this.getAllItems());
459
					this.onDynamicValuesLoaded(res);
445
					this.onValuesLoaded(this.getAllItems());
460
					this.onValuesLoaded(this.getAllItems());
446
461
447
					// unblock value loading
462
					// unblock value loading
 Lines 452-457    Link Here 
452
					this._setStaticValues();
467
					this._setStaticValues();
453
468
454
					// error handler
469
					// error handler
470
					//console.log('### _SelectMixin ['+this.name+']: resolved _readyDeferred');
471
					this._readyDeferred.resolve([]);
455
					this.onDynamicValuesLoaded([]);
472
					this.onDynamicValuesLoaded([]);
456
					this.onValuesLoaded(this.getAllItems());
473
					this.onValuesLoaded(this.getAllItems());
457
474
 Lines 465-470    Link Here 
465
				this._setStaticValues();
482
				this._setStaticValues();
466
483
467
				// values have been loaded
484
				// values have been loaded
485
				//console.log('### _SelectMixin ['+this.name+']: resolved _readyDeferred');
486
				this._readyDeferred.resolve(this.getAllItems());
468
				this.onValuesLoaded(this.getAllItems());
487
				this.onValuesLoaded(this.getAllItems());
469
488
470
				// unblock value loading
489
				// unblock value loading
 Lines 532-537    Link Here 
532
			if (this._valuesLoaded) {
551
			if (this._valuesLoaded) {
533
				this._loadValues();
552
				this._loadValues();
534
			}
553
			}
554
		},
555
556
		// ready:
557
		//		Returns null or a Deferred which resolves as soon as any
558
		//		loading activity of the widget is finished.
559
		ready: function() {
560
			return this._readyDeferred;
535
		}
561
		}
536
	});
562
	});
537
});
563
});
(-)umc/widgets/MixedInput.js (-1 / +19 lines)
 Lines 31-36    Link Here 
31
define([
31
define([
32
	"dojo/_base/declare",
32
	"dojo/_base/declare",
33
	"dojo/_base/lang",
33
	"dojo/_base/lang",
34
	"dojo/Deferred",
34
	"dojo/json",
35
	"dojo/json",
35
	"dijit/layout/ContentPane",
36
	"dijit/layout/ContentPane",
36
	"umc/tools",
37
	"umc/tools",
 Lines 38-44    Link Here 
38
	"umc/widgets/TextBox",
39
	"umc/widgets/TextBox",
39
	"umc/widgets/ComboBox",
40
	"umc/widgets/ComboBox",
40
	"umc/widgets/CheckBox"
41
	"umc/widgets/CheckBox"
41
], function(declare, lang, json, ContentPane, tools, _FormWidgetMixin) {
42
], function(declare, lang, Deferred, json, ContentPane, tools, _FormWidgetMixin) {
42
	return declare("umc.widgets.MixedInput", [ ContentPane, _FormWidgetMixin ], {
43
	return declare("umc.widgets.MixedInput", [ ContentPane, _FormWidgetMixin ], {
43
		// umcpCommand:
44
		// umcpCommand:
44
		//		Reference to the umcpCommand the widget should use.
45
		//		Reference to the umcpCommand the widget should use.
 Lines 74-79    Link Here 
74
75
75
		style: 'padding: 0',
76
		style: 'padding: 0',
76
77
78
		_readyDeferred: null,
79
77
		constructor: function(/*Object*/ props) {
80
		constructor: function(/*Object*/ props) {
78
			// mixin in the 'disabled' property
81
			// mixin in the 'disabled' property
79
			props.disabled = this.disabled;
82
			props.disabled = this.disabled;
 Lines 94-99    Link Here 
94
97
95
			this._userProperties.sizeClass = this.sizeClass;
98
			this._userProperties.sizeClass = this.sizeClass;
96
			this.sizeClass = null;
99
			this.sizeClass = null;
100
101
			this._readyDeferred = new Deferred();
97
		},
102
		},
98
103
99
		buildRendering: function() {
104
		buildRendering: function() {
 Lines 135-140    Link Here 
135
				return;
140
				return;
136
			}
141
			}
137
142
143
			// initiate a new Deferred object in case there is none already pending
144
			if (this._readyDeferred.isFulfilled()) {
145
				this._readyDeferred = new Deferred();
146
			}
147
138
			// mixin additional options for the UMCP command
148
			// mixin additional options for the UMCP command
139
			if (this.dynamicOptions && typeof this.dynamicOptions == "object") {
149
			if (this.dynamicOptions && typeof this.dynamicOptions == "object") {
140
				lang.mixin(params, this.dynamicOptions);
150
				lang.mixin(params, this.dynamicOptions);
 Lines 199-204    Link Here 
199
			this._widget.startup();
209
			this._widget.startup();
200
210
201
			this.onValuesLoaded();
211
			this.onValuesLoaded();
212
			this._readyDeferred.resolve();
202
		},
213
		},
203
214
204
		_setValueAttr: function(newVal) {
215
		_setValueAttr: function(newVal) {
 Lines 249-254    Link Here 
249
			if (lang.getObject('_widget.focus', false, this)) {
260
			if (lang.getObject('_widget.focus', false, this)) {
250
				this._widget.focus();
261
				this._widget.focus();
251
			}
262
			}
263
		},
264
265
		// ready:
266
		//		Returns null or a Deferred which resolves as soon as any
267
		//		loading activity of the widget is finished.
268
		ready: function() {
269
			return this._readyDeferred;
252
		}
270
		}
253
	});
271
	});
254
});
272
});
(-)umc/widgets/LabelPane.js (-1 / +29 lines)
 Lines 31-43    Link Here 
31
define([
31
define([
32
	"dojo/_base/declare",
32
	"dojo/_base/declare",
33
	"dojo/_base/lang",
33
	"dojo/_base/lang",
34
	"dojo/Deferred",
34
	"dojo/dom-class",
35
	"dojo/dom-class",
35
	"dojo/dom-attr",
36
	"dojo/dom-attr",
36
	"dijit/_WidgetBase",
37
	"dijit/_WidgetBase",
37
	"dijit/_TemplatedMixin",
38
	"dijit/_TemplatedMixin",
38
	"dijit/_Container",
39
	"dijit/_Container",
39
	"umc/tools"
40
	"umc/tools"
40
], function(declare, lang, domClass, attr, _WidgetBase, _TemplatedMixin, _Container, tools) {
41
], function(declare, lang, Deferred, domClass, attr, _WidgetBase, _TemplatedMixin, _Container, tools) {
41
	lang.extend(_WidgetBase, {
42
	lang.extend(_WidgetBase, {
42
		// isLabelDisplayed: Boolean?
43
		// isLabelDisplayed: Boolean?
43
		//		If specified as true, LabelPane assumes that the widget itself will take
44
		//		If specified as true, LabelPane assumes that the widget itself will take
 Lines 81-86    Link Here 
81
82
82
		labelNodeRight: null,
83
		labelNodeRight: null,
83
84
85
		_startupDeferred: null,
86
87
		constructor: function(params) {
88
			this._startupDeferred = new Deferred();
89
90
			// lang._mixin() would not work sometimes, leaving this.content empty, see
91
			//   https://forge.univention.org/bugzilla/show_bug.cgi?id=26214#c3
92
			tools.forIn(params, function(ikey, ival) {
93
				this[ikey] = ival;
94
			}, this);
95
		},
96
84
		postMixInProperties: function() {
97
		postMixInProperties: function() {
85
			this.inherited(arguments);
98
			this.inherited(arguments);
86
99
 Lines 120-125    Link Here 
120
			domClass.toggle(this.domNode, 'dijitHidden', this.content.visible === false);
133
			domClass.toggle(this.domNode, 'dijitHidden', this.content.visible === false);
121
		},
134
		},
122
135
136
		startup: function() {
137
			this.inherited(arguments);
138
139
			this._startupDeferred.resolve();
140
			if (lang.getObject('content.startup', false, this)) {
141
				this.content.startup();
142
			}
143
		},
144
123
		_setLabelAttr: function(label) {
145
		_setLabelAttr: function(label) {
124
			if (lang.getObject('content.isLabelDisplayed', false, this)) {
146
			if (lang.getObject('content.isLabelDisplayed', false, this)) {
125
				// the widget displays the label itself
147
				// the widget displays the label itself
 Lines 164-169    Link Here 
164
			else if (lang.getObject('domNode', false, content) && lang.getObject('declaredClass', false, content)) {
186
			else if (lang.getObject('domNode', false, content) && lang.getObject('declaredClass', false, content)) {
165
				this.contentNode.innerHTML = '';
187
				this.contentNode.innerHTML = '';
166
				this.addChild(content);
188
				this.addChild(content);
189
				if (content.startup) {
190
					this._startupDeferred.then(function() {
191
						// call widget's startup after we have been started up
192
						content.startup();
193
					});
194
				}
167
			}
195
			}
168
			this.set( 'disabled', this.disabled );
196
			this.set( 'disabled', this.disabled );
169
		},
197
		},
(-)umc/widgets/ComplexInput.js (+30 lines)
 Lines 57-62    Link Here 
57
57
58
		umcpCommand: tools.umcpCommand,
58
		umcpCommand: tools.umcpCommand,
59
59
60
		_allReady: null,
61
62
		constructor: function() {
63
			// initialize with empty list
64
			this._allReady = [];
65
		},
66
60
		buildRendering: function() {
67
		buildRendering: function() {
61
			this.inherited(arguments);
68
			this.inherited(arguments);
62
69
 Lines 101-106    Link Here 
101
				}
108
				}
102
			}, this);
109
			}, this);
103
110
111
			this._updateAllReady();
104
		},
112
		},
105
113
106
		_getValueAttr: function() {
114
		_getValueAttr: function() {
 Lines 127-132    Link Here 
127
				var iisValid = areValid instanceof Array ? areValid[i] : areValid;
135
				var iisValid = areValid instanceof Array ? areValid[i] : areValid;
128
				this._widgets[ iname ].setValid( iisValid, imessage );
136
				this._widgets[ iname ].setValid( iisValid, imessage );
129
			}, this );
137
			}, this );
138
		},
139
140
		_updateAllReady: function() {
141
			// wait for all widgets to be ready
142
			this._allReady = [];
143
			tools.forIn(this._widgets, function(iname, iwidget) {
144
				this._allReady.push(iwidget.ready ? iwidget.ready() : null);
145
			}, this);
146
		},
147
148
		ready: function() {
149
			// update the internal list in order to wait until everybody is ready
150
			if (!this._allReady.length) {
151
				_updateAllReady();
152
			}
153
			var ret = all(this._allReady);
154
155
			// empty list when all widgets are ready
156
			ret.then(lang.hitch(this, function() {
157
				this._allReady = [];
158
			}));
159
			return ret;
130
		}
160
		}
131
	});
161
	});
132
});
162
});
(-)umc/widgets/LoginDialog.js (-9 / +20 lines)
 Lines 88-94    Link Here 
88
				style: 'margin-left: auto; margin-right: auto; margin-top: 1em; width: 280px;',
88
				style: 'margin-left: auto; margin-right: auto; margin-top: 1em; width: 280px;',
89
				content: ''
89
				content: ''
90
			});
90
			});
91
			this._text.placeAt(this.containerNode, 'first');
92
91
93
			// create the language_combobox
92
			// create the language_combobox
94
			this._languageBox = new ComboBox({
93
			this._languageBox = new ComboBox({
 Lines 100-113    Link Here 
100
				label: _('Language'),
99
				label: _('Language'),
101
				content: this._languageBox
100
				content: this._languageBox
102
			});
101
			});
103
			// we need to manually startup the widgets
104
			this._languageBox.startup();
105
			this._languageLabel.startup();
106
			this._languageLabel.placeAt('umc_LoginDialog_FormContainer');
107
			// register onchange event
108
			this.own(this._languageBox.watch('value', function(name, oldLang, newLang) {
109
				i18nTools.setLanguage(newLang);
110
			}));
111
102
112
			// automatically resize the DialogUnderlay container
103
			// automatically resize the DialogUnderlay container
113
			this.own(on(win.global, 'resize', lang.hitch(this, function() {
104
			this.own(on(win.global, 'resize', lang.hitch(this, function() {
 Lines 117-122    Link Here 
117
			})));
108
			})));
118
		},
109
		},
119
110
111
		postCreate: function() {
112
			this.inherited(arguments);
113
114
			this._text.placeAt(this.containerNode, 'first');
115
			this._languageLabel.placeAt('umc_LoginDialog_FormContainer');
116
		},
117
118
		startup: function() {
119
			this.inherited(arguments);
120
121
			// we need to manually startup the widgets
122
			this._languageBox.startup();
123
			this._languageLabel.startup();
124
125
			// register onchange event
126
			this.own(this._languageBox.watch('value', function(name, oldLang, newLang) {
127
				i18nTools.setLanguage(newLang);
128
			}));
129
		},
130
120
		_initForm: function() {
131
		_initForm: function() {
121
			// wait until the iframe is completely loaded
132
			// wait until the iframe is completely loaded
122
			setTimeout(lang.hitch(this, function() {
133
			setTimeout(lang.hitch(this, function() {
(-)tests/depends.html (-2 / +27 lines)
 Lines 30-36    Link Here 
30
				async: true
30
				async: true
31
			};
31
			};
32
		</script>
32
		</script>
33
		<script type="text/javascript" src="/univention-management-console/js/dojo/dojo.js"></script>
33
		<script type="text/javascript" src="/univention-management-console/js/dojo/dojo.js.uncompressed.js"></script>
34
		<script type="text/javascript">
34
		<script type="text/javascript">
35
			require([
35
			require([
36
				"dojo/_base/window",
36
				"dojo/_base/window",
 Lines 244-249    Link Here 
244
				}, {
244
				}, {
245
					type: 'Text',
245
					type: 'Text',
246
					label: '',
246
					label: '',
247
					name: 'test8',
248
					content: '<h1>Test case: MultiInput w/ComboBox &amp; dynamicValues -> check for onValuesLoaded</h1>'
249
				}, {
250
					type: 'Text',
251
					label: '',
252
					name: 'Text8',
253
					style: 'color:red; font-weight: bold;',
254
					content: 'values are loading...'
255
				}, {
256
					type: 'MultiInput',
257
					name: 'MultiInput8',
258
					subtypes: [{
259
						type: 'ComboBox',
260
						dynamicOptions: { _data: valuesColors },
261
						dynamicValues: valuesAsync,
262
						label: 'Test'
263
					}],
264
					label: 'MultiInput'
265
				}, {
266
					type: 'Text',
267
					label: '',
247
					name: 'test7',
268
					name: 'test7',
248
					content: '<h1>Test case: disabled ComboBoxes with staticValues and dynamicValues</h1>'
269
					content: '<h1>Test case: disabled ComboBoxes with staticValues and dynamicValues</h1>'
249
				}, {
270
				}, {
 Lines 300-308    Link Here 
300
						'test4', ['MultiInput4-1', 'ComboBox4-1'],
321
						'test4', ['MultiInput4-1', 'ComboBox4-1'],
301
						'test5', ['MultiSelect5-1', 'ComboBox5-1'],
322
						'test5', ['MultiSelect5-1', 'ComboBox5-1'],
302
						'test6', 'MultiInput6',
323
						'test6', 'MultiInput6',
303
						'test7', 'MultiInput7-1', 'MultiInput7-2', 'ComboBox7-1', 'ComboBox7-2'
324
						'test7', 'MultiInput7-1', 'MultiInput7-2', 'ComboBox7-1', 'ComboBox7-2',
325
						'test8', 'MultiInput8', 'Text8'
304
					]
326
					]
305
				});
327
				});
328
				/*form.getWidget('MultiInput8').ready().then(function() {
329
					form.getWidget('Text8').set('content', 'Values have been loaded succesfully');
330
				});*/
306
				form.startup();
331
				form.startup();
307
				form.placeAt(win.body());
332
				form.placeAt(win.body());
308
			});
333
			});

Return to bug 26214