Der Custom Field Manager ist eine JavaScript-API innerhalb von LearningSuite, mit der Custom Fields ausgelesen, aktualisiert und beobachtet werden können. Diese Anleitung richtet sich ausschließlich an IT-affine Anwender (bspw. Web-Entwickler)!
Er eignet sich insbesondere für individuelle Integrationen, die AI-Agents und dynamische Erweiterungen innerhalb von Elementen wie Hubs oder Lektionsinhalten.
Verfügbarkeit
Der Custom Field Manager ist global verfügbar über:
window.customFields
oder verkürzt:
customFields
Typische Anwendungsfälle
Auslesen von System- oder Profilinformationen (z. B. Benutzername, Kontaktdaten)
Schreiben von Werten in Custom Fields (serverseitig gespeichert)
Reaktive UI-Logik bei Feldänderungen
Arbeiten mit mehreren Profilen pro Card (z. B. Standorte, Rollen, Geräte)
Initialisierung
Da Custom Fields asynchron geladen werden, muss vor der Nutzung auf die Initialisierung gewartet werden:
await customFields.waitForInitialization();
Dies wird empfohlen für alle Skripte, die beim Page Load oder früh im Lifecycle ausgeführt werden.
Feldwerte lesen
Einzelnes Feld lesen
await customFields.waitForInitialization(); const firstName = customFields.getFieldValue('system.user.firstName');Mit Typisierung:
const firstName = customFields.getFieldValue<string>('system.user.firstName');Alle Feldwerte lesen
const allValues = customFields.getFieldValues();
Ideal für Debugging oder explorative Entwicklung.
Feldwerte setzen
Feldwerte können serverseitig aktualisiert werden:
await customFields.setFieldValue( 'profile.contact.phone', '+43 660 1234567' );
Wichtige Hinweise:
Updates erfolgen asynchron
Es wird ein Patch-Update durchgeführt (keine Überschreibung anderer Felder)
Serverseitig ist ein Throttle aktiv, um zu viele Requests zu vermeiden
Reaktive Nutzung (Observer)
Einzelnes Feld beobachten
const unsubscribe = customFields.observeField( 'system.user.firstName', (value) => { console.log('Neuer Wert:', value); } ); // Wichtig: später aufräumen unsubscribe();Geeignet für UI-Bindings oder Validierungslogik.
Alle Felder beobachten
const unsubscribe = customFields.observeFields((values) => { console.log('Mindestens ein Feld hat sich geändert', values); }); unsubscribe();Arbeiten mit Profilen
Eine Card kann mehrere Profile enthalten (z. B. Standorte, Benutzerrollen).
Profil wechseln
customFields.switchProfile('card-123', 1);Profil hinzufügen
const profileIndex = customFields.addProfile( 'card-123', 'Filiale Wien' );
Profil löschen
customFields.deleteProfile('card-123', 2);Profil-spezifische Feldzugriffe (optional)
Diese Methoden sind für Sonderfälle gedacht und sollten nur genutzt werden, wenn der Profilindex explizit relevant ist.
Lesen
const email = customFields.getFieldValueForProfile( 'profile.contact.email', 0 );
Schreiben
await customFields.setFieldValueForProfile( 'profile.contact.email', '[email protected]', 0 );
Best Practices
waitForInitialization()immer nutzen, wenn dein Code früh ausgeführt wirdObserver (
observeField,observeFields) immer unsubscribensetFieldValuenicht in ungedrosselten Events (z. B.keyup) verwendenProfil-spezifische Methoden nur einsetzen, wenn wirklich nötig
Für Standard-Use-Cases bevorzugt die LearningSuite Widgets verwenden
Beispiel: Sicherer Zugriff mit Fallback
await customFields.waitForInitialization(); const firstName = customFields.getFieldValue('system.user.firstName') ?? 'Gast'; document.querySelector('#welcome').textContent = `Hallo, ${firstName}!`;API-Übersicht (Kurzfassung)
waitForInitialization()getFieldValue(key)setFieldValue(key, value)getFieldValues()observeField(key, callback)observeFields(callback)switchProfile(cardId, profileIndex)addProfile(cardId, name)deleteProfile(cardId, profileIndex)
Langversion
// the custom Field manager is accessible via the following code:
//window.customFields: CustomFieldManagerType
/**
* @type {CustomFieldManagerType}
*/
window.customFields
//OR directly
/**
* @type {CustomFieldManagerType}
*/
customFields
// Usage:
customFields.getFieldValue('system.user.firstName')
//Custom Field Manager Type:
interface CustomFieldManagerType {
/**
* Waits for the CustomFieldManager to be initialized.
* This is useful to ensure that the data is loaded before accessing field values.
* @returns A promise that resolves when the CustomFieldManager is initialized.
*/
waitForInitialization(): Promise<void>;
/** Returns all field values for the current profile selection. */
getFieldValues(): Record<string, any>;
/**
* Gets the value of a field for the current profile selection.
* @param key The key of the field.
*/
getFieldValue<T>(key: string): T | undefined;
/**
* Sets the value of a field for the current profile selection.
* This operation will perform an asynchronous update to the server.
* It will execute a patch update to avoid overwriting other fields.
*
* We have set a throttle on the server updates to avoid too many requests in a short time.
* @param key The key of the field.
* @param value The value to set.
*/
setFieldValue<T>(key: string, value: T): Promise<void>;
/**
* Gets the value of a field for a specific profile index.
* This method is optional and should only be used when necessary.
* It's not recommended to use this method in most cases.
* @param key
* @param profileIndex
*/
getFieldValueForProfile<T>(key: string, profileIndex: number): T | undefined;
/**
* Sets the value of a field for a specific profile index.
* This method is optional and should only be used when necessary.
* It's not recommended to use this method in most cases.
* @param key
* @param value
* @param profileIndex
*/
setFieldValueForProfile<T>(key: string, value: T, profileIndex: number): Promise<void>;
/**
* Observes all field values. The callback is called whenever any field value changes.
* Please ensure to call the returned unsubscribe function when no longer needed to avoid memory leaks.
* @param callback
*/
observeFields(callback: Callback<Record<string, any>>): UnsubFn;
/**
* Observes a specific field value. The callback is called whenever the field value changes.
* Please ensure to call the returned unsubscribe function when no longer needed to avoid memory leaks.
* @param key
* @param callback
*/
observeField<T>(key: string, callback: (value: T | undefined) => void): () => void;
/**
* Switches the current profile for a given card.
* This is usefull if you want to integrate profile switching in your own UI.
* Otherwise just use the provided Widgets from LearningSuite directly.
* @param cardId
* @param profileIndex
*/
switchProfile(cardId: string, profileIndex: number): void;
/**
* Adds a new profile for a given card.
* This is usefull if you want to integrate profile creation in your own UI.
* Otherwise just use the provided Widgets from LearningSuite directly.
* @param cardId
* @param name
*/
addProfile(cardId: string, name: string): number;
/**
* Deletes a profile for a given card.
* This is usefull if you want to integrate profile deletion in your own UI.
* Otherwise just use the provided Widgets from LearningSuite directly.
* @param cardId
* @param profileIndex
*/
deleteProfile(cardId: string, profileIndex: number): void;
}
