The KoiSwitch component is a toggle button that sends different commands in the event depending on its internal state.
The task of the KoiSwitch is the same as that of the KoiIdButton. When clicked, KoiSwitch transmits a command in the koi-operated event, described by the identifier of an element, a string action code, and a parameter. However, while the KoiIdButton is associated with a single command, KoiSwitch sends one of two commands, primary_action and secondary_action, toggling between them.
Upon initialization, KoiSwitch selects the command defined by item_action. Just before firing the event, the KoiSwitch component changes the currently selected command to the other one. The event will transmit the newly selected command. For example, if secondary_action is currently selected, clicking will transmit primary_action, and the new selected command will be primary_action.
The selected command is remembered by the KoiSwitch component in its own data using the KoiBinary data element behavior, which is responsible for storing the command codes. Since KoiSwitch uses its own data to store the state, it does not rely on the behaviors of internal components. Internal components are only needed for displaying the state, not for storing information about it. Therefore, subclasses of the KoiSwitch component can be implemented using different native components. For example, the KoiSwitch component can use a checkbox, two buttons, a color-changing button, or even a label.
Thanks to its ability to remember commands and toggle between them, the KoiSwitch component can be used as a universal switch for controlling collapsing/expanding, turning on/off, and so on.
Essentially, if an external component uses KoiSwitch as a toggle, it delegates the responsibility for storing the state to KoiSwitch. For example, the KoiFormFieldCheckButtons component uses KoiSwitch to add values to its own data and remove values from its own data. In this case, KoiFormFieldCheckButtons does not track which values it contains, trusting the internal components of KoiSwitch. If, for some reason, KoiFormFieldCheckButtons, which contains values B and C, receives a command from KoiSwitch to delete value A, it will not trigger an error event, as the responsibility for the correctness of the value set has been delegated to KoiSwitch.
Class
The initialization process of the KoiSwitch component is as follows:
-
_onConstructed() KoiDataCapable
- _constructState() KoiStateCapable
- _constructData() KoiSwitchDataCapable
- _constructSocket() KoiSwitchNativeCheckboxSocketConnectable
-
_onBeforeConnected() KoiDataCapable
- _constructOperationEvent() KoiOperationEventDispatchable
- _prepareDefaultDataValuesFromAttributes() KoiSwitchDataCapable
- _prepareSocket() KoiSocketConnectable
-
- socket.getTemplate() KoiSwitchNativeBaseSocket
-
_onConnected() KoiElementStencil
- _updateSomethingWhenConnected() KoiElementStencil
-
- _updateOwnDataWhenConnected() KoiElementStencil
- _updateStateCodeWhenConnected() KoiStateCapable
-
_onAfterConnected() KoiElementStencil
- isSomethingChanged() KoiDataCapable
- _handleSomethingChangedWhenAfterConnected() KoiBaseControl
-
- updateAppearance() KoiBaseControl
- _subscribeToEvents() KoiOperationsInterceptable
-
- _subscribeToOperateEvent() KoiOperationsInterceptable
The KoiSwitch component inherits from KoiBaseSwitch and implements the KoiSwitchNativeCheckboxSocketConnectable behavior.
The KoiBaseSwitch class is a subclass of KoiButtonStencil, like a regular button. Therefore, KoiBaseSwitch inherits the typical button behavior, where the button receives an event from the internal native component and responds by triggering its own event. However, KoiBaseSwitch extends this behavior by requiring the component to display the initial state in the socket upon its first render, and then, upon receiving an event from the internal native component, change its state before triggering its own event.
Additionally, the KoiBaseSwitch class implements the KoiSwitchDataCapable behavior, which extends the KoiOperationDataCapable behavior by defining KoiSwitchData as the data object and allows the component to obtain from the tag attributes not only the initial values defining the command but also the command variants, such as primary_action and secondary_action.
The KoiSwitchNativeCheckboxSocketConnectable behavior defines the KoiSwitchNativeCheckboxSocket class socket for the KoiSwitch component, which uses a checkbox as the native component.
By replacing the KoiSwitchNativeCheckboxSocketConnectable behavior with KoiSwitchNativeButtonSocketConnectable, the component switches from using a checkbox to a color-changing button.
The checkbox native component and the change event are associated with several features, which are encapsulated by the KoiSwitch component.
The first feature relates to the approach for event transmission. The idea behind KoiCom button components is that when interacting with buttons, the user wants to issue a command. This motivation is far more important than the implementation details. Therefore, the component must encapsulate the method of issuing the command.
The native checkbox component triggers a change event, while a regular button triggers a click event. This information is not important for the command receiver, but the use of native components forces it to be handled differently.
The KoiOperationsInterceptable behavior, which forms the basis for all button behavior, enables buttons to respond consistently to any native events. The only thing needed is to specify in the component which types of native events the component will intercept. This can be done in the _getInterceptableOperateEventCode method, which provides flexibility regarding the types of intercepted native events and allows for the implementation of KoiSwitch variants that will work with other native components triggering different events.
The second feature is that KoiSwitch modifies the transmitted command in its own data, whereas the KoiIdButton component does not. Nevertheless, both components must trigger an event in the _dispatchEventsWhenChangedAfterOperated method. Therefore, the shared ancestor of these components, KoiButtonStencil, marks its state as changed in the _updateStateCodeWhenOperated method upon receiving an event from internal components, causing both components to send their own events every time they receive events from internal components.
For the KoiIdButton component, this reaction is natural, but the native checkbox component, which can be used in the KoiSwitch component, still has a lingering issue that has not yet been resolved. A click on the checkbox itself triggers a click event only once, but a click on the label triggers the click event twice. Since KoiSwitch intercepts change events, this issue does not affect it. However, if you are implementing components based on the click event, you will need to find a way to encapsulate this feature to ensure that your component, when processing events from internal components, triggers its own event only once.
In terms of the event triggered, the KoiSwitch component behaves the same way as KoiIdButton. The KoiSwitch component has its own data object of type KoiSwitchData, inherited from KoiButtonData. This data is passed in the koi-operated event, which has a bubbles property set to true, meaning it can propagate upwards through the DOM tree and be intercepted by a component acting as a controller.
To intercept the koi-operated event, the component-controller must implement the KoiOperationsInterceptable behavior. For more details, refer to the description of the KoiIdLink component.
Data
The KoiSwitch component's own data is of type KoiSwitchData, defined by the following schema:
The KoiSwitchData class extends the KoiOperationData class, designed for describing commands, and uses the KoiBinary behavior. This behavior allows the data element to hold one of two values, with the possible values stored within the data element.
Within the data object context, the command codes primary_action and secondary_action are treated as options for the item_action data element, which can only hold one of these two values. Therefore, if an external controller component needs to determine which of the two values was passed in the event, it can refer to the data object to identify which value is primary_action and which value the item_action data element currently holds. However, both actions and their comparison are part of the data object, and the controller component is not required to perform these actions itself. Thus, the controller component can simply call the isActionPrimary method on the data object to get the same result.
The KoiSwitch component receives command codes during initialization, usually from tag attributes, and then passes them to the data object. To enable this action, the KoiSwitch component extends the _prepareDefaultDataValuesFromAttributes method in the KoiSwitchDataCapable behavior and calls the setActionOptions method on the data object.
The setActionOptions method can also be invoked under other circumstances, such as when the component is reinitialized. However, in such cases, I recommend the following reinitialization steps: first, make the component unavailable, then reinitialize it, and only after that allow the user to interact with the component again.
The KoiSwitchDataCapable behavior provides two additional methods for the component: _selectPrimaryAction and _selectSecondaryAction. These methods enable the component to assign the appropriate command option to the data object based on the data state when processing the event received from the internal component.
Attributes
id | Component identifier |
---|---|
item_id | String identifier for the item |
item_action | Initial value of the string identifier for the command |
primary_action | First possible value for the command identifier |
secondary_action | Second possible value for the command identifier |
css_class | Additional CSS class for the component |
placeholder | Text displayed on the button |
Almost all the attributes have the same purpose as the attributes of a regular KoiIdButton component. For example, the item_id and item_action attributes serve to clarify the user's intent, i.e., to indicate the reason why the user clicked the button.
The primary_action and secondary_action attributes specify two possible values for the data element item_action, which is passed in the event.
State
The KoiSwitch component is inherited from KoiBaseControl, enabling it to implement two basic states, defined by the show and hide methods. Additionally, the component has a displayable state, which is implemented in the KoiSocketInputEnablementToggleable behavior and allows the button to be activated or deactivated with the disable and enable methods. Moreover, the KoiSocketInputEnablementToggleable behavior provides the setReadonly and removeReadonly methods to lock and unlock user interaction with the component.
As shown, in this example, the states defined by the disable and enable methods are implemented, but the states defined by the setReadonly and removeReadonly methods are not, because the chosen internal native component is a checkbox. Using a different native component would allow these two states to be implemented as well.
Event
The KoiSwitch component has its own data and implements the KoiOperationEventDispatchable behavior, which means it generates the koi-operated event. Normally, components with their own data trigger the koi-changed event. However, in the case of KoiSwitch, which acts as a button, data changes are closely tied to the pressing of the component, so the koi-changed event is replaced with the koi-operated event.
The koi-operated event has the bubbles property set to true, meaning the event propagates upward through the DOM tree. This enables the creation of buttons within a composite component, where the composite component will automatically handle the incoming data, acting as a controller.
The example above demonstrates how, when the KoiSwitch component is pressed, the panel containing the components acts as a controller and modifies the text in the KoiLabel component using the command code received in the event. For this, the panel implements the KoiOperationsInterceptable behavior.
Usage
The concept of KoiSwitch is a direct extension of the ideas implemented in KoiIdButton. The purpose of any button is to communicate the user's intent to a controller component, which involves performing actions on a specific element.
However, KoiSwitch extends the behavior of a button. While the KoiIdButton is associated with a single, fixed command, KoiSwitch toggles between two commands. This makes it suitable for tasks that require performing an action and then undoing it. For example, hiding and showing a component, adding an item to an array, or removing an item from an array.