Conditional States
Scope of Conditions
Conditions within Qodly are classified into two types:
Local Conditions
Local Conditions are specific to the currently selected state and can be customized to meet unique logic requirements of that state.
Saved Conditions
Saved Conditions are reusable and can be applied across different states, stored within the Saved Conditions
area for easy access and application.
For more details, please refer to the Saved Conditions area section.
Conditions Interface
Accessible via the Conditions
button next to the States
header, this interface is pivotal in visualizing and managing conditions that define the behavior of Page states. It includes major tools such as the States Area
, Saved Conditions Area
, Schema Editor
, and JSON Editor
, each designed to facilitate specific aspects of condition management.
States Area
Saved Conditions Area
The tab representing the condition currently being modified is distinctly highlighted, providing users with a clear visual indication of the active condition.
Adding a new saved condition involves clicking the button, which initializes it with a generic name.
JSON Editor
Upon addition, each condition's initial JSON structure appears in the editor as follows:
{
"id": "auto_generated_unique_identifier",
"name": "default_condition_name",
"type": "unspecified"
}
This initial blueprint provides a template that users can modify to fit the specific requirements of their Page conditions.
When working with conditions in the JSON Editor, users will encounter several common fields:
- id: A unique identifier for the condition (type: string).
- name: The name of the condition (type: string).
- type: Specifies the type of condition (e.g., qodlysource, privilege, parentState, reference, combination).
- path: The data path within the qodlysource (for qodlysource conditions).
- value: The value to compare against, which can be of various types (number, string, boolean, object, array, or null).
- op: The operator for comparison (e.g., eq, neq, regex, in, nin, gt, gte, lt, lte).
Conditions Schema Editor
At the core of the Conditions Interface is the Schema Editor, a dynamic visualization tool essential for mapping out and manipulating condition logic in a flowchart-like format. This interface allows for intuitive operations such as:
Default Options
Add condition
button by default, facilitating quick starts in condition creation.Saved Condition Integration
Saved Condition
into the current state's logic by clicking and dragging from the Saved Conditions Section directly into the schema.Ensure proper placement by dragging the Saved condition
to the ellipsis icon , which represents the condition's specific level within the schema. Dropping it elsewhere might not integrate the condition correctly.
When multiple conditions are present, dropping it onto the connecting logical operator square will integrate it as well.
Logical Condition Combination
&
operator for combined fulfillment, or the |
operator for partial fulfillment.Comprehensive View Controls
Facilitate a switch between detailed and overview modes by using the global expand/collapse button , accessible via the designated button in the schema header .
Condition Configuration Card
For additional details, please refer to the Condition Types section.
Condition Types
Each condition within the schema is represented by an interactive card, providing a user-friendly interface for configuring specific properties. These cards can be expanded or collapsed to display key details and settings.
Qodly Source
Name | Icon | Description | Available Operators |
---|---|---|---|
Qodly Source | Evaluates data from a specified qodlysource. | = , != , > , >= , < , <= , in , not in , regex |
Value Type | Operator | Description |
---|---|---|
String | = | Checks if the string is exactly equal to the specified value. |
!= | Checks if the string is not equal to the specified value. | |
regex | Evaluates the string using a regular expression. Useful for pattern matching, e.g., checking if a string follows a format. | |
starts with | Checks if the string starts with the specified substring. | |
in | Checks if the string is present within a list of values. | |
not in | Checks if the string is not present within a list of values. | |
is null | Checks if the string is null , meaning it has no value or is undefined. | |
not null | Checks if the string is not null , meaning it has a defined value. | |
Number | = | Checks if the number is exactly equal to the specified value. |
!= | Checks if the number is not equal to the specified value. | |
> | Checks if the number is greater than the specified value. | |
>= | Checks if the number is greater than or equal to the specified value. | |
< | Checks if the number is less than the specified value. | |
<= | Checks if the number is less than or equal to the specified value. | |
between | Checks if the number falls within a specified range of two values. | |
is null | Checks if the number is null , meaning it has no value. | |
not null | Checks if the number is not null , meaning it has a defined value. | |
Boolean | is true | Checks if the value is true . |
is false | Checks if the value is false . | |
is null | Checks if the boolean value is null . | |
not null | Checks if the boolean value is not null . | |
Object | = | Checks if the object is exactly equal to the specified object. |
!= | Checks if the object is not equal to the specified object. | |
isempty | Checks if the object is empty, meaning it contains no key-value pairs. | |
is null | Checks if the object is null , meaning it has no value or has not been initialized. | |
not null | Checks if the object is not null , meaning it exists and contains data. | |
Array | = | Checks if the array is exactly equal to the specified array. |
!= | Checks if the array is not equal to the specified array. | |
isempty | Checks if the array is empty, meaning it contains no elements. | |
is null | Checks if the array is null , meaning it has no value or is undefined. | |
not null | Checks if the array is not null , meaning it contains elements or is initialized. | |
Entity Selection | = | Checks if the selected entity selection matches the specified entity selection. |
!= | Checks if the selected entity does not match the specified entity. | |
is null | Checks if no entity has been selected or if the selection is null . | |
not null | Checks if an entity has been selected and is not null . | |
Entity | = | Checks if the entity is equal to the specified entity. |
!= | Checks if the entity is not equal to the specified entity. | |
is null | Checks if the entity is null , meaning it does not exist or has not been defined. | |
not null | Checks if the entity exists and is not null . |
Example
- Visual Representation
- Json Code
{
"type": "combination",
"id": "auto_generated_unique_identifier_1",
"op": "and",
"conditions": [
{
"type": "qodlysource",
"id": "auto_generated_unique_identifier_2",
"name": "Age over 25",
"path": "employee.age",
"op": "gt",
"value": 25
},
{
"type": "qodlysource",
"id": "auto_generated_unique_identifier_3",
"name": "Lastname starts with D",
"path": "employee.lastname",
"op": "regex",
"value": "^D"
}
]
}
Current State Condition
Name | Icon | Description | Available Operators |
---|---|---|---|
Current State | Evaluates the currently applied state of a page against a specified condition. | = , != , regex |
Example
- Visual Representation
- Json Code
{
"type": "combination",
"id": "auto_generated_unique_identifier_13",
"op": "and",
"conditions": [
{
"type": "currentState",
"id": "auto_generated_unique_identifier_14",
"name": "Current state is State_1",
"op": "eq",
"value": "State_1"
},
{
"type": "currentState",
"id": "auto_generated_unique_identifier_15",
"name": "Current state matches regex",
"op": "regex",
"value": "^State"
}
]
}
Parent State Condition
Name | Icon | Description | Available Operators |
---|---|---|---|
Parent State | Evaluates the currently applied state of a page's parent page against a specified condition. This condition is typically used when a Page Loader component is added to a certain page, and the loaded page must evaluate the parent page's state to determine the behavior of it. | = , != , regex |
Example
- Visual Representation
- Json Code
{
"type": "combination",
"id": "auto_generated_unique_identifier_10",
"op": "and",
"conditions": [
{
"type": "parentState",
"id": "auto_generated_unique_identifier_11",
"name": "Parent state is Active",
"op": "eq",
"value": "Active"
},
{
"type": "parentState",
"id": "auto_generated_unique_identifier_12",
"name": "Parent state starts with A",
"op": "regex",
"value": "^A"
}
]
}
Privilege Condition
Name | Icon | Description | Available Operators |
---|---|---|---|
Privilege | Evaluates the user's privilege level, typically used to control access to specific features or actions based on the user’s permissions. | = , != , regex |
A conditional state on a privilege evaluates whether the privileges have changed on the server. The front end requests the current session privileges from the server if the privileges stamp has changed. This ensures that any changes in privileges are accurately reflected in the application's state.
Example
- Visual Representation
- Json Code
{
"type": "combination",
"id": "auto_generated_unique_identifier_7",
"op": "and",
"conditions": [
{
"type": "privilege",
"id": "auto_generated_unique_identifier_8",
"name": "User is guest",
"op": "eq",
"value": "guest"
},
{
"type": "privilege",
"id": "auto_generated_unique_identifier_9",
"name": "Not restricted",
"op": "neq",
"value": "restricted"
}
]
}
Saved Condition
Name | Icon | Description | Available Operators |
---|---|---|---|
Saved Condition | References a pre-defined condition stored in the Saved Conditions area, allowing for reuse across different states. | N/A |
Example
- Visual Representation
- Json Code
{
"type": "combination",
"id": "iiq55CwnDbkEbqtZ46HmuN",
"op": "or",
"conditions": [
{
"type": "reference",
"id": "auto_generated_unique_identifier_5",
"name": "Condition 2",
"ref": "7EhcZvWyNCr6AqPqS139Mz"
},
{
"type": "reference",
"id": "auto_generated_unique_identifier_6",
"name": "Condition 3",
"ref": "7ymDgJc1iL6ca1Q8WzL43z"
}
]
}
Condition Management
Add Condition (Local)
Local Conditions are specific to the currently active state and allow for state-specific conditions customization. To add a Local Condition to your state:
From the Schema Window: If no conditions are currently set up, simply click the
Add condition
button in the schema window to insert a new condition at the base level of the state’s logic hierarchy.Using the Side Menu: For contextual additions within a specific logic level, select the
Add condition
option from the side menu. This will introduce a new condition card at the same hierarchical level as the location where you invoked the command.infoFor instance, in the visual example provided, ifAdd condition
is selected from the side menu at the position of conditionsc1
andc2
, the new condition will be placed on the same level as these conditions.It ensures that your new condition is logically organized within the same group, maintaining the consistency and flow of the state's configuration.
Duplicate Condition
The Duplicate condition
option allows users to create an exact copy of an existing condition or groups of conditions, preserving all configurations.
Rename Condition
Rename condition
option enables users to change its default name.Alternatively, users can click on the button next to the condition's name to initiate renaming
Upon initiating renaming, the condition name switches to an editable input field.
Save Condition
Save condition
option, conditions or groups of conditions can be stored as saved conditions accessible in the Saved States
area.Upon saving, a prompt will appear requesting a name for the saved condition.
Remove Condition
Remove condition
option is available for users needing to clear out unused or unwanted conditions from the schema. This tool helps declutter the configuration space by removing selected conditions or groups of conditions.Upon initiating deletion, a confirmation popup will appear, requiring user confirmation to proceed.
Conditional State Lifecycle
Conditional states are primarily applied during the Rendering and Post-Render Updates phases of the Page/Renderer lifecycle:
Rendering Phase:
- The page renders its initial state, often defaulting to the Base state. This is when the initial content, styles, and layouts are displayed to the user.
Post-Render Updates Phase:
Based on the evaluated conditions and fetched qodly sources, the page updates its state. Conditional states modify the Base state to reflect user-specific configurations.
Users interact with the page, which might trigger further state changes and updates.
The Base state might be visible initially due to the timing of data fetching and condition evaluation relative to the rendering process. The page initializes its structure and components, then renders the Base state, which contains all potential elements and components.
To ensure the Base state is not visible before the correct state is applied, follow these steps:
Use the
onInit
Event:Utilize the
onInit
event to set up all necessary qodly sources and conditions before the page is rendered.This event runs before the rendering phase, allowing you to prepare the page state in advance.
Initialize Qodly Sources Early:
Ensure that all required qodly sources are fetched and available during the
onInit
event.This ensures that the data needed for conditional states is ready before rendering.
Evaluate Conditions Pre-render:
Evaluate all conditions necessary to determine the user-specific state within the
onInit
event.This includes checking priviliges and other relevant criteria.
Singleton Properties's Impact on State
Singleton computed properties are used to manage and return objects stored in Qodly Sources. These properties are typically invoked to refresh data or trigger server-side processes. However, their interaction with a state can lead to significant implications:
State Dependency: When a singleton computed property updates a Qodly Source that is bound to a state condition on the Qodly Page, any change in this source can trigger a state change.
Deserialize and Re-rendering: Clicking a button that invokes a singleton computed property can cause a state change. This triggers Qodly to deserialize and re-render the page to update the internal state of CraftJS, which can result in an entire page reload.
Initial Action: A button with an onClick event calls a singleton computed property that returns an object and stores it in a Qodly Source. Clicking this button alone works as expected without reloading the page.
Triggering a Server-side Process: Another action triggers a server-side process through the singleton computed property.
Subsequent Action: Clicking the initial button again causes the page to reload. This happens because the Qodly Source used in the state condition is updated, triggering a state change. Qodly then deserializes and re-renders the page through CraftJS, leading to a full page reload.
To avoid unintended page reloads when using singleton computed properties, consider the following strategies:
Minimize State Changes: Avoid binding state conditions to Qodly Sources that are frequently updated by singleton computed properties. This helps reduce unnecessary re-renders.
Proper Navigation Handling: If you use a qodly source for navigation purposes, ensure its value is correctly updated during navigation events. This prevents unintended reloads due to outdated qodly source values.