Cloud Canal logo
CoreClientsConnectComponentsContent
Log In
Dashboard

Connect

Heading
Heading
Heading

Overview

Transform your web development process with Cloud Canal Connect, a free, low-code framework for building web apps. Designed for Webflow but versatile enough for any platform, Cloud Canal Connect transforms static sites into dynamic experiences, supercharging your projects with interactive features.

The entire library is packed with features and weighs in at around 9 kB over our CDN (compressed)!

Philosophy

Cloud Canal Connect operates on one simple principle: when this happens, do that. It handles a wide range of website events—from page loads to button clicks. Want to fetch data from an API or execute a calculation when an event occurs? Cloud Canal makes it easy with four core components:

  • Events: Trigger actions based on user interactions, API calls, or form submissions.
  • Actions: Implement a variety of steps, like updating a table, which can be linked in sequence.
  • Transformers: Modify values through operations such as arithmetic, comparisons, or formatting.
  • Parameters: Access dynamic data such as query parameters, variables, or API responses.

How it Works

Quickly integrate Cloud Canal Connect into your site by adding the script snippet to the head. Then, bring elements to life with custom attributes that capture user interactions. These attributes act as event triggers, setting off one or more actions seamlessly.

Use Cases

Cloud Canal's flexibility supports a wide array of applications, limited only by your imagination. Ideal for creating advanced Webflow projects, it’s perfect for:

  • SaaS applications
  • Marketplaces
  • Job boards
  • Learning platforms
  • Online communities

...And much more. Let's unleash your creativity and build the next big thing with Cloud Canal Connect. If you're looking for a back end solution to integrate with, we highly recommend Core.

Getting Started

You can add Cloud Canal Connect to any webpage by including the snippet below in the <head> element. If you're using Webflow, we recommend applying it across your site via project settings.

<script src="https://cdn.jsdelivr.net/npm/@cloud-canal/cloud-canal@3.27.3" defer></script><style>  :root {    --cc-load-visibility: hidden;  }  :where([data-cc-hidden-until-load="true"]) {    visibility: var(--cc-load-visibility);  }</style><script>  window.cloudCanalInit = window.cloudCanalInit || [];  window.cloudCanalInit.push(() => {    window.cloudCanal.api.setVariable('baseURL', '[Replace URL]');  });</script>

Once added, you can start using all of the components in this library. Note that the styles above are for the "Hidden Until Load" component to work properly. The script to push a "baseURL" is optional, but makes it significantly easier to port a project to a different backend if the URL ever changes. It is mandatory for projects using CC Components. The format should be like "https://www.example.com", including the "https".

Browser Extension

You can optionally install our free Chrome extension to make working with Cloud Canal in Webflow even easier. It let you test Cloud Canal attributes in the Webflow Designer's Preview mode, without having to publish changes first.

General

These components can be used across your site in combination with other Cloud Canal Connect features.

Form

These attributes apply to forms and their children and can be used to add settings or additional functionality to them.

False Values

When a form is serialized, any unchecked checkboxes do not have their value appended by default. You can optionally specify a value to append instead by putting this attribute on the input.

Attribute:

data-cc-false-value="[value]"

Ignore Submit

Form fields without names are automatically omitted from serialization. For greater control, you can specify that a field should always be ignored or ignored if empty.

Attribute:

data-cc-ignore-submit="always|empty"

Filter Match

Applies only to form serialization for Cloud Canal Core filtering and must be placed on input, select, or textarea elements. Dictates how multiple filters with the same name should be combined (defaults to "or").

Attribute:

data-cc-filter-match="and|or"

Example: a value of "and" in the attribute will result in values being combined with "&&"

(title ~ "foo" && title ~ "bar")

Example: a value of "or" in the attribute will result in values being combined with "||"

(title ~ "foo" || title ~ "bar")

Filter Operator

Applies only to form serialization for Cloud Canal Core filtering and must be placed on input, select, or textarea elements. Dictates how each filter will compare its value to the data. Possible options include:

= Equal (default)
‍!= NOT equal
‍> Greater than
‍>= Greater than or equal
‍< Less than
‍<= Less than or equal
‍~ Like/Contains (if not specified auto wraps the right string OPERAND in a "%" for wildcard match)
‍!~ NOT Like/Contains (if not specified auto wraps the right string OPERAND in a "%" for wildcard match)
‍?= Any/At least one of Equal
‍?!= Any/At least one of NOT equal
‍?> Any/At least one of Greater than
‍?>= Any/At least one of Greater than or equal
‍?< Any/At least one of Less than
‍?<= Any/At least one of Less than or equal
‍?~ Any/At least one of Like/Contains (if not specified auto wraps the right string OPERAND in a "%" for wildcard match)
‍?!~ Any/At least one of NOT Like/Contains (if not specified auto wraps the right string OPERAND in a "%" for wildcard match)

Attribute:

data-cc-filter-operator="[operator]"

Example: a value of "<=" in the attribute on an input named "mileage" will result in the filter below when the value is "20000"

mileage <= 20000

Filter Type

Applies only to form serialization for Cloud Canal Core filtering and must be placed on input, select, or textarea elements. Dictates the type of data that the value of the input represents. If absent, Connect will attempt to automatically determine the default based on the value of the input. For example, a "text" input in which the user types "123" will be treated as a number by default, not a string. Note that a "literal" can be something like a field name in Core; essentially a string without the wrapping quotation marks.

Attribute:

data-cc-filter-type="string|literal|number|boolean"

Example: a value of "boolean" in the attribute on a checkbox named "mailing_list" will result in the filter below when it is checked (this would also be the default behavior if you give the checkbox a "value" of "true", since Connect will automatically convert it to a boolean)

mailing_list = true

Join Separator

By default, when there are multiple inputs with the same "name", form serialization will either only take the final key/value pair (when serializing to "application/json") or add all key/value pairs separately (all other scenarios). You can specify an optional join separator on each input to let Connect know that if a value already exists for that field, add this one to it (separated by the provided separator).

Attribute:

data-cc-join-separator="[separator]"

Example: a value of "," in the attribute on multiple inputs named "feature" will result in the values being combined as below

feature=foo,bar,baz

Without the attribute, the data would be serialized with the values separate

feature=foo&feature=bar&feature=baz

Miscellaneous

The following components don't fit into any other category but are important for various utility cases.

Comment

You can leave comments across your project to explain what you're doing with various attributes on the element. Note that anything you write in these comments can be seen by anyone inspecting your HTML, so avoid any sensitive information.

Attribute:

data-cc-comment="[comment]"

Group

Often, it may be beneficial to separate sequences of actions into groups for organizational purposes. Many actions also must refer to groups in their fields, like "If" or "For Each". Each group gets its own attribute and must be referred to by name.

Attribute:

data-cc-group-[name]="[action(s)]"

Example: the attribute below can be executed by the action "group::populate" on the same element

data-cc-group-populate="[action(s)]"

Hidden Until Load

To prevent a flash of an uninitialized view of your page before all the "Load" events have fired, you can hide specific elements (or even the whole body). Any element with this attribute will become visible only after all of the "Load" events have been executed. Any value other than "true" will not hide the element.

Attribute:

data-cc-hidden-until-load="true"

Prevent Default

Many elements like forms and buttons have default behaviors in the browser. You can prevent these from happening with this attribute in favor of using an event attribute to handle the functionality instead.

The value of this attribute can be an asterisk, meaning it applies to all events, or a comma-separated list of specific events.

Attribute:

data-cc-prevent-default="* | [event(s)]"

Example: when submitting the form, prevent the default submit and reset behaviors (which would then be coupled with "data-cc-on-submit" and "data-cc-on-reset" attributes to add your own handling)

<form data-cc-prevent-default="submit,reset">...</form>

Events

Cloud Canal Connect supports a ton of events right out of the box through the use of custom attributes. Once triggered, the actions inside the attribute's value will be executed sequentially. The data passed in the "Data" parameter is context-specific and will change based on the type of event.

DOM

These events trigger when changes happen to the Document Object Model (i.e. the page).

Insert

Trigger: element added to page

Applicable elements: any

Attribute:

data-cc-on-insert="[action(s)]"

Data parameter: standard MutationRecord object

Instantiate

Trigger: element added to page using "Instantiate" action

Applicable elements: any

Attribute:

data-cc-on-instantiate="[action(s)]"

Data parameter: inherited from wherever "Instantiate" action is executed

Load

Trigger: DOM is ready and library has finished loading

Applicable elements: any

Attribute:

data-cc-on-load="[action(s)]"

Data parameter: standard Event object

Load (Complete)

Trigger: page has completely loaded, along with stylesheets and images

Applicable elements: any

Attribute:

data-cc-on-loadcomplete="[action(s)]"

Data parameter: standard Event object

Load (Logged In)

Trigger: DOM is ready, library has finished loading, and user is currently logged in using the Cloud Canal authentication system

Applicable elements: any

Attribute:

data-cc-on-loadloggedin="[action(s)]"

Data parameter: standard Event object

Load (Logged Out)

Trigger: DOM is ready, library has finished loading, and user is not currently logged in using the Cloud Canal authentication system

Applicable elements: any

Attribute:

data-cc-on-loadloggedout="[action(s)]"

Data parameter: standard Event object

Preload

Trigger: fires right before the "Load" event

Warning: this event usually isn't the one you want (use "Load" instead); the main use case for this event is for creating components that need to be initialized in some way before being used in "Load" events and elsewhere

Applicable elements: any

Attribute:

data-cc-on-preload="[action(s)]"

Data parameter: standard Event object

Remove

Trigger: element removed from page

Applicable elements: any

Attribute:

data-cc-on-remove="[action(s)]"

Data parameter: standard MutationRecord object

Tab

Trigger: tab component's page is changed using "tab" action

Applicable elements: any

Attribute:

data-cc-on-tab-[id]="[action(s)]"

Data parameter:‍

{  index,  previous}

HTTP

These events trigger at various stages of the HTTP requests executed by the "API" action. They are arranged here based on the order in which they are called, with "Start" coming first and "Finish" coming last.

Start

Trigger: request begins

Applicable elements: same element that is triggering the request using the "API" action

Attribute:

data-cc-on-httpstart="[action(s)]"

Data parameter:

{  url,  request: {    method,    headers,    body,    mode  }}

Status Code

Trigger: request completes with status code specified (highest priority)

Applicable elements: same element that is triggering the request using the "API" action

Attribute:

data-cc-on-http[code]="[action(s)]"

Data parameter:

{  url,  request: {    method,    headers,    body,    mode  },  response: {    status,    headers,    body  }}

Example: the attribute below would be triggered when the response has a status code of 401

data-cc-on-http401="[action(s)]"

Success

Trigger: request succeeds with status code of 2XX

Applicable elements: same element that is triggering the request using the "API" action

Attribute:

data-cc-on-httpsuccess="[action(s)]"

Data parameter:

{  url,  request: {    method,    headers,    body,    mode  },  response: {    status,    headers,    body  }}

Error

Trigger: request fails with status code of 4XX or 5XX

Applicable elements: same element that is triggering the request using the "API" action

Attribute:

data-cc-on-httperror="[action(s)]"

Data parameter:

{  url,  request: {    method,    headers,    body,    mode  },  response: {    status,    headers,    body  }}

Finish

Trigger: request triggered with "API" action completes, regardless of status (lowest priority)

Applicable elements: same element that is triggering the request using the "API" action

Attribute:

data-cc-on-httpfinish="[action(s)]"

Data parameter:

{  url,  request: {    method,    headers,    body,    mode  },  response: {    status,    headers,    body  }}

User

These events trigger when the user performs an action.

Blur

Trigger: element loses focus

Applicable elements: focusable elements like inputs, textareas, selects, anchors, and buttons

Attribute:

data-cc-on-blur="[action(s)]"

Data parameter: standard Event object

Change

Trigger: element has value changed and loses focus

Applicable elements: inputs, selects, and textareas

Attribute:

data-cc-on-change="[action(s)]"

Data parameter: standard Event object

Click

Trigger: user clicks/taps element

Applicable elements: any

Attribute:

data-cc-on-click="[action(s)]"

Data parameter: standard Event object

Focus

Trigger: element gains focus

Applicable elements: focusable elements like inputs, textareas, selects, anchors, and buttons

Attribute:

data-cc-on-focus="[action(s)]"

Data parameter: standard Event object

Input

Trigger: element has value changed

Applicable elements: inputs, selects, and textareas

Attribute:

data-cc-on-input="[action(s)]"

Data parameter: standard Event object

Key Down

Trigger: user presses a key on the keyboard

Applicable elements: any

Attribute:

data-cc-on-keydown="[action(s)]"

Data parameter: standard Event object

Key Up

Trigger: user releases a key on the keyboard

Applicable elements: any

Attribute:

data-cc-on-keyup="[action(s)]"

Data parameter: standard Event object

Mouse Out

Trigger: user's mouse moves off element

Applicable elements: any

Attribute:

data-cc-on-mouseout="[action(s)]"

Data parameter: standard Event object

Mouse Over

Trigger: user's mouse moves onto element

Applicable elements: any

Attribute:

data-cc-on-mouseover="[action(s)]"

Data parameter: standard Event object

Reset

Trigger: form element reset

Applicable elements: forms

Attribute:

data-cc-on-reset="[action(s)]"

Data parameter: standard Event object

Submit

Trigger: form element submitted

Applicable elements: forms

Attribute:

data-cc-on-submit="[action(s)]"

Data parameter: standard Event object

Custom

You can emit and listen for your own custom events if you need even more control.

Emit

Trigger: manually using "Emit" action

Applicable elements: any

Attribute:

data-cc-on-[event]="[action(s)]"

Data parameter: dependent on the second field of the "Emit" action

Example: the attribute below would be triggered elsewhere with the action "emit::increment::123" with the "Data" parameter set to "123"

data-cc-on-increment="[action(s)]"

Update

Trigger: variable updated using "Set Variable", "Remove Variable", or "Clear Variables" actions

Applicable elements: any

Attribute:

data-cc-on-update-[variable]="[action(s)]"

Data parameter:

{  name,  value,  scope}

Example: the attribute below would be triggered when a variable called "name" is updated

data-cc-on-update-name="[action(s)]"

Actions

Actions are bits of functionality (similar to methods or functions in programming) that can do a wide range of things without resorting to coding. They are strung together in the value of an event attribute, such that when that event is triggered, the actions fire off in sequence. You can include multiple actions in an event attribute by separating them with double semicolons (;;).

Some actions have a "slot", which is placed in brackets right after the name of the action. Any remaining inputs are referred to as "fields". Slots and fields with an asterisk are required, while others are optional. When omitting a variable in an action's slot, you also omit the brackets. Actions with optional selectors will operate on the current element if the selector is omitted. Field order matters, so if you want to include a value for a field, you'll have to make sure that all fields up to that point have a value as well.

App

These actions are core to the Cloud Canal Connect experience and govern the sending & receiving of data.

API

Function: Make an API call to an endpoint; if executed from a form, the form fields will be sent as application/json in the body as long as the method is not GET or HEAD. If the form contains a file input, the data will be sent as multipart/form-data instead. If executed on a form and the method is GET or HEAD, the form fields will be sent as query parameters in the URL (file inputs are not allowed in this case).

If using Cloud Canal's authentication system, you can set auth to true in order to send the token along with the request. You can optionally pass any additional headers with the request in the last parameter.

Applicable elements: any, but especially forms

Signature:

api([loader])::[url*]::[method]::[auth]::[header(s)]

Slot & Fields:

NameRequiredTypeDefaultDescription
loaderNoselector-Select any loader element(s) that will be shown when the request begins and hidden when it finishes
urlYestext-The URL of the endpoint to send the request to
methodNotextGETThe request method to use (GET, POST, PUT, etc.)
authNobooleantrueWhether to use Cloud Canal's authentication system
header(s)Notext-A comma-separated list of additional headers to set, ex. "X-Foo:123,X-Bar:456"

Example: When the form is submitted, POST the data in the form to "https://www.example.com/articles"

<form  data-cc-on-submit="api::https://www.example.com/articles::POST"  data-cc-prevent-default="submit">...</form>

Bind

Function: Link an aspect of an element on the page to a variable depending on the "type" field. Binding text will make the text of the element automatically update whenever the bound variable changes. Binding value produces a two-way link that will update the value of the element when the variable changes, and will also update the variable when the value of the input changes. Binding a form is shorthand for binding all input elements within.

Binding arrays will instantiate a copy of that element and its children for each element of the array in the variable. You can use the "data-cc-on-instantiate" attribute to then populate the element. In this case, the "data" parameter will be set to the current array item.

If "type" is anything other than the options above, then the variable will be bound to a custom attribute on the element(s) with the name of the "type" field.

Applicable elements: any element that can have text content when type is "text"; input, select, and textarea elements when type is "value"; a form or wrapping element when type is "form"; any element when type is "array" or anything else

Signature:

bind([selector])::[type*]::[key*]::[scope]

Slot & Fields:

NameRequiredTypeDefaultDescription
selectorNoselector-Select any element(s) that will be bound (if omitted, applies to current element)
typeYestext-Which kind of binding to use (options: text, value, checked, form, array); if type is not one of the options, the value will be bound to a custom attribute with this name
keyYestext-The name of the variable to bind to
scopeNotextwindowWhich scope of variable to bind to (options: window, session, local)

Example: bind the value of an input to a variable called "age" as soon as the page loads (the name of the input does not affect this, but make sure the input type and variable data are compatible)

<input  data-cc-on-load="bind::value::age"  name="user_age"  type="number"/>

Example: bind a custom attribute called "data-cust-attr" to a variable called "my-var"

<div data-cc-on-load="bind::data-cust-attr::my-var"></div>

Example: bind the element to an array stored in a session variable called "notes" on page load and populate some data in the element (the variable must be an array);  "notes" has the following structure in this example:

[  {    id,    title,    body  }, ...]
<div data-cc-on-load="bind::array::notes::session">  <div data-cc-on-instantiate="text::{{data::id}}. {{data::title}}"></div>  <p data-cc-on-instantiate="text::{{data::body}}"></p></div>

Emit

Function: triggers all elements on the page listening for the emitted event by name; the event can be a built-in event from Cloud Canal Connect like "click" or a custom one specific to your application

Applicable elements: any

Signature:

emit::[event*]::[data]

Fields:

NameRequiredTypeDefaultDescription
eventYestext-The name of the event to emit
dataNoany-Optional data to pass as the "data" parameter in triggered attributes

Example: when the input below has its value changed, it will emit a custom "renamed" event with the value of the input as the "data" parameter; other elements can listen for it with an attribute of "data-cc-on-renamed"

<input  data-cc-on-change="emit::renamed::{{value}}"  name="username"  type="text"/>

Trigger

Function: triggers the given event only on the matched elements (or the calling element if the selector is omitted); the value of the "data" parameter in the triggered attribute is inherited from wherever this action is executed

Applicable elements: any

Signature:

trigger([selector])::[event*]

Slot & Fields:

NameRequiredTypeDefaultDescription
selectorNoselector-Select any element(s) that will have the event triggered on them (if omitted, applies to current element)
eventYestext-The name of the event to emit

Example: when the first button below is clicked, it will mirror the click to the second button

<button data-cc-on-click="trigger(#other-button)::click">First Button</button><button id="other-button">Second Button</button>

Attributes

These actions relate to attributes on elements.

Assign Id

Function: assigns a random UUID as the id of the element if it does not already have one

Applicable elements: any

Signature:

assignId

Example: on page load, assign an id to the button if it does not have one

<button data-cc-on-load="assignId">Begin</button>

Set Attribute

Function: add or update the attribute with the given name on the matched element(s)

Applicable elements: any

Signature:

setAttribute([selector])::[name*]::[value]

Slot & Fields:

NameRequiredTypeDefaultDescription
selectorNoselector-Select any element(s) that will have the attribute set (if omitted, applies to current element)
nameYestext-The name of the attribute
valueNoany-The value to set (if omitted, will set a boolean attribute)

Example: when the page loads, set an attribute on the div of data-foo="bar"

<div data-cc-on-load="setAttribute::data-foo::bar"></div>

Remove Attribute

Function: remove the attribute with the given name on the matched element(s)

Applicable elements: any

Signature:

removeAttribute([selector])::[name*]

Slot & Fields:

NameRequiredTypeDefaultDescription
selectorNoselector-Select any element(s) that will have the attribute set (if omitted, applies to current element)
nameYestext-The name of the attribute

Example: when the user mouses over the div, remove the "data-foo" attribute from it

<div data-cc-on-mouseover="removeAttribute::data-foo" data-foo="bar"></div>

Auth

These actions relate to Cloud Canal Connect's built-in authentication system, allowing easy integration with your back end of choice.

Set Auth

Function: save the token to a cookie called "cc-auth"; it will be sent in an authorization header as a bearer token automatically whenever using the "API" action with its "auth" field set to true

Applicable elements: any, but especially login/registration forms

Signature:

setAuth::[token*]::[expiration]

Fields:

NameRequiredTypeDefaultDescription
tokenYestext-The token to save (usually from the successful response of a login or signup request)
expirationNonumber-The lifetime of the cookie in seconds, up to 7 days max due to browser constraints (if omitted, will last for the duration of the session)

Example: when the request completes successfully, set the token from the response body (assuming the response has the token under a key of "authToken") and make it valid for 1 day; then, navigate to the relative url  "/dashboard"

<form  data-cc-on-submit="api::https://www.example.com/login::POST"  data-cc-on-httpsuccess="setAuth::{{response::authToken}}::86400;;navigate::/dashboard"  data-cc-prevent-default="submit">...</form>

Clear Auth

Function: delete the "cc-auth" cookie from the browser, logging the user out on the front end

Applicable elements: any, but especially logout buttons

Signature:

clearAuth

Example: when the button is clicked, clear the authentication token from the user's cookies and navigate back to the home page

<button data-cc-on-click="clearAuth;;navigate::/">Logout</button>

Classes

These actions relate to classes in the browser.

Add Class

Function: add the class to the matched element(s) if they don't already have it

Applicable elements: any

Signature:

addClass([selector])::[name*]

Slot & Fields:

NameRequiredTypeDefaultDescription
selectorNoselector-Select any element(s) that will have the class set (if omitted, applies to current element)
nameYestext-The name of the class

Example: when moused over, add the "is-hovered" class to the div

<div data-cc-on-mouseover="addClass::is-hovered"></div>

Remove Class

Function: remove the class from the matched element(s) if they have it

Applicable elements: any

Signature:

removeClass([selector])::[name*]

Slot & Fields:

NameRequiredTypeDefaultDescription
selectorNoselector-Select any element(s) that will have the class removed (if omitted, applies to current element)
nameYestext-The name of the class

Example: when moused out, remove the "is-hovered" class from the div

<div data-cc-on-mouseout="removeClass::is-hovered"></div>

Toggle Class

Function: toggle the class from the matched element(s), adding it if they don't have it and removing it if they do

Applicable elements: any

Signature:

toggleClass([selector])::[name*]

Slot & Fields:

NameRequiredTypeDefaultDescription
selectorNoselector-Select any element(s) that will have the class toggled (if omitted, applies to current element)
nameYestext-The name of the class

Example: when clicked, toggle the "active" class on the div

<div data-cc-on-click="toggleClass::active"></div>

Cookies

These actions relate to cookies in the browser.

Set Cookie

Function: add or update a cookie in the user's browser

Applicable elements: any

Signature:

setCookie::[key*]::[value*]::[expiration]

Fields:

NameRequiredTypeDefaultDescription
keyYestext-The name of the cookie
valueYesany-The value to store in the cookie
expirationNonumber-The lifetime of the cookie in seconds, up to 7 days max due to browser constraints (if omitted, will last for the duration of the session)

Example: on page load, make an authenticated API request and save the id from the response to a session cookie called "user-id"

<body  data-cc-on-load="api::https://www.example.com/me::GET::true"  data-cc-on-httpsuccess="setCookie::user-id::{{response::id}}">...</body>

Remove Cookie

Function: delete a cookie in the user's browser

Applicable elements: any

Signature:

removeCookie::[key*]

Fields:

NameRequiredTypeDefaultDescription
keyYestext-The name of the cookie

Example: on button click, delete a cookie called "user-id"

<button data-cc-on-click="removeCookie::user-id">Forget User ID</button>

Clear Cookies

Function: delete all code-accessible cookies in the user's browser (for the current site); note that if you've used the "Set Auth" action, its cookie will be deleted as well

Applicable elements: any

Signature:

clearCookies

Example: on button click, delete all cookies

<button data-cc-on-click="clearCookies">Clear Cookies</button>

Instances

These actions relate to templates and instances of them.

Template

Function: transform the element into a template, moving it to the head of the page; this action can only target a single element

Applicable elements: any

Signature:

template([selector])::[id*]

Slot & Fields:

NameRequiredTypeDefaultDescription
selectorNoselector-Select the FIRST matched element that will become the template (if omitted, applies to current element)
idYestext-An identifier to associate with the template, used for instantiating it

Example: on page load, convert the div to a template with id "todo"; note the "data-cc-on-instantiate" attribute, which fires when the template is instantiated and can be used to populate it

<div data-cc-on-load="template::todo">  To do: <span data-cc-on-instantiate="text::{{data::task}}"></span></div>

Instantiate

Function: clone a template and insert the instance into a container element; the container can only be a single element

Applicable elements: any

Signature:

instantiate([container])::[id*]::[data]

Slot & Fields:

NameRequiredTypeDefaultDescription
containerNoselector-Select the FIRST matched element the instance will be appended to (if omitted, applies to current element)
idYestext-The identifier of the template to use
dataNoanyinheritedThe value to pass as the "data" parameter (if omitted, will be inherited from where this action is called)

Example: when the button is clicked, add an instance of the "note" template to the div with class "note-wrapper"

<button data-cc-on-click="instantiate(.note-wrapper)::note">Add Note</button><div class="note-wrapper"></div>

Remove Instance

Function: remove the selected element or closest ancestor using the specified template; this action can only target a single element

Applicable elements: any (on or inside of an instance)

Signature:

removeInstance([selector])::[id*]

Slot & Fields:

NameRequiredTypeDefaultDescription
selectorNoselector-Select the FIRST matched element from which to look for the instance (if omitted, applies to current element)
idYestext-The identifier of the template to target

Example: When the button inside the instance is clicked, remove the ancestor which was instantiated from the "note" template; note that the instances all have the "data-cc-on-load" attribute of the original template which can safely be ignored since the "Load" event would have already fired before instantiation. The "data-cc-template" attribute is used internally by Cloud Canal Connect to track instances and can also be ignored.

<div class="note-wrapper">  <div data-cc-on-load="template::note" data-cc-template="note">    <input type="text" />    <button data-cc-on-click="removeInstance::note">X</button>  </div>  <div data-cc-on-load="template::note" data-cc-template="note">    <input type="text" />    <button data-cc-on-click="removeInstance::note">X</button>  </div></div>

Clear Instances

Function: remove all instances of a specified template from the page

Applicable elements: any

Signature:

clearInstances::[id*]

Fields:

NameRequiredTypeDefaultDescription
idYestext-The identifier of the template to target

Example: when the button is clicked, remove all instances using the "note" template

<button data-cc-on-click="clearInstances::note">Reset</button><div class="note-wrapper">...</div>

Interface

These actions relate to various interactions with the UI.

Blur

Function: remove focus from the element(s)

Applicable elements: focusable elements like inputs or links

Signature:

blur([selector])

Slot:

NameRequiredTypeDefaultDescription
selectorNoselector-Select the matched element(s) to affect (if omitted, applies to current element)

Example: when the input is focused,  unfocus it after 5 seconds

<input data-cc-on-focus="wait::5;;blur" type="text" />

Check

Function: (un)check the element(s)

Applicable elements: radio and checkbox inputs

Signature:

check([selector])::[boolean]

Slot & Fields:

NameRequiredTypeDefaultDescription
selectorNoselector-Select the matched element(s) to affect (if omitted, applies to current element)
booleanNobooleantrueTrue to check the input and false to uncheck it

Example: when the page loads, check the checkbox

<input data-cc-on-load="check" type="checkbox" />

Click

Function: click (or tap) the element(s)

Applicable elements: any, but especially buttons and links

Signature:

click([selector])

Slot:

NameRequiredTypeDefaultDescription
selectorNoselector-Select the matched element(s) to affect (if omitted, applies to current element)

Example: when the first button is clicked, the second one is clicked as well

<button data-cc-on-click="click(.other-button)">Click Me</button><button class="other-button">I Get Clicked</button>

Copy

Function: copy the value to the user's clipboard

Applicable elements: any

Signature:

copy::[value*]::[type]

Fields:

NameRequiredTypeDefaultDescription
valueYesany-The data to copy to the clipboard
typeNotexttext/plainThe MIME type of the data to copy

Example: when the button is clicked, copy the text of the div to the clipboard

<button data-cc-on-click="copy::{{text(#secret-key)}}">Click To Copy</button><div id="secret-key">ABC123</div>

Disable

Function: disable the element(s)

Applicable elements: forms and form elements like inputs, selects, textareas and buttons

Signature:

disable([selector])

Slot:

NameRequiredTypeDefaultDescription
selectorNoselector-Select the matched element(s) to affect (if omitted, applies to current element)

Example: when the form is submitted, disable the inputs inside it

<form data-cc-on-submit="disable(:this input)">  <input name="username" type="text" />  <input name="password" type="password" /></form>

Disable Unloader

Function: disable a warning message when the user attempts to navigate away or close the browser tab (useful for warning of unsaved changes)

Applicable elements: any

Signature:

disableUnloader

Example: when the form is submitted, disable the unloader

<form data-cc-on-submit="disableUnloader">...</form>

Enable

Function: enable the element(s)

Applicable elements: forms and form elements like inputs, selects, textareas and buttons

Signature:

enable([selector])

Slot:

NameRequiredTypeDefaultDescription
selectorNoselector-Select the matched element(s) to affect (if omitted, applies to current element)

Example: As soon as a character is inputted into the first input below, the second will become enabled

<form>  <input name="username" type="text" data-cc-on-input="enable([type='password'])" />  <input name="password" type="password" disabled /></form>

Enable Unloader

Function: enable a warning message when the user attempts to navigate away or close the browser tab (useful for warning of unsaved changes)

Applicable elements: any

Signature:

enableUnloader

Example: when the input is changed, enable the unloader

<input name="memo" type="text" data-cc-on-change="enableUnloader" />

Focus

Function: focus the element(s); if multiple elements are matched then the last one will gain focus, but any "focus" events will fire for all of them

Applicable elements: focusable elements like inputs or links

Signature:

focus([selector])

Slot:

NameRequiredTypeDefaultDescription
selectorNoselector-Select the matched element(s) to affect (if omitted, applies to current element)

Example: when the button is clicked, focus the input

<button data-cc-on-click="focus(#message)">Start</button><input id="message" type="text" />

Hide

Function: hide the element(s) by setting their "display" property to "none"

Applicable elements: any

Signature:

hide([selector])

Slot:

NameRequiredTypeDefaultDescription
selectorNoselector-Select the matched element(s) to affect (if omitted, applies to current element)

Example: when the button is clicked, hide the div

<button data-cc-on-click="hide(#my-div)">Hide</button><div id="my-div">...</div>

HTML

Function: set the HTML of the element(s)

Warning: Setting the HTML directly can be dangerous if using data from an untrusted source, like user-generated content. Proceed with caution. If you just want to set the text of an element, use the "Text" action instead.

Applicable elements: any element that can contain children, like a div

Signature:

html([selector])::[value]

Slot & Fields:

NameRequiredTypeDefaultDescription
selectorNoselector-Select the matched element(s) to affect (if omitted, applies to current element)
valueNotext(empty)The HTML content to set (if omitted, will clear the HTML content)

Example: when the page loads, set the HTML of the div to a paragraph with some text

<div data-cc-on-load="html::<p>This is a paragraph.</p>"></div>

Invalid

Function: mark the form element(s) invalid

Applicable elements: form elements like inputs, selects, textareas and buttons

Signature:

invalid([selector])::[message*]::[class]

Slot & Fields:

NameRequiredTypeDefaultDescription
selectorNoselector-Select the matched element(s) to affect (if omitted, applies to current element)
messageYestext-The error message to display
classNotext-An optional class to apply to the element

Example: when the input value changes, if it is greater than or equal to (gte) 18, mark the input valid; otherwise, mark it invalid and show a message to the user

<input  name="age"  type="number"  data-cc-on-change="if(<<gte::{{value}}::18>>)::pass::fail"  data-cc-group-pass="valid"  data-cc-group-fail="invalid::You must be 18 or older."/>

Meta

Function: set metadata in the head of the page (via <meta> elements)

Applicable elements: any

Signature:

meta::[name*]::[content]

Fields:

NameRequiredTypeDefaultDescription
nameYestext-The name attribute of the meta element
contentNotext(empty)The content attribute of the meta element

Example: when the page loads, set the meta description

<body data-cc-on-load="meta::description::This is my website.">...</body>

Move

Function: move the selected element(s) to the target element

Applicable elements: any

Signature:

move([selector])::[target*]::[position]

Slot & Fields:

NameRequiredTypeDefaultDescription
selectorNoselector-Select the matched element(s) to affect (if omitted, applies to current element)
targetYesselector-The selector for the target element to move the matched element(s) to (uses the first match)
positionNotextafterWhere to insert the element(s) relative to the target (one of: before, after, prepend, append, or replace)

Example: when the page loads, get a list of users from an authenticated API call; when the call succeeds, generate the options from the response using the "name" of each user as the text and their "id" as the value

<body  data-cc-on-load="api::https://www.example.com/users::GET::true"  data-cc-on-httpsuccess="options(#user-input)::{{response}}::name::id">  ...  <select id="user-input"></select>  ...

Options

Function: generate option elements for a select element from an array

Applicable elements: select elements

Signature:

options([selector])::[array*]::[text]::[value]

Slot & Fields:

NameRequiredTypeDefaultDescription
selectorNoselector-Select the matched element(s) to affect (if omitted, applies to current element)
arrayYesarray-The list to generate the options from
textNotext-An optional key at which to find the text of the option (if using an array of objects)
valueNotext-An optional key at which to find the value of the option (if using an array of objects)

Example: when the page loads, get a list of users from an authenticated API call; when the call succeeds, generate the options from the response using the "name" of each user as the text and their "id" as the value

<body  data-cc-on-load="api::https://www.example.com/users::GET::true"  data-cc-on-httpsuccess="options(#user-input)::{{response}}::name::id">  ...  <select id="user-input"></select>  ...

Populate

Function: fill out fields within a form with the given data and format; fields are filled out based on their "name" attributes (ignores "file" inputs)

Applicable elements: forms

Signature:

populate([selector])::[data*]::[format]

Slot & Fields:

NameRequiredTypeDefaultDescription
selectorNoselector-Select the matched element(s) to affect (if omitted, applies to current element)
dataYesdepends-The data to populate the fields with (must match the format specified in the "Format" field)
formatNotextapplication/cc-core-filterThe format of the passed data (one of: application/cc-core-filter, application/x-www-form-urlencoded, application/json, or multipart/form-data)

Example: when the page loads, populate the form with data from the "user" session variable (in JSON format)

<form data-cc-on-load="populate::{{variable::user::session}}::application/json">...</form>

Remove

Function: remove the element(s) from the page

Applicable elements: any

Signature:

remove([selector])

Slot:

NameRequiredTypeDefaultDescription
selectorNoselector-Select the matched element(s) to affect (if omitted, applies to current element)

Example: when the button is clicked, remove the div

<button data-cc-on-click="remove(#my-div)">Delete</button><div id="my-div">...</div>

Reset

Function: reset the form(s)

Applicable elements: forms

Signature:

reset([selector])

Slot:

NameRequiredTypeDefaultDescription
selectorNoselector-Select the matched element(s) to affect (if omitted, applies to current element)

Example: reset the form when it is submitted

<form data-cc-on-submit="reset">...</form>

Scroll

Function: scroll to the element

Applicable elements: any visible element

Signature:

scroll([selector])::[behavior]::[block]::[inline]

Slot & Fields:

NameRequiredTypeDefaultDescription
selectorNoselector-Select the FIRST matched element to affect (if omitted, applies to current element)
behaviorNotextsmoothDetermines the scroll type (options: smooth, instant, auto)
blockNotextstartDefines vertical alignment (options: start, center, end, nearest)
inlineNotextnearestDefines horizontal alignment (options: start, center, end, nearest)

Example: on page load, scroll to the form

<form data-cc-on-load="scroll">...</form>

Show

Function: show the element(s) by setting their "display" property to "block"

Applicable elements: any

Signature:

show([selector])

Slot:

NameRequiredTypeDefaultDescription
selectorNoselector-Select the matched element(s) to affect (if omitted, applies to current element)

Example: when the button is clicked, hide the div

<button data-cc-on-click="hide(#my-div)">Hide</button><div id="my-div">...</div>

Style

Function: set an inline style on the element(s); if the value is omitted, then the style will be unset

Applicable elements: any

Signature:

style([selector])::[name*]::[value]

Slot & Fields:

NameRequiredTypeDefaultDescription
selectorNoselector-Select the matched element(s) to affect (if omitted, applies to current element)
nameYestext-The name of the CSS property in camel case, like "backgroundColor" or "display"
valueNotext-The value to set (if omitted, will unset the inline property)

Example: when the button is clicked, change the background color of the whole body to red

<button data-cc-on-click="style(body)::backgroundColor::#ff0000">Red</button>

Text

Function: set the text of the element(s)

Applicable elements: any element that can contain text, like a paragraph or heading

Signature:

text([selector])::[value*]

Slot & Fields:

NameRequiredTypeDefaultDescription
selectorNoselector-Select the matched element(s) to affect (if omitted, applies to current element)
valueYestext-The text to set (can be an empty string to clear text)

Example: when the page loads, set the text of the first div to "Lorem" and clear the text from the second div

<div data-cc-on-load="text::Lorem"></div><div data-cc-on-load="text::">Ipsum</div>

Title

Function: set the title of the page (visible in the tab of the user's browser); especially useful with dynamic content in a web app

Applicable elements: any

Signature:

title::[text*]

Fields:

NameRequiredTypeDefaultDescription
textYestext-The title to set

Example: when the page loads, set the title to "My Website"

<body data-cc-on-load="title::My Website">...</body>

Toggle

Function: toggle the display of an element, hiding it when it is visible and showing it when it is hidden

Applicable elements: any

Signature:

toggle([selector])

Slot:

NameRequiredTypeDefaultDescription
selectorNoselector-Select the matched element(s) to affect (if omitted, applies to current element)

Example: when the button is clicked, toggle the div

<button data-cc-on-click="toggle(#my-div)">Hide</button><div id="my-div">...</div>

Valid

Function: mark the form element(s) valid

Applicable elements: form elements like inputs, selects, textareas and buttons

Signature:

valid([selector])::[class]

Slot & Fields:

NameRequiredTypeDefaultDescription
selectorNoselector-Select the matched element(s) to affect (if omitted, applies to current element)
classNotext-An optional class to remove from the element

Example: when the input value changes, if it is greater than or equal to (gte) 18, mark the input valid; otherwise, mark it invalid and show a message to the user

<input  name="age"  type="number"  data-cc-on-change="if(<<gte::{{value}}::18>>)::pass::fail"  data-cc-group-pass="valid"  data-cc-group-fail="invalid::You must be 18 or older."/>

Value

Function: set the value of the element(s); note that this will NOT trigger any associated events like "input" or "change" (You can use the "trigger" action for that) and so will not update any variable bindings either (set the variable instead)

Applicable elements: form elements like inputs, selects, textareas and buttons

Signature:

value([selector])::[value*]

Slot & Fields:

NameRequiredTypeDefaultDescription
selectorNoselector-Select the matched element(s) to affect (if omitted, applies to current element)
valueYesdepends-The value to set (can be an empty string to clear value)

Example: when the first element receives input, clone its value to the second element

<input type="text" data-cc-on-input="value([name='clone'])::{{value}}" /><input name="clone" type="text" />

Logic

These actions relate to logical flows like conditions and loops.

For

Function: loop over the action group a number of times; if the number is omitted, the group will be looped infinitely and asynchronously

Applicable elements: any

Signature:

for([number])::[group*]

Slot & Fields:

NameRequiredTypeDefaultDescription
numberNonumber-The number of iterations (if omitted, loop infinitely)
groupYestext-The name of the group to execute (same element)

Example: for all children of the div, increment a counter variable (the "count" transformer is counting all elements that match the selector ":this > *", the direct children of the element)

<div  data-cc-on-load="setVariable::counter::0;;for(<<count:::this > *>>)::increment"  data-cc-group-increment="setVariable::counter::<<add::{{variable::counter}}::1>>">...</div>

For Each

Function: loop over the action group once per array item; the "data" parameter in the called group will be set to the individual array item

Applicable elements: any

Signature:

forEach([array*])::[group*]

Slot & Fields:

NameRequiredTypeDefaultDescription
arrayYesarray-The list to iterate over
groupYestext-The name of the group to execute (same element)

Example: for each item in the HTTP response, instantiate a template called "post" inside the div

<div  data-cc-on-load="api::https://www.example.com/posts"  data-cc-on-httpsuccess="forEach({{response}})::instance"  data-cc-group-instance="instantiate::post">...</div>

Group

Function: execute an action group on the element(s); this is a useful way to organize actions into bigger "blocks"

Applicable elements: any

Signature:

group([selector])::[name*]

Slot & Fields:

NameRequiredTypeDefaultDescription
selectorNoselector-Select the matched element(s) on which to trigger the group(s) (if omitted, applies to current element)
nameYestext-The name of the group to execute

Example: for both load and click events, execute the "message" group

<button  data-cc-on-load="group::message"  data-cc-on-click="group::message"  data-cc-group-message="log::Hello!">Send Message</button>

If

Function: Execute a group based on a condition; if the condition is not met, execute an optional false group. You can implement AND and OR logic by chaining multiple instances of this action across groups.

Applicable elements: any

Signature:

if([condition*])::[true*]::[false]

Slot & Fields:

NameRequiredTypeDefaultDescription
conditionYesboolean-Evaluates to either true or false and executes the corresponding action group
trueYestext-The name of the group to execute if the condition is true
falseNotext-The name of the group to execute if the condition is false

Example: on load, change the text to reflect the age of the user based on the "age" session variable

<div  data-cc-on-load="if(<<gte::{{variable::age::session}}::13>>)::check-18::child"  data-cc-group-check-18="if(<<gte::{{variable::age::session}}::18>>)::adult::teen"  data-cc-group-child="text::You are a child"  data-cc-group-teen="text::You are a teen"  data-cc-group-adult="text::You are an adult"></div>

Timeout

Function: trigger a timeout for a specified duration, calling an action group when it expires; if the timeout action is called again with the same name before that, it will restart the timeout

Applicable elements: any

Signature:

timeout::[name*]::[time*]::[group*]

Fields:

NameRequiredTypeDefaultDescription
nameYestext-An identifier to assign to this timeout so it can be referenced later
timeYesnumber-The duration in seconds before the group is executed
groupYestext-The name of the group to execute

Example: When the user types into the element below, once they pause typing for 0.5 seconds, the API call will be made (prevents unnecessary API calls on every key)

<input  data-cc-on-input="timeout::search::0.5::get-users"  data-cc-group-get-users="api::https://example.com/users::GET::true"  type="text"/>

Wait

Function: pause the execution of the following actions for a certain period of time

Applicable elements: any

Signature:

wait::[time*]

Fields:

NameRequiredTypeDefaultDescription
timeYestext-The duration in seconds to pause for

Example: When the page loads, wait 10 seconds before showing a modal with id "newsletter-modal"

<body data-cc-on-load="wait::10;;show(#newsletter-modal)">...</body>

Navigation

These actions relate to sending the user to specific pages.

Navigate

Function: send the user to the specified URL

Applicable elements: any

Signature:

navigate::[url*]

Fields:

NameRequiredTypeDefaultDescription
urlYestext-The URL to navigate to

Example: When the button is clicked, navigate to the homepage

<button data-cc-on-click="navigate::/">Reject</button>

Redirect

Function: send the user to the specified URL and replace the current page in the browser's navigation history

Applicable elements: any

Signature:

redirect::[url*]

Fields:

NameRequiredTypeDefaultDescription
urlYestext-The URL to redirect to

Example: When the page loads, redirect to a different one at "/new-page"

<body data-cc-on-load="redirect::/new-page">...</body>

Reload

Function: refresh the current page

Applicable elements: any

Signature:

reload

Example: When the form is submitted, reload the page

<form data-cc-on-submit="reload">...</form>

Query Parameters

These actions relate to the query string of the current URL.

Set Query

Function: add or update a key in the query string

Applicable elements: any

Signature:

setQuery::[key*]::[value]

Fields:

NameRequiredTypeDefaultDescription
keyYestext-The name of the query parameter
valueNotext(empty)The value of the query parameter

Example: on page load, set a query parameter of "loaded=true"

<body  data-cc-on-load="setQuery::loaded::true">...</body>

Remove Query

Function: remove a key in the query string

Applicable elements: any

Signature:

removeQuery::[key*]

Fields:

NameRequiredTypeDefaultDescription
keyYestext-The name of the query parameter

Example: on page load, remove a query parameter called "id"

<body  data-cc-on-load="removeQuery::id">...</body>

Clear Queries

Function: remove the query string completely

Applicable elements: any

Signature:

clearQueries

Example: on page load, remove all query parameters

<body  data-cc-on-load="clearQueries">...</body>

System

These actions are useful for testing or logging information.

Alert

Function: show an alert message in the browser

Applicable elements: any

Signature:

alert::[message*]

Fields:

NameRequiredTypeDefaultDescription
messageYestext-The message to display

Example: When the button is clicked, show an alert message saying "Button clicked"

<button data-cc-on-click="alert::Button clicked">Test</button>

Debug

Function: logs the current element and "data" parameter to the console and triggers the JavaScript debugger

Applicable elements: any

Signature:

debug

Example: When the call completes, debug it (so you can, for example, inspect the response)

<body  data-cc-on-load="api::https://www.example.com/posts"  data-cc-on-httpsuccess="debug">...</body>

Log

Function: log a message to the console

Applicable elements: any

Signature:

log::[message*]

Fields:

NameRequiredTypeDefaultDescription
messageYestext-The message to log

Example: When the button is clicked, log a message saying "Button clicked"

<button data-cc-on-click="log::Button clicked">Test</button>

Tabs

These actions relate to creating advanced components for tabs, sliders, and multistep forms.

Tabs

Function: create tab panels from the direct children of the target element

Applicable elements: any (with children)

Signature:

tabs([selector])::[id*]

Fields:

NameRequiredTypeDefaultDescription
selectorNoselector-Select the first matched element on which to transform into tabs (if omitted, applies to current element)
idYestext-The identifier to tie this tabs instance to (must be unique)

Example: when the page loads, transform the contents of the div into tab panels and assign an id of "example"

<div data-cc-on-load="tabs::example">...</div>

Tab

Function: switch the tabs component with the given id to the specified page, optionally validating any form elements on the current page before switching; validation is applied to the current page in all cases except when the page field is "invalid" in which case it applies to the destination page

Applicable elements: any

Signature:

tab::[id*]::[page*]::[validate]

Fields:

NameRequiredTypeDefaultDescription
idYestext-The identifier of the tabs component to target
pageYesvarious-The page to switch to (can be a zero-based numerical index or one of: previous, next, first, last, invalid); "invalid" switches to the first page with invalid elements, otherwise remaining on the current page
validateNovariousfalseWhether to validate form elements on the current page prior to switching (can be true/false or a specific class name to apply to invalid elements)

Example: when the button is clicked, validate all inputs on the current page of the tabs component with id "example" and apply a class of "invalid-input" to any invalid elements; if all are valid, advance to the next page

<button data-cc-on-click="tab::example::next::invalid-input">Next</button>

Variables

These actions relate to variables, which can persist over different scopes:

  • window: until navigation or refresh
  • session: until the session ends (the tab is closed)
  • local: until cleared programmatically or by the user

Set Variable

Function: add or update the variable with the given name in the given scope

Applicable elements: any

Signature:

setVariable::[name*]::[value*]::[scope]::[expiration]

Fields:

NameRequiredTypeDefaultDescription
nameYestext-The name of the variable
valueYesany-The value to set
scopeNotextwindowWhere to store the variable (options: window, session, local)
expirationNonumber(empty)An optional lifetime for the variable in seconds

Example: when the page loads, set a window variable of "count" to "0"

<div data-cc-on-load="setVariable::count::0"></div>

Remove Variable

Function: remove the variable with the given name from the given scope

Applicable elements: any

Signature:

removeVariable::[name*]::[scope]

Fields:

NameRequiredTypeDefaultDescription
nameYestext-The name of the variable
scopeNotextwindowThe scope of the variable (options: window, session, local)

Example: when the button is clicked, delete the "name" session variable

<button data-cc-on-click="removeVariable::name::session">Forget</button>

Clear Variables

Function: remove all variables with the given scope

Applicable elements: any

Signature:

clearVariables::[scope]

Fields:

NameRequiredTypeDefaultDescription
scopeNotextwindowThe scope of the variables (options: window, session, local)

Example: when the button is clicked, clear all variables from local storage

<button data-cc-on-click="clearVariables::local">Forget All</button>

Transformers

Sometimes the data you receive from an API call or user input isn't in the exact format you need. Transformers change the data passed into them by applying some sort of operation and returning the result. They are especially useful with "Logic" actions such as conditions and loops. Transformers can have other transformers nested inside them in order to chain transformations.

Comparison

These transformers compare two values and output either true or false.

Equal

Function: check whether the first field is equal to the second

Signature:

<<eq::[first*]::[second*]>>

Fields:

NameRequiredTypeDefaultDescription
firstYesany-The first value to compare
secondYesany-The second value to compare

Output:

true | false

Example: check if the "status" variable is "passed"

<<eq::{{variable::status}}::passed>>

Greater Than

Function: check whether the first field is greater than the second

Signature:

<<gt::[first*]::[second*]>>

Fields:

NameRequiredTypeDefaultDescription
firstYesany-The first value to compare
secondYesany-The second value to compare

Output:

true | false

Example: check if the "age" variable is greater than 17

<<gt::{{variable::age}}::17>>

Greater Than or Equal

Function: check whether the first field is greater than or equal to the second

Signature:

<<gte::[first*]::[second*]>>

Fields:

NameRequiredTypeDefaultDescription
firstYesany-The first value to compare
secondYesany-The second value to compare

Output:

true | false

Example: check if the "age" variable is greater than or equal to 18

<<gte::{{variable::age}}::18>>

Less Than

Function: check whether the first field is less than the second

Signature:

<<lt::[first*]::[second*]>>

Fields:

NameRequiredTypeDefaultDescription
firstYesany-The first value to compare
secondYesany-The second value to compare

Output:

true | false

Example: check if the "age" variable is less than 18

<<lt::{{variable::age}}::18>>

Less Than or Equal

Function: check whether the first field is less than or equal to the second

Signature:

<<lte::[first*]::[second*]>>

Fields:

NameRequiredTypeDefaultDescription
firstYesany-The first value to compare
secondYesany-The second value to compare

Output:

true | false

Example: check if the "age" variable is less than or equal to 17

<<lte::{{variable::age}}::17>>

Not Equal

Function: check whether the first field is not equal to the second

Signature:

<<ne::[first*]::[second*]>>

Fields:

NameRequiredTypeDefaultDescription
firstYesany-The first value to compare
secondYesany-The second value to compare

Output:

true | false

Example: check if the "status" variable is not "failed"

<<ne::{{variable::status}}::failed>>

Not True

Function: check whether the field is falsey

Signature:

<<not::[value*]>>

Fields:

NameRequiredTypeDefaultDescription
valueYesany-The value to check

Output:

true | false

Example: check if the "admin" variable is not true (or not set)

<<not::{{variable::admin}}>>

Date & Time

These transformers format dates and times.

Date

Function: convert the value to a date; optionally select a time zone and format

Signature:

<<date::[value*]::[format]::[zone]>>

Fields:

NameRequiredTypeDefaultDescription
valueYesany-The date as a string or a timestamp in milliseconds
formatNotextbrowserThe locale, like "en-US" (if omitted, defaults to user's browser locale); Can also be set to: "ISO", "year", "month", "day", "browser", "long-month", "short-month", "long-day", or "short-day"
zoneNotextbrowserThe IANA time zone, like "America/Los_Angeles" or "UTC" (if omitted, defaults to user's "browser" time zone)

Output: dependent on locale; for example, the "en-US" locale outputs the format below

m/d/Y

Example: convert the timestamp in the "created" response field to a date using the user's browser settings

<<date::{{response::created}}>>

Time

Function: convert the value to a time; optionally select a time zone and format

Signature:

<<time::[value*]::[format]::[zone]>>

Fields:

NameRequiredTypeDefaultDescription
valueYesany-The date as a string or a timestamp in milliseconds
formatNotext-The locale, like "en-US" (if omitted, defaults to user's browser locale); can also be set to "ISO"
zoneNotext-The IANA time zone, like "America/Los_Angeles" or "UTC" (if omitted, defaults to user's browser time zone)

Output: dependent on locale; for example, the "en-US" locale outputs the format below

h:mm:ss AM/PM

Example: convert the timestamp in the "appointment" response field to a time using the user's browser settings

<<time::{{response::appointment}}>>

Lists

These transformers operate on lists of various items.

Count

Function: count the number of elements on the page that match the selector

Signature:

<<count::[selector*]>>

Fields:

NameRequiredTypeDefaultDescription
selectorYesselector-The selector used to match the elements to count

Output:

[number]

Example: count the number of elements with the class "post-wrapper"

<<count::.post-wrapper>>

Length

Function: count the number of items in the array

Signature:

<<length::[array*]>>

Fields:

NameRequiredTypeDefaultDescription
arrayYesarray-The array of items to count

Output:

[number]

Example: count the number of items in the "posts" field of the response

<<length::{{response::posts}}>>

Merge

Function: combine an array with additional element(s), including another array

Signature:

<<merge::[array*]::[payload*]>>

Fields:

NameRequiredTypeDefaultDescription
arrayYesarray-The array of items to merge
payloadYesany-the data to merge with the array

Output:

[array]

Example: combine the posts in a variable with additional items returned from an API call (useful in bound arrays that are implementing infinite scrolling)

<<merge::{{variable::posts}}::{{response::items}}>>

Logic

These transformers can be used to for more complex conditions.

And

Function: returns true if both arguments are true; otherwise, returns false

Signature:

<<and::[first*]::[second*]>>

Fields:

NameRequiredTypeDefaultDescription
firstYesany-The first value to evaluate
secondYesany-The second value to evaluate

Output:

true | false

Example: evaluate if the "data-foo" attribute is greater than 10 and the "disabled" attribute is false

<<and::<<gt::{{attribute::data-foo}}::10>>::<<not::{{attribute::disabled}}>>>>

Or

Function: returns true if either of the arguments is true; otherwise, returns false

Signature:

<<or::[first*]::[second*]>>

Fields:

NameRequiredTypeDefaultDescription
firstYesany-The first value to evaluate
secondYesany-The second value to evaluate

Output:

true | false

Example: evaluate if the "data-foo" attribute is less than or equal to 10 or the "disabled" attribute is true

<<or::<<lte::{{attribute::data-foo}}::10>>::{{attribute::disabled}}>>

Math

These transformers perform various arithmetic operations and return the result.

Absolute

Function: get the absolute value of a number

Signature:

<<absolute::[number*]>>

Fields:

NameRequiredTypeDefaultDescription
numberYesnumber-The number from which to get the absolute value

Output:

[number]

Example: calculate the absolute value of the "score" field in the response

<<absolute::{{response::score}}>>

Add

Function: add the first number to the second

Signature:

<<add::[first*]::[second*]>>

Fields:

NameRequiredTypeDefaultDescription
firstYesnumber-The first number
secondYesnumber-The second number

Output:

[number]

Example: get the result of incrementing the "count" variable by 1

<<add::{{variable::count}}::1>>

Ceiling

Function: round the number up

Signature:

<<ceiling::[number*]::[precision]>>

Fields:

NameRequiredTypeDefaultDescription
numberYesnumber-The number to round
precisionNonumber0The number of decimal places to round to

Output:

[number]

Example: round up the "cost" variable to 2 decimal places

<<ceiling::{{variable::cost}}::2>>

Divide

Function: divide the first number by the second

Signature:

<<divide::[numerator*]::[denominator*]>>

Fields:

NameRequiredTypeDefaultDescription
numeratorYesnumber-The first number
denominatorYesnumber-The second number

Output:

[number]

Example: get the result of dividing the "cost" variable by the "users" variable

<<divide::{{variable::cost}}::{{variable::users}}>>

Floor

Function: round the number down

Signature:

<<floor::[number*]::[precision]>>

Fields:

NameRequiredTypeDefaultDescription
numberYesnumber-The number to round
precisionNonumber0The number of decimal places to round to

Output:

[number]

Example: round down the "cost" variable to 2 decimal places

<<floor::{{variable::cost}}::2>>

Max

Function: return the larger of the two values specified

Signature:

<<max::[first*]::[second*]>>

Fields:

NameRequiredTypeDefaultDescription
firstYesnumber-The first number
secondYesnumber-The second number

Output:

[number]

Example: if the "offset" variable becomes negative, return 0 instead; otherwise, return the "offset" variable

<<max::{{variable::offset}}::0>>

Min

Function: return the smaller of the two values specified

Signature:

<<min::[first*]::[second*]>>

Fields:

NameRequiredTypeDefaultDescription
firstYesnumber-The first number
secondYesnumber-The second number

Output:

[number]

Example: return the lower of the "sale-price" and "employee-price"

<<min::{{variable::sale-price}}::{{variable::employee-price}}>>

Multiply

Function: multiply the first number by the second

Signature:

<<multiply::[first*]::[second*]>>

Fields:

NameRequiredTypeDefaultDescription
firstYesnumber-The first number
secondYesnumber-The second number

Output:

[number]

Example: get the result of dividing the "price" variable by the "units" variable

<<multiply::{{variable::price}}::{{variable::units}}>>

Percent

Function: convert the decimal number to a percentage

Signature:

<<percent::[number*]::[precision]>>

Fields:

NameRequiredTypeDefaultDescription
numberYesnumber-The number to convert
precisionNonumber0The number of decimal places to show

Output:

[number]%

Example: convert the "progress" variable to a percentage

<<percent::{{variable::progress}}>>

Power

Function: calculate the base to the exponent

Signature:

<<power::[base*]::[exponent]>>

Fields:

NameRequiredTypeDefaultDescription
baseYesnumber-The first number
exponentNonumber2The second number

Output:

[number]

Example: get the square of the value of the input with id "calc-input"

<<power::{{value(#calc-input)}}>>

Root

Function: calculate the root of the radicand

Signature:

<<root::[radicand*]::[index]>>

Fields:

NameRequiredTypeDefaultDescription
radicandYesnumber-The first number
indexNonumber2The second number

Output:

[number]

Example: get the square root of the value of the input with id "calc-input"

<<root::{{value(#calc-input)}}>>

Round

Function: round the number

Signature:

<<round::[number*]::[precision]>>

Fields:

NameRequiredTypeDefaultDescription
numberYesnumber-The number to round
precisionNonumber0The number of decimal places to round to

Output:

[number]

Example: round the "cost" variable to 2 decimal places

<<round::{{variable::cost}}::2>>

Subtract

Function: subtract the second number from the first

Signature:

<<subtract::[first*]::[second*]>>

Fields:

NameRequiredTypeDefaultDescription
firstYesnumber-The first number
secondYesnumber-The second number

Output:

[number]

Example: get the result of decrementing the "count" variable by 1

<<subtract::{{variable::count}}::1>>

Text

These transformers modify data for display

Default

Function: returns a default value if the original value is falsy like null, 0, or an empty string

Signature:

<<default::[value*]::[replacement*]>>

Fields:

NameRequiredTypeDefaultDescription
valueYesany-The original value to check
replacementYestext-What to replace the value with if it is falsy

Output:

[text]

Example: if childrenCount is 0 in the response, replace it with the word "None"

<<default::{{response::childrenCount}}::None>>

Format

Function: formats a number according to a locale, optionally forcing a certain amount of digits

Signature:

<<format::[number*]::[fraction]::[integer]::[locale]>>

Fields:

NameRequiredTypeDefaultDescription
numberYesnumber-The number to format
fractionNonumber0-3Force an exact amount of digits in the fraction (will be padded with 0s); can be 0-100
integerNonumber1Set the minimum amount of digits in the integer (will be padded with 0s); can be 1-21
localeNotextbrowserThe locale, like "en-US" (if omitted, defaults to user's browser locale); can also be set to: "browser"

Output:

[number (formatted)]

Example: formats the number "3000.1" as "3,000.10" (two digits in the fraction, assuming en-US locale)

<<format::3000.1::2>>

Replace

Function: replace all instances of the pattern within the text with the given replacement

Signature:

<<replace::[text*]::[pattern*]::[replacement]::[flags]>>

Fields:

NameRequiredTypeDefaultDescription
textYestext-The text to make the replacements in
patternYestext | regex-The text to replace
replacementNotext(empty)What to replace the text with
flagsNotext-If set, will act as regex flag(s) for the replacement, and the pattern will be treated as a regular expression

Output:

[text]

Example: replace all instances of "the" from the text with "my"

<<replace::This is the text::the::my>>

Example: use a regular expression to replace all numbers with "X" (equivalent to /[0-9]/g)

<<replace::abc123::[0-9]::X::g>>

Slug

Function: returns a slugified version of the text that is URL-friendly

Signature:

<<slug::[text*]>>

Fields:

NameRequiredTypeDefaultDescription
textYestext-The text to modify

Output:

[text]

Example: get a slugified version of the value of an input field named "title"

<<slug::{{value(input[name='title'])}}>>

URI Decode

Function: decode a URI-encoded piece of text

Signature:

<<uriDecode::[payload*]::[component]>>

Fields:

NameRequiredTypeDefaultDescription
payloadYestext-The text to decode
componentNobooleantrueWhether to decode as a component or a whole URI

Output:

[text]

Example: decode the data in the "username" query parameter

<<uriDecode::{{query::username}}>>

URI Encode

Function: URI-encode a piece of text

Signature:

<<uriEncode::[payload*]::[component]>>

Fields:

NameRequiredTypeDefaultDescription
payloadYestext-The text to encode
componentNobooleantrueWhether to encode as a component or a whole URI

Output:

[text]

Example: Encode the name "John Smith" (presumably for use in a query parameter)

<<uriEncode::John Smith>>

Parameters

Parameters allow you to pull data from various dynamic sources, be it API calls, variables, user inputs, or anything else. They are the key to building app-like functionality into your project. Parameters can also have other parameters nested within them.

API

These parameters work exclusively with the "API" action.

Request

Returns: the body of the request; this parameter is accessible in any "HTTP" event

Signature:

{{request::[key]}}

Fields:

NameRequiredTypeDefaultDescription
keyNotext-The optional key to search for within the request body (using dot notation)

Example: get the value of "username" from within the request body

{{request::username}}

Response

Returns: the body of the response; this parameter is accessible in any "HTTP" event except for "HTTP Start"

Signature:

{{response::[key]}}

Fields:

NameRequiredTypeDefaultDescription
keyNotext-The optional key to search for within the response body (using dot notation)

Example: get the value of "user.id" from within the response body

{{response::user.id}}

Elements

These parameters get their values from various properties of elements on the page.

Attribute

Returns: the value of an attribute on the element

Signature:

{{attribute([selector])::[name*]}}

Slot & Fields:

NameRequiredTypeDefaultDescription
selectorNoselector-The selector used to get the FIRST matched element to affect (if omitted, the current element is used)
nameYestext-The name of the attribute from which to get the value

Example: get the value of an attribute called "data-name" from the current element

{{attribute::data-name}}

Checked

Returns: either true or false, depending on if the element is checked (only applies to radio and checkbox inputs)

Signature:

{{checked([selector])}}

Slot:

NameRequiredTypeDefaultDescription
selectorNoselector-The selector used to get the FIRST matched element to affect (if omitted, the current element is used)

Example: get whether an input with id "my-checkbox" is checked

{{checked(#my-checkbox)}}

Disabled

Returns: either true or false, depending on if the element is disabled (only applies to form elements like inputs or buttons)

Signature:

{{disabled([selector])}}

Slot:

NameRequiredTypeDefaultDescription
selectorNoselector-The selector used to get the FIRST matched element to affect (if omitted, the current element is used)

Example: get whether an input with id "my-checkbox" is disabled

{{disabled(#my-checkbox)}}

HTML

Returns: the HTML content of the element

Signature:

{{html([selector])}}

Slot:

NameRequiredTypeDefaultDescription
selectorNoselector-The selector used to get the FIRST matched element to affect (if omitted, the current element is used)

Example: get the HTML from an element with id "instructions"

{{html(#instructions)}}

Index

Returns: a zero-based number representing the position of the element in its parent

Signature:

{{index([selector])}}

Slot:

NameRequiredTypeDefaultDescription
selectorNoselector-The selector used to get the FIRST matched element to affect (if omitted, the current element is used)

Example: get the index of the current element

{{index}}

Serialize

Returns: the field data of a form stringified in the format specified (does not work with "file" inputs)

Signature:

{{serialize([selector])::[format]}}

Slot & Fields:

NameRequiredTypeDefaultDescription
selectorNoselector-Select the first matched element to affect (if omitted, applies to current element)
formatNotextapplication/cc-core-filterThe format of the resulting data (one of: application/cc-core-filter, application/x-www-form-urlencoded, application/json, or multipart/form-data)

Example: serialize a form with id "my-form" into JSON

{{serialize(#my-form)::application/json}}

Text

Returns: the text content of the element (only applies to elements that can contain text, like headings or paragraphs)

Signature:

{{text([selector])}}

Slot:

NameRequiredTypeDefaultDescription
selectorNoselector-The selector used to get the FIRST matched element to affect (if omitted, the current element is used)

Example: get the text from an element with id "instructions"

{{text(#instructions)}}

Value

Returns: the value of the element (only applies to form elements like inputs, selects and textareas)

Signature:

{{value([selector])}}

Slot:

NameRequiredTypeDefaultDescription
selectorNoselector-The selector used to get the FIRST matched element to affect (if omitted, the current element is used)

Example: get the value of an input with name attribute of "startDate"

{{value([name='startDate'])}}

Universal

These parameters can be used anywhere.

Auth

Returns: the user authentication token if they were logged in using the Cloud Canal Connect authentication system; can be used to check if the user is logged in

Signature:

{{auth}}

Example: if the user is logged in, execute the group called "logged-in"

if({{auth}})::logged-in

Clipboard

Returns: the text copied to the user's clipboard (may require permission confirmation in the browser)

Warning: this is not currently supported in Firefox

Signature:

{{clipboard}}

Example: paste the clipboard value into an input with id "target"

value(#target)::{{clipboard}}

Code

Returns: the return value of the custom code; note that the code does not have to return anything, and can instead be used to execute any arbitrary code (including interacting with the Cloud Canal Connect API)

Warning: ensure that you trust the source of any data you use inside a code parameter; the use of nested parameters here is highly discouraged unless you can guarantee that a malicious user will not be able to inject their own values

Signature:

{{code::[code*]}}

Fields:

NameRequiredTypeDefaultDescription
codeYestext-The JavaScript code to execute

Example: return the value of the "count" variable + 1 (using the Cloud Canal Connect API)

{{code::return window.cloudCanal.api.getVariable('count') + 1}}

Cookie

Returns: the value stored in a specific code-accessible cookie

Signature:

{{cookie::[key*]}}

Fields:

NameRequiredTypeDefaultDescription
keyYestext-The name of the cookie from which to get the value

Example: get the value of a cookie called "x-id"

{{cookie::x-id}}

Data

Returns: context-specific data depending on the event in which this parameter is used (certain actions like "For Each" also modify the "data" parameter)

Signature:

{{data::[key]}}

Fields:

NameRequiredTypeDefaultDescription
keyNotext-The optional key to search for within the data object (using dot notation)

Example: get the value of the URL from the "data" parameter in an "HTTP" event

{{data::url}}

Location

Returns: information about the URL of the current page

Signature:

{{location::[key]}}

Fields:

NameRequiredTypeDefaultDescription
keyNotexthrefThe specific part of the url to return; options: hash, host, hostname, href, origin, pathname, port, protocol, search

Example: on the webpage "https://www.example.com/foo?bar=baz", return the origin of "https://www.example.com"

{{location::origin}}

Meta

Returns: the content of the meta element with the given name

Signature:

{{meta::[name*]}}

Fields:

NameRequiredTypeDefaultDescription
nameYestext-The name attribute of the meta element

Example: get the meta description of the current page

{{meta::description}}

Now

Returns: the current timestamp, in milliseconds

Signature:

{{now}}

Example: get the current year (ex. for use in a footer)

<<date::{{now}}::browser::year>>

Path

Returns: the value of the URL path segment at the given index

Signature:

{{path::[index]}}

Fields:

NameRequiredTypeDefaultDescription
indexNonumber(empty)The zero-based index of the path segment (can be negative to start from last segment); omitting the index will return the entire path with leading and trailing slashes removed

Example: get the last path segment of the current page (on "https://www.example.com/foo/bar/baz" will return "baz")

{{path::-1}}

Query

Returns: the value of the specified query parameter

Signature:

{{query::[key]}}

Fields:

NameRequiredTypeDefaultDescription
keyNotext(empty)The name of the query parameter in the URL (if omitted, will return the whole query string)

Example: get the value for a query parameter called "id"

{{query::id}}

Title

Returns: the title of the current page

Signature:

{{title}}

Example: set the value of the current element to the page title

value::{{title}}

Variable

Returns: the value of the specified variable

Signature:

{{variable::[name*]::[scope]}}

Fields:

NameRequiredTypeDefaultDescription
nameYestext-The name of the variable
scopeNotextwindowThe scope of the variable (options: window, session, local)

Example: get the value of a session variable called "username"

{{variable::username::session}}
Cloud Canal logo
CoreClientsConnectComponentsContent
© 20XX Cloud Canal. All rights reserved.
Privacy PolicyTerms of ServiceCookie PolicyCookies