Editing a Filter

Prev Next

A filter is a piece of JavaScript code that takes the value (e.g., from a metric or property) as input and produces a new value, for instance:

  • A number (e.g., 2 decimal formatted).

  • A string (e.g., integer to label).

  • An HTML fragment (e.g., colored icon).

The filter is loaded into the Servitly front-end and executed directly in the user's browser.
The widget uses the resulting value by displaying it directly (e.g., millisToHours) on the page or within an internal logic (e.g., value > 100 then display a warning).
The filter may also generate an HTML fragment, which will be attached to the main page HTML in the right place.

Here are some examples of filters applied to value.

Value to Dictionary

Percentage as Progress Bar

Booleans as colored circles

Class declaration

Custom filters can be defined by creating a JavaScript class with a predefined set of methods that are invoked by the front-end application engine during page computation.
The class can be declared directly in the Custom Filters or in the Source Code panel of a custom component when using the Components Manager.
The following code describes a filter that receives a number (float or string) and truncates decimals to 1 digit.

exports.singleDecimalFormat = class {

    constructor() {}
    
    transform(value, args) {
        return parseFloat(value).toFixed(1);
    }   

};

The class must be registered in the exports object with a specific name, which will be used in templates and components.

When writing code for your filters, you can use the following built-in classes:

  • AppUtils: provides a set of methods to access and interact with the page.
    This class is automatically instantiated by the front-end framework and is available in the context via the appUtils variable.

  • ColorManager: provides access to the color palettes.
    This class is automatically instantiated by the front-end framework and is available in the context via the colorManager variable.

  • ServitlyClient: provides methods to access the Servitly backend API.
    This class is automatically instantiated by the front-end framework and is available in the context via the servitlyClient variable.

Asynchronous API invocation

Note that since filters generate value synchronously, the use of the Servitly API (which is asynchronous) is not recommended.
In this case, the filter must return a placeholder element (e.g. a div with specific class or ID) to be updated in the success callback passed to the servitlyClient method.

How to use a Filter

Filters (custom or built-in) can be used directly in Templates, for instance, to display a property or a metric.

<thing-details-widget [title]="'Machine Info'" >
	<property name="name"></property>
	<property name="serialNumber"></property>
	<metric name="Connection Status" filter="connectionStatus"></metric>
</thing-details-widget>

<time-series-chart-widget>
	<metric name="temperature" filter="singleDecimalFormat"></metric>
</time-series-chart-widget>

Instead, in case you are developing a widget, you can reference a filter (custom or built-in) by using the following code.

// creates the filter instance
let filter = appUtils.createFilter(ā€œmillisToHoursā€œ);

// uses the filter instance to transform values
let hours = filter.transform(452657);

When iterating over values, the best practice is to create the instance once and reuse it for all values to transform.

Some filters are context-aware, so you must also pass the context to the transform method.
For instance, the Dictionary filter requires the definition of the metric or property whose values are displayed.

let ctx = {"metric": metric} // metric is the metric-definition object in case of metric value transforming 
let ctx = {"property": property} // property is the property-definition object in case of property value transforming

// creates the filter instance
let dictionary = appUtils.createFilter('dictionary:{"showIcon":false,"showValue":true,"showLabel":false}');

// uses the filter instance to transform values and context
let htmlValue = dictionary.transform(123, ctx);

For an example of usage in a widget, you can refer to the article Editing a Widget.