Form manager¶
The FormManager is the class
responsible for actually managing a form on the client side of an application. It provides an API
where, via paths, developers are able to, amongst other operations, read and write
values of the form, validate them, and overall manage or subscribe to their state.
Albeit implemented in Kotlin, because KForm currently only targets JavaScript/TypeScript for the
client, this documentation will focus on the API exposed by
tech.ostack:kform-js-bindings/@ostack.tech/kform,
since that’s the one developers will most likely interact with.
In most cases, when using KForm with React via
@ostack.tech/kform-react, an instance of
the form manager will be automatically constructed by the <Form>
component, becoming accessible via the useFormManager
hook. However, a new instance of a FormManager can still be manually constructed via:
Operations¶
The following are the main methods available on a form manager instance, when interacted with from JavaScript/TypeScript (for more details, consult the TypeScript definitions directly):
setValidationMode(mode): Sets the validation mode to one of"auto"(default) or"manual". Returns a promise which resolves upon completion.isValidPath(path): Returns abooleanindicating whether the provided path is valid according to the form manager’s schema.-
schemaInfo(path = "/**"): Returns anIterable<SchemaInfo<T>>containing schema-information about all schemas matching the provided path. -
valueInfo(path = "/**", callback): Returns a promise that resolves with the return value of the provided callback. The callback receives, as argument, anAsyncIterable<ValueInfo<T>>containing value-information about all values matching the provided path. info(path = "/**", callback): Returns a promise that resolves with the return value of the provided callback. The callback receives, as argument, anAsyncIterable<Info<T>>containing all information related to all values matching the provided path.schema(path = "/"): Returns the schema at the given path.has(path): Returns a promise which resolves with abooleanindicating whether there exists at least one value matching the provided path.-
get(path = "/", callback): Returns a promise which resolves with the return value of the provided callback. The callback receives, as argument, the value at the provided path.Mutable values shouldn’t be read outside the callback, so avoid returning them.
-
getClone(path = "/"): Returns a clone (deep copy) of the value at the provided path. set(path = "/", value): Sets the value at the provided path to the provided value. Returns a promise which resolves upon completion.reset(path = "/"): Resets the value at the provided path to its initial value. Returns a promise which resolves upon completion.remove(path): Removes all values matching the provided path from their parent collection. Returns a promise which resolves upon completion.getExternalContext(name, callback): Returns a promise that resolves with the return value of the provided callback. The callback receives, as argument, the external context with the provided name.setExternalContext(name, value): Sets the external context with the provided name to the provided value. Returns a promise which resolves with the previous value of the external context, if any.removeExternalContext(name): Removes the external context with the provided name. Returns a promise which resolves with the previous value of the external context, if any.validate(path = "/**", callback?):- If a callback is provided, returns a promise which resolves with its return value. The
callback receives, as argument, an
AsyncIterable<LocatedValidationIssue>containing all issues found in values matching the provided path. - If no callback is provided, returns a promise which resolves with
LocatedValidationIssue[]: an array containing all issues found in values matching the provided path.
- If a callback is provided, returns a promise which resolves with its return value. The
callback receives, as argument, an
isValid(path = "/**"): Returns a promise which resolves with abooleanindicating whether all values matching the provided path are valid.addExternalIssues(issues): Manually adds the provided located validation issues as “external issues”. Returns a promise which resolves upon completion.removeExternalIssues(path = "/**", code?): Removes all previously added external issues whose path matched the provided path. If a code is provided, only issues with the provided code are removed. Returns a promise which resolves upon completion.isDirty(path = "/"): Returns a promise which resolves with abooleanindicating whether at least one value matching the provided path is dirty.isPristine(path = "/"): Returns a promise which resolves with abooleanindicating whether all values matching the provided path are pristine (i.e. not dirty).setDirty(path = "/"): Sets all values matching the provided path as dirty, as well as their parents. Returns a promise which resolves upon completion.setPristine(path = "/"): Sets all values matching the provided path as pristine (i.e. as not dirty), as well as their descendents. Returns a promise which resolves upon completion.isTouched(path = "/"): Returns a promise which resolves with abooleanindicating whether at least one value matching the provided path has been touched.isUntouched(path = "/"): Returns a promise which resolves with abooleanindicating whether all values matching the provided path are untouched.setTouched(path = "/"): Sets all values matching the provided path as touched, as well as their parents. Returns a promise which resolves upon completion.setUntouched(path = "/"): Sets all values matching the provided path as untouched, as well as their descendents. Returns a promise which resolves upon completion.-
subscribe(path = "/**", eventHandler, onSubscription?): Subscribes to all events with paths matching the provided path by running theeventHandlerfunction for each event (see the following section for more information on events). Returns a promise which resolves with a function that should be called to unsubscribe.The subscription itself is asynchronous. An
onSubscriptionfunction may be provided, which is guaranteed to run after the subscription has completed but before any events are emitted to the handler.
Note
Methods such as get or info receive a callback function containing the value or information
at the provided path. This is done so that the form manager can guarantee that there are no
conflicting concurrent operations during the (possibly asynchronous) execution of the callback.
Accessing and mutating values should be done exclusively through the form manager’s API. Getting a mutable value and storing it externally for later use is not recommended.
Events¶
All operations that affect the state of the form may be observed via events using the previously
described subscribe method of the form manager. Form manager events are instances of
FormManagerEvent<T> and
have two common properties:
path: The path of the form value that was affected.schema: The schema associated with said form value.
Besides these properties, events may have additional properties depending on their subclass:
-
ValueEvent<T>: An event indicating a change in a form value itself. All value events have the following additional properties:oldValue: The previous form value at the affected path.value: The current value at the affected path.
Value events themselves are subdivided into the following subclasses:
ValueEvent.Init<T>: Value event indicating the initialisation of a form value.oldValueis alwaysnull.ValueEvent.Change<T>: Value event indicating that a certain form value has changed.ValueEvent.Destroy<T>: Value event indicating the destruction of a form value.valueis alwaysnull.ValueEvent.Add<T, TChildren>: Value event indicating the addition of an element to a collection of the form.oldValueis alwaysnulland the event contains two extra properties:addedValue: The value of the added element.id: The identifier of the added element within the collection.
ValueEvent.Remove<T, TChildren>: Value event indicating the removal of an element from a collection of the form.oldValueis alwaysnulland the event contains two extra properties:removedValue: The value of the removed element.id: The identifier of the removed element within the collection.
-
StateEvent<T>: An event indicating a change in the state of a form value. State events are subdivided into the following subclasses:StateEvent.ValidationChange<T>: State event indicating a change in the validation status of a value. Contains two additional properties:StateEvent.DisplayChange<T>: State event indicating a change in the display status of a value (how the value should be displayed in a UI). Contains an additional property:status: The new display status of the value, one of"valid","error", or"warning".
StateEvent.DirtyChange<T>: State event indicating a change in the “dirty” status of a value. Contains an additional property:status: Boolean indicating whether the value is “dirty”.
StateEvent.TouchedChange<T>: State event indicating a change in the “touched” status of a value. Contains an additional property:status: Boolean indicating whether value is “touched”.
Validation modes¶
The form manager supports two modes which determine when the form is validated:
"auto": In the default automatic mode, a background process is launched that runs validations as needed, as values are changed."manual": In manual mode, validations are only executed whenvalidateorisValidis called.
The validation mode can be set either at construction time, or dynamically via setValidationMode.