HTML Input Aspects
Framework-agnostic library controlling various aspects of user input. Such as value conversion, form validation, etc.
;;// Create controls for input elements.convertintoTrimmed // Remove whitespace.setupInValidation,.setupInCssClasses, classes.addinCssInfo; // Add validation status CSS classes.setupInValidation,.setupInCssClasses, classes.addinCssInfo; // Add validation status CSS classes;// Create control group;
First, an input control should be created for input element.
Input controls implementations extend
InControl class that, in turn, extends
Each control has a value. It can be accessed or updated by
InControl.it property. Input control sends an event when
the value change.
There are several input control implementations available. They can be used for different input elements.
Textual input control is created by
The value of this control is a
Multi-select input control is created by
The value of this control is an array of
Checkbox input control is created by
The value of this control is three-state, corresponding to checked, unchecked, and intermediate values.
By default these are
undefined. But can be configured to be arbitrary values by specifying
Radio button control is created by
By default the value of this control is
true when the radio button is checked. This can be configured though.
The value of this control when the radio button is unchecked is always
It is convenient to group the radio buttons into a radio group, that can be created using
The value of radio group control is a string key corresponding to checked radio button. Or
undefined when none
Arbitrary Value Control
Is created by
This control is not associated with any input element. Its value is expected to be set programmatically.
An input container is an input control containing other controls.
The value of such container is formed by the ones of nested controls. An update to container value updates the ones of nested controls.
All containers extend
InContainer class. A
controls property of container grants access to nested controls.
The are two input containers implemented.
A group of input controls is created by
Nested controls are identified by keys and can be added and removed via
Group value (called model) is an object formed by nested control values. The model property value is the one of the control with the same key, if present. When model is updated corresponding controls are also updated.
A group model type is passed as a generic type parameter to
An indexed list of input controls is created by
Nested controls can be added and removed via
List value (called model) is an array object formed by nested control values. The item property value is the one of the control with the same index, if present. When model is updated corresponding controls are also updated.
A model item type type is passed as a generic type parameter to
An input control can be converted. E.g. to the one with another value type.
This can be done by
InControl.convert() method that accepts a converter as parameter and returns converted input
When original control is updated, the converted one is automatically updated with converted value. When converted control is updated, the original one is automatically updated with the value restored from converted one.
There are several converters implemented:
intoFallback()converts an input control to the one replacing
undefinedvalue with fallback one.
intoInteger()converts string values to integer ones.
intoTrimmed()trims input value.
intoParsedBy()parses and formats input text with the given functions.
Simple conversions can be implemented like this:
control.converttext.length, // Convert a `text` to its length'*'.repeatstars, // Restore the text as several `stars`;
Once control created, input aspects can be attached to it with
InControl.aspect() method accepting an aspect key
and returning the attached aspect. An aspect is attached only once and returned on subsequent
An input aspect is an arbitrary value. There are several input aspects implemented for various control use cases:
InElementHTML input element control available as an aspect of itself and, possibly, of converted controls. Or
nullif not available.
InContainerInput controls container available as an aspect of itself and, possibly, of converted controls. Or
nullif not available.
InParentsParents of input control.
Reflects all containers the control belongs to. Note that component may belong to multiple containers. Or even to the same container multiple times.
InFocusInput focus aspect.
This is a value tracker of element focus flag. Or
InElementaspect is absent.
InStatusAggregate status aspect of user input.
Collects and reports input status flags. Like whether the input ever had focus or being altered.
Supports input elements and containers. For the rest of input controls always sends default status flags.
InModeInput mode aspect of control. Control can be either enabled, disabled, or readonly.
Each control maintains its own state, while nested controls respect container ones. I.e. when container is disabled all nested ones are also disabled. When container is readonly, all nested ones are also readonly, unless explicitly disabled.
When applied to input element this aspect maintains its
readonlyattributes (not properties!).
InDataA data aspect of the input.
Represents input control data that will be submitted.
Input data is typically the same as control value with respect to input mode. I.e. when input mode is
offthe data is
InStyledElementAn input aspect representing HTML element to apply styles to.
This is a HTML element for input element control, and
nullfor everything else by default.
InStyledElement.to()converter can be used to convert arbitrary control to the one with the given styled element. This is useful for controls without elements (such as input groups), or can be used to apply CSS classes to input element wrappers (such as
InCssClassesAn aspect of the user input representing CSS classes to apply to styled element.
inCssInfo()creates a source of informative CSS classes.
inCssError()creates a source marker CSS classes applied when particular validation error occur.
InNamespaceAliaserNamespace aliaser aspect.
Used by other aspect to generate unique names.
InNamespaceAliaser.to()converter can be used to convert arbitrary control to the one with the given aliaser.
InRenderSchedulerInput elements render scheduler.
It is used e.g. to schedule CSS updates. The control values and attributes are updated instantly.
InRenderScheduler.to()converter can be used to convert arbitrary control to the one with the given scheduler.
InValidationValidation aspect of the input.
Reports validation messages sent by registered validators.
Input validation is performed by validators added to
A validation aspect of converted control reports all messages from original control in addition to its own.
A validation aspect of input controls container reports all messages from nested controls in addition to its own.
Validator can be added to input validation aspect using
InValidation.by() method. After that all validation
messages it sends are reported by validation aspect. Multiple messages could be sent at a time. These messages
replace the previously sent ones. To report the absence of error just send an empty event without messages.
This can be one either a validation messages event keeper, a function returning one and accepting input control as its only parameter, or simple validator instance.
Validators report validation errors as messages. Each validation message is a map of key/value pairs, where the key is a message code, while the value is arbitrary.
Validation result is reported as
InValidation.Result instance, that has methods to request all reported messages,
or just messages with the given message code.
There are several validators implemented:
requireAll()validates using all listed validators.
requireLength()applies requirements on input text length.
requireNeeded()filters validation messages from the given
validatorsaccording to their codes.
requirePresent()requires value to present.
requireRange()applies requirements to numeric value range.
Simple validator can be applied like this: