Skip to main content

Views

Some Nodes may need to display UI elements such as text inputs, buttons, or maps. To create a Node with UI elements, follow these three steps:

  • Set the environment to browser in the manifest.yaml file
  • Add a property with a web-view datatype (usually named view)
  • Define a render function for the view property
manifest.yaml
name: Visual Node
environments: browser
properties.yaml
view:
datatype: web-view
src/main.js
context.set('view', context.render(renderFn));
Note

web-view is a datatype that indicates the property is a render function that renders a view for the web or browser. In the future, there will be other datatypes for rendering other types of views.

 

Note

A View Property does not have to use the key view, other keys can be used. A Node can also have multiple views. However, if your node only has a single view, using view as the key will follow standard naming convention.

properties.yaml
input_view:
datatype: web-view
result_view:
datatype: web-view

Rendering

A render function is a function that produces display elements and adds those elements to the canvas.

For web-view properties, the render function will produce html elements and given a parentElement, append the elements.

src/main.js
function render(parentElement) {

// Create display element(s)
const button = document.createElement('button');
button.innerHTML = `Count is ${context.get('count')}`;

parentElement.appendChild(button);
}

Setting a View Property

Once a render function and View Property are defined, you can set the render function to the View Property just like any other property.

Setting the render function on a View Property allows it to be displayed either by connecting it to another Node's Viewport Property or used as the Root View.

properties.yaml
view:
datatype: web-view
src/main.js
function render(parentElement) {

// Create display element(s)
const button = document.createElement('button');
button.innerHTML = `Count is ${context.get('count')}`;

parentElement.appendChild(button);
}

// Set the render function to the ((view)) property
context.set('view', render);

Render Helper

In order to make defining a render function simpler, Openexus provides a helper function, context.render(), that will append a display element to the parent element.

The render function, when wrapped with context.render(), will only need to return the display elements.

Below is a rewritten example using context.render():

src/main.js
// Note: This render function does not take in a parentElement
function render() {

// Create display element(s)
const button = document.createElement('button');
button.innerHTML = `Count is ${context.get('count')}`;

// Return elements to display
return button;
}

// Set the render function to the ((view)) property, wrapping it with the context.render() helper
context.set('view', context.render(render));

Working with Frameworks

Each framework has its own approach to rendering. These might include creating elements or using JSX/TSX. Openexus has provided context.render() helpers for React, Solid, Svelte, and Vue, allowing for render functions to just be component definitions. Please consult our extensive Framework documentation to learn more details.

Example

 

Simple counter button example without using any external libraries.

manifest.yaml
name: Counter (JavaScript)
description: An example using JavaScript and no framework to render a simple button that displays the number of times the button is clicked.
categories: starter/javascript,starter/vanilla
keywords: starter,javascript,vanilla,counter
icon: logos:javascript
environments: browser
sandbox: browser.shadow
properties.yaml
view:
datatype: web-view
count:
datatype: number
description: The number of times the button has been clicked since this application was started. This represents using a simple Property in the Openexus system.
default: 1
src/main.js
/**
* An example using JavaScript and no framework to render a simple
* button that displays the number of times the button is clicked.
*/

let button;

// Define a render function to return our HTMLElement to display.
function render() {
// Create the element.
button = document.createElement('button');

// Populate the element.
button.innerHTML = `Count is ${context.get('count')}`;

// Openexus components use tailwind by default, but you can define CSS
// classes and styles in your preferred manner.
button.classList.add('bg-blue-500', 'hover:bg-blue-700', 'text-white', 'py-2', 'px-4', 'rounded');

// For our button we want to mutate our count state when it is clicked.
button.addEventListener('click', (value) => {
context.set('count', context.get('count') + 1);
});

return button;
}

// Register to be notified when ((count)) changes.
context.subscribe('count', (value) => {
if (button) button.innerHTML = `Count is ${value}`;
});

// Set our render function to the ((view)) property for rendering.
context.set('view', context.render(render));