getLinkSelector(fmClass: string, field: string): string {
let fieldDef = this.classes[fmClass].field_map[field];
+ if (!fieldDef) {
+ console.warn(
+ `No such field "${field}" for IDL class "${fmClass}"`);
+ return null;
+ }
+
if (fieldDef.map) {
// For mapped fields, we want the selector field on the
// remotely linked object instead of the directly
}
if (fieldDef.class) {
- const classDef = this.classes[fieldDef.class];
+ return this.getClassSelector(fieldDef.class);
+ }
+ return null;
+ }
+
+ // Return the selector field for the class. If no selector is
+ // defined, use 'name' if it exists as a field on the class.
+ getClassSelector(idlClass: string): string {
+
+ if (idlClass) {
+ const classDef = this.classes[idlClass];
+
if (classDef.pkey) {
- return classDef.field_map[classDef.pkey].selector || null;
+ let selector = classDef.field_map[classDef.pkey].selector;
+ if (selector) { return selector; }
+
+ // No selector defined in the IDL, try 'name'.
+ if ('name' in classDef.field_map) { return 'name'; }
}
}
+
return null;
}
}
if (!this.idlField) {
- this.idlField = classDef.field_map[classDef.pkey].selector || 'name';
+ this.idlField = this.idl.getClassSelector(this.idlClass);
}
this.asyncDataSource = term => {
let searchTerm: string;
searchTerm = term;
- if (searchTerm === '_CLICK_' && this.asyncSupportsEmptyTermClick) {
- searchTerm = '';
+ if (searchTerm === '_CLICK_') {
+ if (this.asyncSupportsEmptyTermClick) {
+ searchTerm = '';
+ } else {
+ return of();
+ }
}
return new Observable(observer => {
});
}
- // Returns the name of the field on a class (typically via a linked
- // field) that acts as the selector value for display / search.
- getClassSelector(class_: string): string {
- if (class_) {
- const linkedClass = this.idl.classes[class_];
- return linkedClass.pkey ?
- linkedClass.field_map[linkedClass.pkey].selector : null;
- }
- return null;
- }
-
private flattenLinkedValues(field: any, list: IdlObject[]): ComboboxEntry[] {
const class_ = field.class;
const fieldOptions = this.fieldOptions[field.name] || {};
const idField = this.idl.classes[class_].pkey;
const selector = fieldOptions.linkedSearchField
- || this.getClassSelector(class_) || idField;
+ || this.idl.getClassSelector(class_) || idField;
return list.map(item => {
return {id: item[idField](), label: item[selector]()};
// field. Otherwise, avoid the network lookup and let the
// bare value (usually an ID) be displayed.
const selector = fieldOptions.linkedSearchField ||
- this.getClassSelector(field.class);
+ this.idl.getClassSelector(field.class);
if (selector && selector !== field.name) {
promise = this.pcrud.retrieve(field.class, idToFetch)
}
const selector = fieldOptions.linkedSearchField ||
- this.getClassSelector(field.class);
+ this.idl.getClassSelector(field.class);
if (!selector && !fieldOptions.preloadLinkedValues) {
// User probably expects an async data source, but we can't