Let’s come to a core concept of CYPEX: expressions. What you actually see in the GUI isn’t just some static field, but in fact, a JavaScript expression which can be modified. This gives you a great deal of flexibility and allows you to tailor the GUI to your needs. Using JavaScript expressions, you have great power at your fingertips.
However, most people aren’t heavy JavaScript users and therefore a lot of the more common tasks have been simplified by adding graphical shortcuts. One of these shortcuts was shown before: ID resolution. What the GUI element actually does is to modify the underlying JavaScript relation in the desired way.
But let’s not get lost in technical details, rather move forward and see what you can do in real life to build more useful applications.

To show how things work, look at the TODO list built in one of the previous chapters. Go to edit mode, and click on the “TODO item” column in your main table. If you look closely, you’ll see “props.data”. This is the JavaScript expression mentioned a moment ago.
In this case, the column is supposed to display the “todo_item” element coming from the backend. But you can modify that - you can apply basically any expression to this data.
For the sake of simplicity, let’s add a prefix to the content of the column:

What we’re using here is pure JavaScript code.
“MY CHANGE: “ will be used as a prefix. If you have a basic knowledge of JavaScript, you’ll be able to do really powerful things using simple expressions.
The final product will look as follows:

The way data is displayed has been changed on the fly. The workflow stays unchanged. The data in the backend is also going to stay unchanged - we’re only talking about the way CYPEX displays data.
Custom expressions allow you to write JavaScript code that evaluates at runtime, enabling dynamic behavior in your CYPEX applications. Instead of static values, you can create expressions that:
- Display data from other elements
- Calculate values dynamically
- Filter data based on user input
- Format content conditionally
- Show or hide elements based on conditions
- Create interactive user experiences
Custom expressions are available in many element configuration fields. Look for the expression toggle (⚡) icon next to input fields in the element editor. Common use cases include:
- Text Fields: Dynamic text content (
textproperty) - Data Display: Custom formatting (
formatproperty) - Tables: Filter expressions (
fixedFilter,elementsFilterCombinator,hiddencolumns) - Meta Query: Dynamic filters (
filterproperty) - Number Fields: Calculated values (
valueproperty) - Call Buttons: Dynamic function arguments (
argumentsproperty) - Form Elements: Conditional visibility and dynamic values
- Color Fields: Dynamic colors based on data (
color,backgroundproperties)
Tip: If a field supports custom expressions, you’ll see a toggle switch (⚡) in the editor. Click it to switch between “Plain Value” and “Expression” mode.
In CYPEX, each element on the page has access to its selectors - predefined JavaScript objects with properties and values that allow elements to interact with each other in a controlled way.
Available Context Objects:
element: The current element’s own data and propertieselements: Access to all other elements on the page (e.g.,elements["input_id"].value)props: Data passed from parent elements (e.g., table rows, form data)location: Current page URL and query parameterspage: Current page informationi18n: Translation and internationalizationmoment: Date/time manipulation librarylodash: Utility functions library
Depending on the element configuration, custom expressions should return the appropriate value type: string, number, boolean, array, object, or function. We recommend checking out our video tutorial series for visual examples.
Custom expressions in CYPEX are JavaScript code that evaluates at runtime. When you enter a value in a field that supports custom expressions, you can toggle between a plain value and an expression using the toggle switch in the editor. The expression prefix (@@expression:) is handled automatically by CYPEX - you just write the JavaScript code.
Plain Value:
Hello World
Custom Expression:
"Hello " + "World"
Note: You don’t need to type
@@expression:manually. The expression editor adds this automatically when you toggle to expression mode.
- Open an element editor - Click on any element in edit mode
- Find a field with the expression toggle - Look for the ⚡ icon next to input fields
- Click the toggle - Switch to “Expression” mode
- Enter your JavaScript code - Type your expression (no prefix needed - CYPEX handles this automatically)
- Test your expression - The result is evaluated in real-time
Here are common, simple use cases for custom expressions:
Example: Display a number field’s value with currency formatting
| |
Example: Access a table column value
| |
Example: Show different text based on a condition
| |
Example: Display a message based on another element’s value
| |
Example: Use a query parameter from the URL
| |
Example: Build a dynamic identifier from URL
| |
Example: Display translated text
| |
Example: Combine translation with dynamic value
| |
Example: Calculate a total
| |
Example: Calculate percentage
| |
Example: Format a date string
| |
Example: Uppercase conversion
| |
Example: Check if a value exists
| |
Example: Compare two values
| |
For more complex scenarios, custom expressions can handle sophisticated logic:
Example: Format a data display with multiple fields
| |
Example: Format currency with proper decimal places
| |
Example: Count items in an array
| |
Example: Filter and map array data
| |
Example: Multi-condition display
| |
Example: Conditional styling based on multiple values
| |
Example: Dynamic filter based on element values
| |
Example: Filter using selected table row
| |
Example: GeoJSON style function
| |
Example: Custom formatting function
| |
Example: Group and count data
| |
Example: Find and format
| |
Example: Debounce-like logic with lodash
| |
Example: Dynamic function call with computed arguments
| |
Example: Conditional function name
| |
Example: Format with conditional logic
| |
Example: Format with error handling
| |
Example: Build URL with query parameters
| |
Example: Build email subject line
| |
Example: Calculate age from birthdate
| |
Example: Show relative time
| |
Example: Format date range
| |
This section provides practical examples for using custom expressions in specific CYPEX elements.
Property: text - Returns string, number, or null
Example: Display dynamic text
| |
Example: Conditional text based on data
| |
Example: Format with currency
| |
Property: format - Returns any value for display formatting
Example: Format multiple fields
| |
Example: Format with conditional logic
| |
Example: Custom query filter
| |
Properties: fixedFilter, elementsFilterCombinator, hidden (for columns)
Example: Fixed filter with multiple conditions
| |
Example: Hide column conditionally
| |
Example: Filter combinator based on selection
| |
Property: filter - Returns PostgREST filter object
Example: Dynamic filter from form inputs
| |
Property: value - Returns number
Example: Calculate from other elements
| |
Example: Sum array values
| |
Property: arguments - Returns object with function arguments
Example: Dynamic function arguments
| |
Example: Conditional arguments
| |
Properties: color, background - Returns color string
Example: Color based on status
| |
Example: Color based on value threshold
| |
Property: visible - Returns boolean
Example: Show based on user role
| |
Example: Show based on form state
| |
Property: identifierValue - Returns string or null
Example: Get ID from URL
| |
Example: Get ID from selected table row
| |
| Pattern | Description | Example |
|---|---|---|
element.data.value | Current element’s data value | element.data.value |
elements["id"].value | Another element’s value | elements["input_123"].value |
props.data["field"] | Table row or form field data | props.data["first_name"] |
location.query.param | URL query parameter | location.query.id |
i18n.label | Translated label | i18n.label |
moment().format() | Date formatting | moment().format("YYYY-MM-DD") |
| Use Case | Pattern | Example |
|---|---|---|
| Conditional value | condition ? value1 : value2 | status === "active" ? "Yes" : "No" |
| Null fallback | value ?? defaultValue | element.data.value ?? "N/A" |
| Safe property access | object?.property | elements["table"].selected?.row?.id |
| String concatenation | `${var1} ${var2}` | `Hello ${name}` |
| Array length check | array?.length > 0 | element.data.items?.length > 0 |
| Date comparison | moment(date1).isAfter(date2) | moment(date).isAfter(moment()) |
| Operator | Use Case | Example |
|---|---|---|
eq | Exact match | { field: "status", operator: "eq", value: "active" } |
ilike | Case-insensitive search | { field: "name", operator: "ilike", value: "%john%" } |
in | Match any in list | { field: "id", operator: "in", value: [1, 2, 3] } |
gte / lte | Range queries | { field: "price", operator: "gte", value: 100 } |
cs | Array contains all | { field: "tags", operator: "cs", value: ["a", "b"] } |
ov | Array overlap | { field: "categories", operator: "ov", value: [1, 2] } |
is | Null check | { field: "deleted_at", operator: "is", value: null } |
Use this pattern when building filters with optional values:
| |
Use Optional Chaining: Always use
?.when accessing nested properties that might not exist:1elements["table"].selected?.row?.id ?? "none";Provide Fallbacks: Use nullish coalescing (
??) or ternary operators for default values:1element.data.value ?? "Default Value";Handle Loading States: Check for loading/error states when accessing data:
1element.loading ? "Loading..." : (element.data?.value ?? "No data");Keep Expressions Readable: Break complex logic into multiple expressions or use clear variable names in comments (though comments aren’t supported, keep logic simple).
Validate Input: Check for null/undefined before performing operations:
1props.data["amount"] ? props.data["amount"] * 1.1 : 0;Use Element IDs Correctly: Access other elements using their full ID:
1elements["default_text_field_abc123"].value;
- Forgetting to Toggle Expression Mode: Make sure to toggle to expression mode (⚡ icon) - the prefix is added automatically
- Accessing Non-existent Properties: Always check if properties exist before accessing
- Circular Dependencies: Avoid expressions that reference each other in a loop
- Returning Module Proxies: Never return element modules from expressions (they’re automatically detected and prevented)
- Type Mismatches: Ensure the expression returns the expected type (string, number, boolean, etc.)
Custom expressions are particularly powerful when used to filter data sources like tables, data displays, and meta queries. CYPEX uses PostgREST filter syntax, which provides a comprehensive set of operators for querying your database.
Note: CYPEX implements a subset of PostgREST operators that are most commonly used. For the complete list of PostgREST operators, refer to the official PostgREST documentation.
PostgREST filters use a structured format with three main components:
combinator: How multiple filters are combined ("AND"or"OR")filters: An array of filter rules- Each filter rule contains:
field: The database column name to filter onoperator: The comparison operator (e.g.,"eq","gte","like")value: The value to compare against (can be static or from an element)
| |
| Operator | Description | Example Use Case | PostgREST Equivalent |
|---|---|---|---|
eq | Equals (exact match) | Find records with specific name | = |
neq | Not equal | Exclude specific values | <> or != |
like | Pattern match (case-sensitive) | Search with wildcards (%text%) | LIKE |
ilike | Pattern match (case-insensitive) | Case-insensitive search | ILIKE |
match | Regular expression match | Advanced pattern matching | ~ |
imatch | Case-insensitive regex match | Case-insensitive regex | ~* |
fts | Full-text search | PostgreSQL full-text search | @@ (to_tsquery) |
is | IS comparison (null, true, false) | Check for null values | IS |
in | In list | Match any value in an array | IN |
Note: For pattern matching with
likeandilike, you can use%as a wildcard. In URLs, PostgREST also accepts*as an alias for%to avoid URL encoding, but in CYPEX filter expressions, use%directly.
Example: Filter by name using exact match
| |
Example: Case-insensitive search with pattern matching
| |
Example: Full-text search
| |
Example: Match multiple values (IN operator)
| |
Example: Check for null values
| |
| Operator | Description | Example Use Case | PostgREST Equivalent |
|---|---|---|---|
eq | Equals | Exact number match | = |
neq | Not equal | Exclude specific number | <> or != |
gt | Greater than | Values above threshold | > |
gte | Greater than or equal | Values at or above threshold | >= |
lt | Less than | Values below threshold | < |
lte | Less than or equal | Values at or below threshold | <= |
isdistinct | Is distinct from | Handles null comparisons | IS DISTINCT FROM |
is | IS comparison | Check for null | IS |
in | In list | Match any number in array | IN |
all | All values match (for arrays) | Array field contains all values | Array operator |
any | Any value matches (for arrays) | Array field contains any value | Array operator |
Example: Filter by price range
| |
Example: Filter by multiple numeric values
| |
Example: Filter using array field (any value matches)
| |
| Operator | Description | Example Use Case | PostgREST Equivalent |
|---|---|---|---|
eq | Equals | Exact date match | = |
neq | Not equal | Exclude specific date | <> or != |
gt | Greater than | Dates after | > |
gte | Greater than or equal | Dates on or after | >= |
lt | Less than | Dates before | < |
lte | Less than or equal | Dates on or before | <= |
ov | Overlap | Date ranges that overlap | && |
sl | Strictly left of | Date range completely before | << |
sr | Strictly right of | Date range completely after | >> |
is | IS comparison | Check for null dates | IS |
Note: For date range operators (
ov,sl,sr), use PostgreSQL range format:[start,end]for inclusive ranges or(start,end)for exclusive ranges. Example:"[2024-01-01,2024-12-31]".
Example: Filter by date range
| |
Example: Filter records created today
| |
Example: Filter by date overlap (for date ranges)
| |
| Operator | Description | Example Use Case | PostgREST Equivalent |
|---|---|---|---|
eq | Equals | Match true/false | = |
neq | Not equal | Exclude true/false | <> or != |
is | IS comparison | Check for null | IS |
Note: Use
isoperator withnull,true, orfalsevalues. Example:{ field: "deleted_at", operator: "is", value: null }or{ field: "is_active", operator: "is", value: true }.
Example: Filter active records only
| |
Example: Filter using checkbox value
| |
| Operator | Description | Example Use Case | PostgREST Equivalent |
|---|---|---|---|
cs | Contains | Array field contains all values | @> |
cd | Contained in | Array field is subset of value | <@ |
ov | Overlap | Arrays have common elements | && |
sl | Strictly left of | Array completely before | << |
sr | Strictly right of | Array completely after | >> |
in | In list | Array field value in list | IN |
all | All values match | All array elements match condition | Array operator |
any | Any value matches | Any array element matches condition | Array operator |
Note:
cs(contains): Array field must contain all specified values. Example:{ field: "tags", operator: "cs", value: ["important", "urgent"] }matches rows where tags array contains both “important” AND “urgent”.ov(overlap): Array field has any common elements. Example:{ field: "categories", operator: "ov", value: [1, 2, 3] }matches rows where categories array contains any of 1, 2, or 3.- Use curly braces
{}for array values in filters:["value1", "value2"]or[1, 2, 3].
Example: Filter by tags (array contains)
| |
Example: Filter where array contains any of the selected values
| |
Example: Filter using array input element
| |
Example: Filter where array field contains all selected values
| |
All conditions must be true:
| |
At least one condition must be true:
| |
Filter a table using multiple optional input fields. Use a self-calling function to define constants and only include filters when values exist (PostgREST is sensitive to null/undefined values):
| |
Filter a related table based on the selected row in another table:
| |
Filter records within a date range with optional boundaries. Use a self-calling function to only include filters when dates are provided:
| |
Filter where an array field contains values from a multi-select input:
| |
Only apply certain filters when conditions are met. Use a self-calling function to safely handle optional filters:
| |
Filter products by price range, with optional category and search. Use a self-calling function to handle optional filters safely:
| |
If your input element returns an array (like a multi-select), use it directly:
| |
Use array-specific operators (cs, cd, ov, any, all):
| |
Filter where an array field contains values from an array input:
| |
Handle Empty Values: Always check if filter values exist before including them. For multiple optional filters, use a self-calling function pattern:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17(() => { const search = elements["search"].value; const filters = []; if (search) { filters.push({ field: "name", operator: "ilike", value: "%" + search + "%", }); } return { combinator: "AND", filters: filters, }; })();This ensures PostgREST never receives null/undefined values in filter objects, which can cause errors.
Use Optional Chaining: Protect against undefined values:
1value: elements["table"].selected?.row?.id;Use Self-Calling Functions for Multiple Filters: PostgREST is sensitive to null/undefined values. Define constants and only add filters when values exist:
1 2 3 4 5 6 7 8 9 10 11 12 13 14(() => { const minPrice = elements["min_price"].value; const maxPrice = elements["max_price"].value; const filters = []; if (minPrice) { filters.push({ field: "price", operator: "gte", value: minPrice }); } if (maxPrice) { filters.push({ field: "price", operator: "lte", value: maxPrice }); } return { combinator: "AND", filters: filters }; })();Use Appropriate Operators:
- Use
ilikefor case-insensitive text search - Use
infor matching multiple discrete values - Use
cs/ovfor array field operations - Use
iswithnullfor null checks
- Use
Format Dates Properly: Always use ISO format for dates:
1value: moment(elements["date"].value).toISOString();
Use a self-calling function to safely handle multiple optional filters:
| |
Use a self-calling function for optional date ranges:
| |
| |
- Filter Not Working: Check that the field name matches the database column exactly (case-sensitive)
- PostgREST Sensitivity: PostgREST is sensitive to null/undefined values in filters. Use self-calling functions to only include filters when values exist (see Best Practices section)
- Array Filter Issues: Ensure you’re using the correct operator (
csfor contains,ovfor overlap) - Date Filter Issues: Always format dates as ISO strings using
moment().toISOString() - Null Values: Use the
isoperator withnullto check for null values - Empty Arrays: Check if array inputs are empty before using them in filters
- Operator Not Supported: If an operator doesn’t work, verify it’s supported in CYPEX. Refer to the operator tables above or check the PostgREST documentation for the complete list of available operators
The first thing to understand is how to navigate inside the page. There are many variables which are of key importance. These can be used to figure out where we are and how to navigate through the application. Let’s inspect these variables in more detail to figure out how it all works, and what is possible:
pathname is a string which contains the URL’s path for the location, which will be an empty string if there is no path.
This variable is a string containing a ‘?’ followed by the parameters of the URL. In CYPEX this is also an object containing arguments.
This object represents the current page of the application.
Identifier of the current page.
Date and time of the last page load.
Elements is an object which contains all elements located on the current page. To access the element selector, the element identifier should be picked from the list, e.g., elements.<element_id>.
Here’s an example showing all element names on the page. Mind that there is tab-completion at work. Simple type “elements” and CYPEX will immediately display all variables inside the object:

The interface of the element itself. It can be used in the custom expression field for the current scope of the element. For example: element.value
An object containing translated texts in the current language, e.g., title, label, etc. for this element.
The properties passed down by the parent element, for example, table or form, so their child elements will have access to props.data (= variable containing data elements).
A modern JavaScript utility library delivering modularity and performance can be used inside the “Custom Expression” editor.
Check out Lodash for more information.
Server data can be filtered by any element selector value.
Advanced filters might look like this:
{
"combinator": "AND",
"filters": []
}
It uses the selected table row value as a column to filter.
Syntax: elements.<table_id>.selected.row.<column_name>.
To create advanced filters, CYPEX uses PostgREST, so the filters array must contain a collection of possible combinations like:
{
field: <column_name>,
operator: "eq",
value: elements.<table_id>.selected.row.<column_name>
}
The following image contains a real-world example:

Values will be returned as strings.
The full list of PostgREST filters can be found here: https://postgrest.org/en/stable/api.html?highlight=operators#operators
A scripting or programming language, running inside the web-browser that allows you to implement complex display logic and features for websites.
The web reference for JavaScript: https://developer.mozilla.org/en-US/docs/Web/JavaScript
The following listing contains a little cheat sheet for your daily work:
500 number
"Star Wars" string
true boolean
[1, 2, 3] array
{success: "green", error: "red"} object
100 (+ - * / ) 2.5 types of calculation
"Star " + "Wars" string concatenation
true && || false opperators
6 / 2 == 3
1 > 2 ? "success" : "error"
"Han Solo".endsWith("o")
You can use all modern JavaScript features available in your browser:
"Luke Skywalker".split(" ")
["Luke", "Leia"][0]
{success: "green", error: "red"}["green"]
Object.keys({foo: 1, bar: 2})
({data:null}).data?.value
null ?? "fallback"
`${5 * 4} years old`
props.data["first_name"]
props.data["created_at"]
props.data["Name with non-alphanumeric characters!"]
This can be used in a json field to visualize the whole row at once
props.data
element.data
element.value
elements["some_markdown_field"].text
elements["some_table"].data
data.props["name"]
i18n.text
location.query.identifier
page.loadedAt
In one of the previous sections, you learned that there are actually two ways to resolve ID’s in a relational model: a.) use queries and joins or b.) fix things on the client side, using expressions. The beauty of expressions is that they’re usually far easier to handle, since you don’t have to touch the database at all. However, you also need to keep an eye on performance. Depending on your situation, one or the other might result in faster performance.
All examples shown in this tutorial so far rely on the fact that elements have always been shown - regardless of the the situation on the page and the data displayed. In reality this isn’t always the case. Sometimes it’s necessary to show elements only in certain situations.
What are some examples of this? Suppose you only want to display an image in case some checkbox is ticked. Or maybe you want to display a button, but only when some fields are filled out. There are countless scenarios where you need conditional elements.
CYPEX supports the notion of a conditional container. What that means is that it’s possible to use a condition to display a group of elements which depend on that condition.
Let’s see how it works and see how to hide a button. The goal is: the “Edit” button should only be visible if a value in a dropdown has been selected. If there’s no value, the button should be hidden.
The way to do that is by adding a “Conditional Container” element to the GUI. The elements you want to show / hide can then be added to this element. Then you need to assign a JavaScript expression to the element. In case it returns true, everything is visible:

However, if this expression does not return true, but false, the elements in the container will be hidden from view. The advantage is that you can basically access all elements on the page and use those values to control this kind of behavior.
Before you take a look at the expression you need to put into the “Show content field”, you can see what the desired output looks like:

No value has been selected and therefore the button is hidden. As soon as you select a value, the button will be displayed:

Let’s take a look at the JavaScript expression you’ll need:
!!elements.default_autocomplete_input_2bedb141.value
This expression is sure to return true or false. But what does it actually mean? You can access all elements on the screen (“elements”). Every element on the page will automatically have a name. In this case CYPEX decided to call the element “default_autocomplete_input_2bedb141” (check the name of the element in the configuration window). Then you can access the value of this element. If it’s there it returns true - if it isn’t there, it returns false.
Almost any level of complexity is allowed here. All you have to do is to produce “true” or “false” to tell the container what to do.
The following examples show how you can make use of variables, and access fields and information using the graphical editor.
element. itself or elements.<data_dispaly_id>.
color: Access to element color, specified below.
Access to the element data if “Query name“ is set as a data source. Depending on the configuration mode, the data can be an object or an array.
For the mode “First Row“ is element.data an object.
For the mode “All Data“, element.data[ ] is an array, use element index access to specific record e.g.
Since this element fetches data by the “Query“ name, the error message is accessible if the request fails.
Get the value of the preformatted data, e.g.,

Returns identifier value if it’s set in the configuration.

element.loading
Boolean value. Indicates if the data is in the process of being loaded from the server.
This section describes internationalization and multi-language support.
Returns a string containing the current translated label.

i18n.text or elements.<markdown_text_id>.i18n.text
Translated texts in the current language, returned by markdown editor.

Let’s focus on configuration parameters available to control charts.
element or elements.<chart_id>.

An array of records, server data fetched by “Query “ name.
Returns the error message if the request fails.
The boolean value indicates if the data is in the process of being loaded from the server.
Returns selected object(record) if selection in chart configuration is enabled.
Returns a string that’s translated into the current language “Title“.
Tables also support custom expressions. This section describes which features are available and what can be done to make this important GUI element more powerful.
element. or elements.<table_id>.

Server data, fetch by setting the proper “Query Name“.
Returns an error message if the request fails.
The number of rows per page.
The boolean value indicates if the data is in the process of being loaded from the server.
A partisan object of the params set during data loading.

An object of advanced table filters, if it exists.
The number of max rows can be fetched.
The number of rows to skip before beginning to return rows.
An optional array of objects like:
{
fieldName: string;
asc: boolean;
hidden?: boolean;
}

A boolean value, returns a value indicating if the user has sufficient permissions to delete records.
A boolean value, returns a value indicating if the user has sufficient permission to update records.
Metadata related to each row / record where the property is a row key;

element.metadata.rows[0].canDelete and canUpdate
Specify permission for the current row.
Translation object generated on the server during table creation.
.short_desc: string
.title: string
.long_desc: string
An array of objects with possible workflows:
{
to: string, // workflow value
i18n: object // translation object, e.g., { title: string }
}
Is a column name which contains workflow values.
This is an advanced option. An object of advanced table filters is a filter object which can be fetched while the user is about to build the filter. You will need this to quickly preview output.
Is a boolean value that shows if the last page has already been fetched or not.
Same as in loadingParams. The only difference is that these values can be configured in the element editor.
Has the same definition as order, but is used as a helper for column sorting.
Also contains filter, limit, offset, and the order specified in the URL to fetch table data.
An object of joined tables (referenced table), if such tables exist (they do exist in case you use “default resolution” in the model builder). This configuration can be found in the “References“ section of the table editor:

Each property or value is accessible in the “Custom Expression“ editor. The property name is a referenced column name (see image)

and the value is an object: .viewName: string (viewName: is the name of a joined table) .identifierName: string (identifierName: is the joined table identifier)
Access to the value of the table search input:

Example: element.searchInputValue = "Dell"
For tables with “Selection“ enabled selected value can be used as an expression:

To get data of the whole table row, even to columns that aren’t displayed in the table but natively present in the “Query“, the following syntax should be used:
elements.<table_id>.selected.row.<column_name>
or for usage inside the element itself
element.selected.row.<column_name>
For example, to use the column “Name“ as a title for another element, which uses the “Custom Expression“ editor:

**Note: **If “First row selected“ isn’t enabled and the row wasn’t clicked, it means the selected object is empty. In this situation, use “?”
which is a JavaScript operator to avoid errors if no value exists:
elements.<table_id>.selected?.row?.<column_name> ?? "Default Value"
“Default Value“ can also be an empty string.
In the current version of CYPEX, table columns are elements but without external access. It’s impossible to get a column value inside the “Custom Expression“ editor used by any other element on the page. However, every column type has access to the table data through the props key.
Here’s an example:

To get the data of a column inside the props objects, use the following syntax: props.data["remote"]. In this case you access the column called “remote” and fetch the idea. The Boolean() method will ensure that the value is neither null nor undefined.
Use “Custom expressions” to format the string or to adjust the output according to your needs. It’s also possible to pick the necessary column using autocomplete inside the “Text Field“, if adjustments aren’t required.

The props object is one of the most fundamental building blocks of the “Custom expressions” machinery. It contains all object-related data, keys, metadata as well as references. It’s the single most important object you must understand when working with CYPEX expressions in general:

Row data object.
Row index.
Row metadata passed through from the table element

Are boolean values defining whether the user has permission to delete or update?
Only the parent table has any of the references(joined tables) configured; it’s possible to get those references using the following method:

Specifies the source column in this example.
Keep in mind the whole referenced row will be returned as a value. Use autocomplete to select the desired field or use a JavaScript expression to access various fields as needed:

To get any value from the referenced row, just pick the desired column names.
Let’s focus our attention on forms which need special infrastructure to work properly. The following variables exist in this context.
element. or elements.<form_id>

Server data, fetch by setting the proper “Query Name“.
Note: The Form data object also has access to values referenced, if the form has any joined (referenced) queries.

An example: To get the value of “manufacturers“, use the following syntax:
element.<form_id>.data.manufacturers
In this example, the manufacturer’s column does not exist in a query that belongs to the form, but this value was joined by configuring “Form“ references.
An object of possible server errors, available only if errors exist.
Is a boolean value. The value is “true” in case the form has been changed.
String or number required for identifying a record in the form with type “Edit“ or “Detail“.
Is a boolean value that describes if the form is valid or not.
These are both objects which look as follows:
{
inProgress: boolean;
error: string | { message: string }
}
Shows whether save or load action is in process. It contains “error” in case the request is failing or has failed. An error message is provided.
Initially fetched data. The original copy of the data is preserved until the form is submitted, so that you can always ensure that the changes can be reverted back to what was stored before.
Boolean value shows if the user has touched any form input.
element. or elements.<conditional_container_id>

Boolean value. Since “Conditional Containers“ serve to display elements conditionally, depending on whether “visible” is set to “true” or “false”. In CYPEX the visibility of an element on a page can be turned on and off.
Note: To toggle an element’s visibility inside a “Conditional Container“ use the configuration value of other components such as “Boolean Input“ elements on the same page.
elements.<boolean_input_id>.value
element. or elements.<tabs_id>

Returns a number (index) of the active tab.
All inputs in CYPEX are accessible, like elements. or elements.<input_id>
Returns a value depending on the input type, e.g., “Number Input“ has an integer value, “Text Input“ a string, and so on.
A boolean value indicating whether the input is read-only or not.
Shows if the user interacted with the current input.
Optional key. Contains form data validation errors.
Note: Controlled Inputs
All inputs inside the form are controlled by the form they belong to.
The “Data Source” section is the place to go to get the data from the parent form.
For example:

Where “Element Id“ is a parent form element ID. “Field Path“ wanted the column to be displayed.
So, the default value of the controlled input is “Form” data passed through the input props.

Is a boolean value that shows if option fetching is in process.
Is an array of options, each option is an object. Here’s an example:
{
value: string | number;
label: string;
}
Server error if fetching options fails.
An array. The row data fetched if “Options Source“ is a query.
An object. The data containing the selected row.
A string. The user input holding the value you are searching for.
If value is selected, the value of the object is simliar to how it is in the the following example:
{ value: string | number; label: string } is accessible.

Access to uploaded files.
Is a boolean value that shows if the file is currently uploading.
An object, uploaded file metadata:
{
"hash": string;
"fileName": string;
"realName": string;
"fileType": string; // e.g., "image/png"
"fileGroup": {
"id": string;
"name": string;
// e.g., "public" | "private",
"acl": string[];
// array of strings (roles),
// permissions for file group, e.g., ["cypex_admin"]
},
"typeGroup": {
"id": string;
"typeName": string; // e.g., "image"
},
"acl": string[]; // array of strings (roles), permissions for file, e.g., ["cypex_admin"],
"id": string;
}
A string error message.
This value is a string error message, defined in case uploading fails.

Access to an array of uploaded files.
Same as for the single file, but an array of metadata objects.
Subform tables serve mostly as form input, in the case of “References“ are configured (at least one). So “Subform table“ can update joined tables, used for 1:n relations during data editing. Subforms used as input have the same input properties mentioned above, but the value is an array of objects (joined table data). The syntax to get those values is as follows: elements.<sub_form_table_id>.value returns Array<object>.
Various elements in CYPEX are accessible as shown in the following listing:
element. or elements.<input_id>
In this section you’ll learn how custom expressions can help to make maps in CYPEX better.
An array of markers, markers are objects:
{
lat: number; // latitude
lng: number; // longitude
name: string;
}
Is a boolean value indicating if data is loading or not.
Error message in case data load fails.
Returns marker (check the type above) object, only if any is selected by the user.

Number of times the button was clicked.
A date type, last time the button was clicked.

An error message in case the function call fails.
A boolean value. Indicates if the function is being called right now.
The result of a function call.

In order to have access to data objects a “Data Source“ is required. In this case, data will be a record (table row). You have access to the data as well as to identifiers and status-related information.
Error message in case a request fails.
A boolean value, indicates if data has started loading.
String or number, in case the identifier was set in the “Data Source“ section.
Boolean value, if loading currently in process.
value: a number, field value.
Browse Documentation by Topic: