Skip to content

Commit 5bbe0c5

Browse files
committed
ValueField: add support for async validators
Wait for pending fields on load 333353
1 parent 3c2286a commit 5bbe0c5

2 files changed

Lines changed: 38 additions & 23 deletions

File tree

‎eclipse-scout-core/src/form/Form.ts‎

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
*/
1010
import {
1111
AbortKeyStroke, App, aria, AriaLabelledByInsertPosition, arrays, BusyIndicatorOptions, Button, ButtonSystemType, ChildModelOf, DialogLayout, DisabledStyle, DisplayParent, DisplayViewId, EnumObject, ErrorHandler, Event, EventHandler,
12-
FileChooser, FileChooserController, FocusRule, FormController, FormEventMap, FormField, FormGrid, FormInvalidEvent, FormLayout, FormLifecycle, FormModel, FormRevealInvalidFieldEvent, GlassPaneRenderer, GroupBox, HtmlComponent,
13-
InitModelOf, KeyStroke, KeyStrokeContext, Lifecycle, MessageBox, MessageBoxController, MessageBoxes, ModelOf, NotificationBadgeStatus, ObjectOrChildModel, objects, Point, PopupWindow, PropertyChangeEvent, Rectangle, scout, Status,
14-
StatusOrModel, strings, TextListWithTitle, tooltips, TreeVisitResult, ValidationResult, webstorage, Widget, WrappedFormField
12+
FileChooser, FileChooserController, FocusRule, FormController, FormEventMap, FormGrid, FormInvalidEvent, FormLayout, FormLifecycle, FormModel, FormRevealInvalidFieldEvent, GlassPaneRenderer, GroupBox, HtmlComponent, InitModelOf,
13+
KeyStroke, KeyStrokeContext, Lifecycle, MessageBox, MessageBoxController, MessageBoxes, ModelOf, NotificationBadgeStatus, ObjectOrChildModel, objects, Point, PopupWindow, PropertyChangeEvent, Rectangle, scout, Status, StatusOrModel,
14+
strings, TextListWithTitle, tooltips, TreeVisitResult, ValidationResult, webstorage, Widget, WrappedFormField
1515
} from '../index';
1616
import $ from 'jquery';
1717

@@ -449,17 +449,23 @@ export class Form extends Widget implements FormModel, DisplayParent {
449449
try {
450450
this._setFormLoading(true);
451451
return this._load()
452-
.then(async data => {
452+
.then(data => {
453453
if (this.destroyed) {
454454
// If form has been closed right after it was opened ignore the load result
455455
return;
456456
}
457+
457458
this.setData(data);
458459
this.importData();
459-
await this._whenPendingFieldsReady();
460-
this._setFormLoading(false);
461-
this.formLoaded = true;
462-
this.trigger('load');
460+
461+
// Wait for async field validators to complete so the value is set when the form loading finishes
462+
let pendingFields = FormLifecycle.validateFormFields(this).pendingElements;
463+
if (pendingFields.length) {
464+
return $.promiseAll(pendingFields.map(field => field.promise))
465+
.then(() => this._loadingDone());
466+
}
467+
468+
this._loadingDone();
463469
})
464470
.always(() => this._setFormLoading(false));
465471
} catch (error) {
@@ -468,23 +474,14 @@ export class Form extends Widget implements FormModel, DisplayParent {
468474
}
469475
}
470476

471-
protected _setFormLoading(loading: boolean) {
472-
this._setProperty('formLoading', loading);
477+
protected _loadingDone() {
478+
this._setFormLoading(false);
479+
this.formLoaded = true;
480+
this.trigger('load');
473481
}
474482

475-
protected _whenPendingFieldsReady() {
476-
let promises = [];
477-
this.visitFields((field: FormField) => {
478-
let result = field.getValidationResult();
479-
if (result.promise) {
480-
promises.push(result.promise);
481-
}
482-
if (field.lifecycleBoundary) {
483-
return TreeVisitResult.SKIP_SUBTREE;
484-
}
485-
return result.visitResult;
486-
});
487-
return $.promiseAll(promises);
483+
protected _setFormLoading(loading: boolean) {
484+
this._setProperty('formLoading', loading);
488485
}
489486

490487
/**

‎eclipse-scout-core/test/form/FormSpec.ts‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,24 @@ describe('Form', () => {
246246
await form.load();
247247
expect(loadCounter).toBe(1);
248248
});
249+
250+
it('waits for async field validators to complete', async () => {
251+
let form = helper.createFormWithOneField();
252+
let field = form.rootGroupBox.fields[0] as StringField;
253+
254+
field.setValidators([value => sleep(50).then(() => value + ' async')], false);
255+
field.setValue('x');
256+
257+
let promise = form.load();
258+
expect(field.value).toBe(null);
259+
expect(field.validatePending).toBe(true);
260+
261+
await promise;
262+
expect(field.value).toBe('x async');
263+
expect(field.validatePending).toBe(false);
264+
265+
return promise;
266+
});
249267
});
250268

251269
describe('save', () => {

0 commit comments

Comments
 (0)