|
83 |
|
83 |
|
84 |
_readyDeferred: null, |
84 |
_readyDeferred: null, |
85 |
|
85 |
|
|
|
86 |
_allWidgetsBuiltDeferred: null, |
87 |
|
86 |
_startupDeferred: null, |
88 |
_startupDeferred: null, |
87 |
|
89 |
|
88 |
_blockChangeEvents: false, |
90 |
_blockChangeEvents: false, |
89 |
|
91 |
|
|
|
92 |
_hasSubtypeLabel: false, |
93 |
|
90 |
_createHandler: function(ifunc) { |
94 |
_createHandler: function(ifunc) { |
91 |
// This handler will be called by all subwidgets of the MultiInput widget. |
95 |
// This handler will be called by all subwidgets of the MultiInput widget. |
92 |
// When the first request comes in, we will execute the function to compute |
96 |
// When the first request comes in, we will execute the function to compute |
|
126 |
this._readyDeferred = new Deferred(); |
130 |
this._readyDeferred = new Deferred(); |
127 |
|
131 |
|
128 |
this._startupDeferred = new Deferred(); |
132 |
this._startupDeferred = new Deferred(); |
|
|
133 |
this._allWidgetsBuiltDeferred = new Deferred(); |
129 |
|
134 |
|
130 |
// check the property 'subtypes' |
135 |
// check the property 'subtypes' |
131 |
tools.assert(this.subtypes instanceof Array, |
136 |
tools.assert(this.subtypes instanceof Array, |
132 |
'umc/widgets/ContainerWidget: The property subtypes needs to be a string or an array of strings: ' + this.subtypes); |
137 |
'umc/widgets/ContainerWidget: The property subtypes needs to be a string or an array of strings: ' + this.subtypes); |
133 |
|
138 |
|
|
|
139 |
this._hasSubtypeLabel = array.some(this.subtypes, function(iwidget) { |
140 |
return iwidget.label; |
141 |
}); |
142 |
|
134 |
// initiate other properties |
143 |
// initiate other properties |
135 |
this._rowContainers = []; |
144 |
this._rowContainers = []; |
136 |
this._widgets = []; |
145 |
this._widgets = []; |
|
171 |
this.inherited(arguments); |
180 |
this.inherited(arguments); |
172 |
|
181 |
|
173 |
// add empty element |
182 |
// add empty element |
174 |
this._appendElements(1); |
183 |
this._appendRows(); |
175 |
}, |
184 |
}, |
176 |
|
185 |
|
177 |
_loadValues: function(depends) { |
186 |
_loadValues: function(depends) { |
|
179 |
this._lastDepends = depends; |
188 |
this._lastDepends = depends; |
180 |
array.forEach(this._widgets, function(iwidgets) { |
189 |
array.forEach(this._widgets, function(iwidgets) { |
181 |
array.forEach(iwidgets, function(jwidget) { |
190 |
array.forEach(iwidgets, function(jwidget) { |
182 |
if ('_loadValues' in jwidget) { |
191 |
if (jwidget && '_loadValues' in jwidget) { |
183 |
jwidget._loadValues(depends); |
192 |
jwidget._loadValues(depends); |
184 |
} |
193 |
} |
185 |
}); |
194 |
}); |
|
187 |
}, |
196 |
}, |
188 |
|
197 |
|
189 |
_setAllValues: function(_valList) { |
198 |
_setAllValues: function(_valList) { |
|
|
199 |
var _valList = lang.clone(_valList); |
190 |
this._blockChangeEvents = true; |
200 |
this._blockChangeEvents = true; |
191 |
var valList = _valList; |
201 |
var valList = _valList; |
192 |
if (!(valList instanceof Array)) { |
202 |
if (!(valList instanceof Array)) { |
|
196 |
// adjust the number of rows |
206 |
// adjust the number of rows |
197 |
var diff = valList.length - this._nRenderedElements; |
207 |
var diff = valList.length - this._nRenderedElements; |
198 |
if (diff > 0) { |
208 |
if (diff > 0) { |
199 |
this._appendElements(diff); |
209 |
this._appendRows(diff); |
200 |
} |
210 |
} |
201 |
else if (diff < 0) { |
211 |
else if (diff < 0) { |
202 |
this._popElements(-diff); |
212 |
this._popElements(-diff); |
203 |
} |
213 |
} |
204 |
|
214 |
|
205 |
// set all values |
215 |
this._allWidgetsBuiltDeferred.then(lang.hitch(this, function() { |
206 |
array.forEach(valList, function(ival, irow) { |
216 |
// set all values |
207 |
if (irow >= this._widgets.length) { |
217 |
array.forEach(valList, function(ival, irow) { |
208 |
// break |
218 |
if (irow >= this._widgets.length) { |
209 |
return false; |
219 |
return; |
210 |
} |
220 |
} |
211 |
|
221 |
|
212 |
var rowVals = []; |
222 |
var rowVals = []; |
213 |
if (typeof ival == "string") { |
223 |
if (typeof ival == "string") { |
214 |
// entry is string .. we need to parse it if we have a delimiter |
224 |
// entry is string .. we need to parse it if we have a delimiter |
215 |
if (this.delimiter) { |
225 |
if (this.delimiter) { |
216 |
rowVals = ival.split(this.delimiter); |
226 |
rowVals = ival.split(this.delimiter); |
|
|
227 |
} |
228 |
else { |
229 |
rowVals = [ ival ]; |
230 |
} |
217 |
} |
231 |
} |
218 |
else { |
232 |
else if (ival instanceof Array) { |
219 |
rowVals = [ ival ]; |
233 |
rowVals = ival; |
220 |
} |
234 |
} |
221 |
} |
|
|
222 |
else if (ival instanceof Array) { |
223 |
rowVals = ival; |
224 |
} |
225 |
|
235 |
|
226 |
// set values |
236 |
// set values |
227 |
for (var j = 0; j < this.subtypes.length; ++j) { |
237 |
for (var j = 0; j < this.subtypes.length; ++j) { |
228 |
var val = j >= rowVals.length ? '' : rowVals[j]; |
238 |
var val = j >= rowVals.length ? '' : rowVals[j]; |
229 |
this._widgets[irow][j].set('value', val); |
239 |
this._widgets[irow][j].set('value', val); |
230 |
|
240 |
|
231 |
// for dynamic combo boxes, we need to save the value as "initial value" |
241 |
// for dynamic combo boxes, we need to save the value as "initial value" |
232 |
if (this._widgets[irow][j].setInitialValue) { |
242 |
if (this._widgets[irow][j].setInitialValue) { |
233 |
this._widgets[irow][j].setInitialValue(val, false); |
243 |
this._widgets[irow][j].setInitialValue(val, false); |
|
|
244 |
} |
234 |
} |
245 |
} |
235 |
} |
246 |
}, this); |
236 |
}, this); |
247 |
this._blockChangeEvents = false; |
237 |
this._blockChangeEvents = false; |
248 |
})); |
238 |
}, |
249 |
}, |
239 |
|
250 |
|
240 |
_setValueAttr: function(_vals) { |
251 |
_setValueAttr: function(_vals) { |
|
252 |
}, |
263 |
}, |
253 |
|
264 |
|
254 |
_setDisabledAttr: function ( value ) { |
265 |
_setDisabledAttr: function ( value ) { |
255 |
var i; |
266 |
this._allWidgetsBuiltDeferred.then(lang.hitch(this, function() { |
256 |
for ( i = 0; i < this._rowContainers.length; ++i) { |
267 |
var i; |
257 |
array.forEach( this._rowContainers[ i ].getChildren(), function( widget ) { |
268 |
for ( i = 0; i < this._rowContainers.length; ++i) { |
258 |
widget.set( 'disabled', value ); |
269 |
var irow = this._rowContainers[i]; |
259 |
} ); |
270 |
array.forEach( irow ? irow.getChildren() : [], function( widget ) { |
260 |
} |
271 |
widget.set('disabled', value); |
261 |
this.disabled = value; |
272 |
} ); |
|
|
273 |
} |
274 |
})); |
275 |
this._set('disabled', value); |
262 |
}, |
276 |
}, |
263 |
|
277 |
|
264 |
_getAllValues: function() { |
278 |
_getAllValues: function() { |
265 |
var i, j, val, isSet, vals = [], rowVals = []; |
279 |
var i, j, jwidget, val, isSet, vals = [], rowVals = []; |
266 |
for (i = 0; i < this._widgets.length; ++i) { |
280 |
for (i = 0; i < this._widgets.length; ++i) { |
267 |
rowVals = []; |
281 |
rowVals = []; |
268 |
isSet = false; |
282 |
isSet = false; |
269 |
for (j = 0; j < this._widgets[i].length; ++j) { |
283 |
for (j = 0; j < this._widgets[i].length; ++j) { |
270 |
val = this._widgets[i][j].get('value'); |
284 |
jwidget = this._widgets[i][j]; |
|
|
285 |
if (!jwidget) { |
286 |
continue; |
287 |
} |
288 |
val = jwidget.get('value'); |
271 |
isSet = isSet || ('' !== val); |
289 |
isSet = isSet || ('' !== val); |
272 |
if (!tools.inheritsFrom(this._widgets[i][j], 'umc.widgets.Button')) { |
290 |
if (!tools.inheritsFrom(this._widgets[i][j], 'umc.widgets.Button')) { |
273 |
rowVals.push(val); |
291 |
rowVals.push(val); |
|
315 |
return; |
333 |
return; |
316 |
} |
334 |
} |
317 |
|
335 |
|
318 |
// verify whether label information for subtypes are given |
|
|
319 |
var hasSubTypeLabels = false; |
320 |
array.forEach(this.subtypes, function(iwidget) { |
321 |
hasSubTypeLabels = hasSubTypeLabels || iwidget.label; |
322 |
}); |
323 |
|
324 |
// create 'new' button |
336 |
// create 'new' button |
325 |
var btn = this.own(new Button({ |
337 |
var btn = this.own(new Button({ |
326 |
disabled: this.disabled, |
338 |
disabled: this.disabled, |
327 |
iconClass: 'umcIconAdd', |
339 |
iconClass: 'umcIconAdd', |
328 |
onClick: lang.hitch(this, '_appendElements', 1), |
340 |
onClick: lang.hitch(this, '_appendRows'), |
329 |
'class': 'umcMultiInputAddButton' |
341 |
'class': 'umcMultiInputAddButton' |
330 |
}))[0]; |
342 |
}))[0]; |
331 |
|
343 |
|
332 |
// wrap a button with a LabelPane |
344 |
// wrap a button with a LabelPane |
333 |
this._newButton = this.own(new LabelPane({ |
345 |
this._newButton = this.own(new LabelPane({ |
334 |
content: btn, |
346 |
content: btn, |
335 |
label: this._nRenderedElements === 1 && hasSubTypeLabels ? ' ' : '' // only keep the label for the first row |
347 |
label: this._nRenderedElements === 1 && this._hasSubtypeLabel ? ' ' : '' // only keep the label for the first row |
336 |
}))[0]; |
348 |
}))[0]; |
337 |
|
349 |
|
338 |
// add button to last row |
350 |
// add button to last row |
339 |
this._rowContainers[this._rowContainers.length - 1].addChild(this._newButton); |
351 |
this._rowContainers[this._rowContainers.length - 1].addChild(this._newButton); |
340 |
}, |
352 |
}, |
341 |
|
353 |
|
342 |
_appendElements: function(n) { |
354 |
_updateReadyDeferred: function() { |
343 |
if (n < 1) { |
355 |
// check all current elements whether they are ready |
344 |
return; |
356 |
var nReady = 0; |
|
|
357 |
var nElements = 0; |
358 |
var nBuiltElements = 0; |
359 |
var i, j; |
360 |
for (i = 0; i < this._widgets.length; ++i) { |
361 |
for (j = 0; j < this._widgets[i].length; ++j, ++nElements) { |
362 |
//console.log(lang.replace('### MultiInput: widget[{0}][{1}]: waiting -> ', [i, j]), this._widgets[i][j].ready()); |
363 |
var jwidget = this._widgets[i][j]; |
364 |
nBuiltElements += jwidget ? 1 : 0; |
365 |
var jreadyDeferred = jwidget && jwidget.ready ? jwidget.ready() : null; |
366 |
if (!jreadyDeferred) { |
367 |
++nReady; |
368 |
} |
369 |
else if (jreadyDeferred.isFulfilled()) { |
370 |
++nReady; |
371 |
} |
372 |
} |
345 |
} |
373 |
} |
346 |
|
374 |
|
347 |
// initiate a new Deferred object in case there is none already pending |
375 |
if (nReady < nElements) { |
348 |
if (this._readyDeferred.isFulfilled()) { |
376 |
if (this._readyDeferred.isFulfilled()) { |
349 |
this._readyDeferred = new Deferred(); |
377 |
// initiate a new Deferred object if none is pending |
|
|
378 |
this._readyDeferred = new Deferred(); |
379 |
} |
380 |
|
381 |
// update progress |
382 |
this._readyDeferred.progress({ |
383 |
max: nElements, |
384 |
current: nReady, |
385 |
percentage: 100 * nReady / nElements |
386 |
}); |
350 |
} |
387 |
} |
351 |
|
388 |
|
352 |
// remove the 'new' button |
389 |
if (nReady == nElements && !this._readyDeferred.isFulfilled()) { |
353 |
this._removeNewButton(); |
390 |
// all elements are ready |
|
|
391 |
this._readyDeferred.resolve(); |
392 |
this.onValuesLoaded(); |
393 |
} |
354 |
|
394 |
|
355 |
var nFinal = this._nRenderedElements + n; |
395 |
if (nBuiltElements < nElements && this._allWidgetsBuiltDeferred.isFulfilled()) { |
356 |
for (var irow = this._nRenderedElements; irow < nFinal && irow < this.max; ++irow, ++this._nRenderedElements) { |
396 |
// initiate a new Deferred object |
357 |
// add all other elements with '__' such that they will be ignored by umc/widgets/Form |
397 |
this._allWidgetsBuiltDeferred = new Deferred(); |
358 |
var order = [], widgetConfs = []; |
398 |
} |
359 |
array.forEach(this.subtypes, function(iwidget, i) { |
|
|
360 |
// add the widget configuration dict to the list of widgets |
361 |
var iname = '__' + this.name + '-' + irow + '-' + i; |
362 |
var iconf = lang.mixin({}, iwidget, { |
363 |
disabled: this.disabled, |
364 |
threshold: this.threshold, // for UDM-threshold |
365 |
name: iname, |
366 |
value: '', |
367 |
dynamicValues: lang.partial(iwidget.dynamicValues, iname) |
368 |
}); |
369 |
if (iwidget.dynamicValuesInfo) { |
370 |
iconf.dynamicValuesInfo = lang.partial(iwidget.dynamicValuesInfo, iname); |
371 |
} |
372 |
widgetConfs.push(iconf); |
373 |
|
399 |
|
374 |
// add the name of the widget to the list of widget names |
400 |
if (nBuiltElements == nElements && !this._allWidgetsBuiltDeferred.isFulfilled()) { |
375 |
order.push(iname); |
401 |
// all elements have been built |
376 |
}, this); |
402 |
this._allWidgetsBuiltDeferred.resolve(); |
|
|
403 |
} |
404 |
}, |
377 |
|
405 |
|
|
|
406 |
__appendRow: function(irow) { |
407 |
var order = [], widgetConfs = []; |
408 |
array.forEach(this.subtypes, function(iwidget, i) { |
409 |
// add the widget configuration dict to the list of widgets |
410 |
var iname = '__' + this.name + '-' + irow + '-' + i; |
411 |
var iconf = lang.mixin({}, iwidget, { |
412 |
disabled: this.disabled, |
413 |
threshold: this.threshold, // for UDM-threshold |
414 |
name: iname, |
415 |
value: '', |
416 |
dynamicValues: lang.partial(iwidget.dynamicValues, iname) |
417 |
}); |
418 |
if (iwidget.dynamicValuesInfo) { |
419 |
iconf.dynamicValuesInfo = lang.partial(iwidget.dynamicValuesInfo, iname); |
420 |
} |
421 |
widgetConfs.push(iconf); |
378 |
|
422 |
|
379 |
// render the widgets |
423 |
// add the name of the widget to the list of widget names |
380 |
var widgets = render.widgets(widgetConfs, this); |
424 |
order.push(iname); |
|
|
425 |
}, this); |
381 |
|
426 |
|
382 |
// if we have a button, we need to pass the value and index if the |
|
|
383 |
// current element |
384 |
tools.forIn(widgets, function(ikey, iwidget) { |
385 |
var myrow = irow; |
386 |
if (tools.inheritsFrom(iwidget, 'umc.widgets.Button') && typeof iwidget.callback == "function") { |
387 |
var callbackOrg = iwidget.callback; |
388 |
iwidget.callback = lang.hitch(this, function() { |
389 |
callbackOrg(this.get('value')[myrow], myrow); |
390 |
}); |
391 |
} |
392 |
}, this); |
393 |
|
427 |
|
394 |
// find out whether all items do have a label |
428 |
// render the widgets |
395 |
var hasSubTypeLabels = array.filter(this.subtypes, function(iwidget) { |
429 |
var widgets = render.widgets(widgetConfs, this); |
396 |
return iwidget.label; |
|
|
397 |
}).length > 0; |
398 |
|
430 |
|
399 |
// layout widgets |
431 |
// if we have a button, we need to pass the value and index of the |
400 |
var visibleWidgets = array.map(order, function(iname) { |
432 |
// current element |
401 |
return widgets[iname]; |
433 |
tools.forIn(widgets, function(ikey, iwidget) { |
402 |
}); |
434 |
var myrow = irow; |
403 |
var rowContainer = this.own(new ContainerWidget({}))[0]; |
435 |
if (tools.inheritsFrom(iwidget, 'umc.widgets.Button') && typeof iwidget.callback == "function") { |
404 |
array.forEach(order, function(iname) { |
436 |
var callbackOrg = iwidget.callback; |
405 |
// add widget to row container (wrapped by a LabelPane) |
437 |
iwidget.callback = lang.hitch(this, function() { |
406 |
// only keep the label for the first row |
438 |
callbackOrg(this.get('value')[myrow], myrow); |
407 |
var iwidget = widgets[iname]; |
439 |
}); |
408 |
var label = irow !== 0 ? '' : iwidget.label; |
440 |
} |
409 |
if (tools.inheritsFrom(iwidget, 'umc.widgets.Button')) { |
441 |
}, this); |
410 |
label = irow !== 0 ? '' : ' '; |
|
|
411 |
} |
412 |
rowContainer.addChild(new LabelPane({ |
413 |
disabled: this.disabled, |
414 |
content: iwidget, |
415 |
label: label |
416 |
})); |
417 |
|
442 |
|
418 |
// register to value changes |
443 |
// layout widgets |
419 |
this.own(iwidget.watch('value', lang.hitch(this, function() { |
444 |
var visibleWidgets = array.map(order, function(iname) { |
420 |
if (!this._blockChangeEvents) { |
445 |
return widgets[iname]; |
421 |
this._set('value', this.get('value')); |
446 |
}); |
422 |
} |
447 |
var rowContainer = this.own(new ContainerWidget({}))[0]; |
423 |
}))); |
448 |
array.forEach(order, function(iname) { |
424 |
}, this); |
449 |
// add widget to row container (wrapped by a LabelPane) |
425 |
|
450 |
// only keep the label for the first row |
426 |
// add a 'remove' button at the end of the row |
451 |
var iwidget = widgets[iname]; |
427 |
var button = this.own(new Button({ |
452 |
var label = irow !== 0 ? '' : iwidget.label; |
|
|
453 |
if (tools.inheritsFrom(iwidget, 'umc.widgets.Button')) { |
454 |
label = irow !== 0 ? '' : ' '; |
455 |
} |
456 |
rowContainer.addChild(new LabelPane({ |
428 |
disabled: this.disabled, |
457 |
disabled: this.disabled, |
429 |
iconClass: 'umcIconDelete', |
458 |
content: iwidget, |
430 |
onClick: lang.hitch(this, '_removeElement', irow), |
459 |
label: label |
431 |
'class': 'umcMultiInputRemoveButton' |
|
|
432 |
}))[0]; |
433 |
rowContainer.addChild(new LabelPane({ |
434 |
content: button, |
435 |
label: irow === 0 && hasSubTypeLabels ? ' ' : '' // only keep the label for the first row |
436 |
})); |
460 |
})); |
437 |
|
461 |
|
438 |
// add row |
462 |
// register to value changes |
439 |
this._widgets.push(visibleWidgets); |
463 |
this.own(iwidget.watch('value', lang.hitch(this, function() { |
440 |
this._rowContainers.push(rowContainer); |
464 |
if (!this._blockChangeEvents) { |
441 |
this._startupDeferred.then(lang.hitch(rowContainer, 'startup')); |
465 |
this._set('value', this.get('value')); |
442 |
this.addChild(rowContainer); |
466 |
} |
|
|
467 |
}))); |
468 |
}, this); |
443 |
|
469 |
|
444 |
// call the _loadValues method by hand |
470 |
// add a 'remove' button at the end of the row |
445 |
array.forEach(order, function(iname) { |
471 |
var button = this.own(new Button({ |
446 |
var iwidget = widgets[iname]; |
472 |
disabled: this.disabled, |
447 |
if ('_loadValues' in iwidget) { |
473 |
iconClass: 'umcIconDelete', |
448 |
iwidget._loadValues(this._lastDepends); |
474 |
onClick: lang.hitch(this, '_removeElement', irow), |
449 |
} |
475 |
'class': 'umcMultiInputRemoveButton' |
450 |
}, this); |
476 |
}))[0]; |
451 |
//this._readyDeferred.progress(_('%(i)s / %(len)s values built', {i: irow, len: nFinal})); |
477 |
rowContainer.addChild(new LabelPane({ |
|
|
478 |
content: button, |
479 |
label: irow === 0 && this._hasSubtypeLabel ? ' ' : '' // only keep the label for the first row |
480 |
})); |
481 |
|
482 |
// add row |
483 |
this._widgets[irow] = visibleWidgets; |
484 |
this._rowContainers[irow] = rowContainer; |
485 |
this._startupDeferred.then(lang.hitch(rowContainer, 'startup')); |
486 |
this.addChild(rowContainer); |
487 |
|
488 |
// call the _loadValues method by hand |
489 |
array.forEach(order, function(iname) { |
490 |
var iwidget = widgets[iname]; |
491 |
if ('_loadValues' in iwidget) { |
492 |
iwidget._loadValues(this._lastDepends); |
493 |
} |
494 |
}, this); |
495 |
|
496 |
// update the ready deferred know and when the widget itself is ready |
497 |
this._updateReadyDeferred(); |
498 |
var allReady = []; |
499 |
tools.forIn(widgets, function(ikey, iwidget) { |
500 |
allReady.push(iwidget.ready ? iwidget.ready() : null); |
501 |
}); |
502 |
all(allReady).then(lang.hitch(this, '_updateReadyDeferred')); |
503 |
}, |
504 |
|
505 |
_appendRows: function(n) { |
506 |
n = n || 1; |
507 |
if (n < 1) { |
508 |
return; |
452 |
} |
509 |
} |
453 |
|
510 |
|
454 |
// wait for all widgets to be ready |
511 |
// remove the 'new' button |
455 |
var allReady = []; |
512 |
this._removeNewButton(); |
456 |
var i, j; |
513 |
|
457 |
for (i = 0; i < this._widgets.length; ++i) { |
514 |
var nFinal = this._nRenderedElements + n; |
458 |
for (j = 0; j < this._widgets[i].length; ++j) { |
515 |
var newRows = []; |
459 |
//console.log(lang.replace('### MultiInput: widget[{0}][{1}]: waiting -> ', [i, j]), this._widgets[i][j].ready()); |
516 |
for (var irow = this._nRenderedElements; irow < nFinal && irow < this.max; ++irow, ++this._nRenderedElements) { |
460 |
allReady.push(this._widgets[i][j].ready ? this._widgets[i][j].ready() : null); |
517 |
newRows.push(irow); |
|
|
518 |
|
519 |
// allocate indeces in 2D array _widget this allows _updateReadyDeferred() |
520 |
// to know how many entries there will be at the end |
521 |
this._rowContainers[irow] = null; |
522 |
this._widgets[irow] = []; |
523 |
for (var jsubWidget = 0; jsubWidget < this.subtypes.length; ++jsubWidget) { |
524 |
this._widgets[irow][jsubWidget] = null; |
461 |
} |
525 |
} |
462 |
} |
526 |
} |
463 |
all(allReady).then(lang.hitch(this, function() { |
527 |
|
464 |
//console.log('### MultiInput: all resolved'); |
528 |
// force the ready deferred to be updated |
465 |
this._readyDeferred.resolve(); |
529 |
this._updateReadyDeferred(); |
466 |
this.onValuesLoaded(); |
530 |
|
|
|
531 |
// perform adding rows asynchronously |
532 |
tools.forEachAsync(newRows, lang.hitch(this, '__appendRow')).then(lang.hitch(this, function() { |
533 |
// all elements have been added to the DOM |
534 |
// add the new button |
535 |
if (this._nRenderedElements < this.max) { |
536 |
this._addNewButton(); |
537 |
} |
538 |
this._updateReadyDeferred(); |
467 |
})); |
539 |
})); |
468 |
|
|
|
469 |
// add the new button |
470 |
if (this._nRenderedElements < this.max) { |
471 |
this._addNewButton(); |
472 |
} |
473 |
}, |
540 |
}, |
474 |
|
541 |
|
475 |
_popElements: function(n) { |
542 |
_popElements: function(n) { |
|
492 |
// update the number of render elements |
559 |
// update the number of render elements |
493 |
this._nRenderedElements -= n; |
560 |
this._nRenderedElements -= n; |
494 |
|
561 |
|
|
|
562 |
|
495 |
// add the new button |
563 |
// add the new button |
496 |
this._addNewButton(); |
564 |
this._addNewButton(); |
497 |
}, |
565 |
}, |