This guide will provide an overview and examples of working with data filters in Molten UIs.
Overview
To search the Leverege platform for data – as opposed to requesting a list of data or making a get request for a specific item – we pass an Imagine filter in to the search endpoint. This filter tells the API what properties of data to select for: where such-and-such a field (i.e., value at an attribute path) equals such-and-such a value, or not this, etc. Leverege’s search is backed by elasticsearch, and supports almost all of the query operations familiar in that platform (though Leverege uses a different query syntax).
The Imagine filter is a plain JSON object that simply encodes the query structure. For example, the following filter will search for devices along where the device’s data.company.name field matches one of the two given strings:
{
"type":"equals",
"field":"data.company.name",
"value":[
"Penguin Parcels",
"Orca Operations"
]
}
Searches can be performed along an interface path to restrict the search space (e.g., api.interface( systemId, ‘continent' ).obj( continentId ).grp( 'packages' ).search( imagineFilter ) would search only children of the given continent’s packages relationship.
Working with Filter Models
Models
In Molten UIs, filter instances are typically constructed based on filter models. Models are templates, in this case templates for the various filtering operations the endpoint will accept.
Simple Filter Model
To quickly create an equals filter without having to code in the boilerplate, we can call EqualsFilterModel.create(), which yields:
{
"type":"filter.equals",
"field":null,
"value":[],
"empty":false,
"fieldType":null
}
Models typically include setters and getters for their properties: e.g., setField( ‘foo’ ), getField().
Types of Filter Models
Molten has Filter models and editors for Comparison, Equals, Exists filters, in addition to equals models and editors based on enums. The models contain all the information detailed , with getters and setters for each field. There is one exception in isDate on Comparison filters. Filter models are created with attributes, and the isDate field is dependent upon a date type field being supplied to the filter model. The models are immutable, and using the setters will return a new instance of the model, with the updated field.
In addition to this, models feature a toImagineFilter method that will return an instance of the filter formatted so be send to the Leverege api. Molten saves the filters that are applied on it to the url parameters. In addition, it reads queries from the url parameters. This allows for filters to be saved through refreshes, in history, and for redirections to have filters pre-applied. Source Models
Filter objects created from these basic models are sufficient for the backend services that need to find data. But they do not always encode enough information for the frontend UIs that need to construct the queries.
Suppose you are working with a Molten UI and looking at a Group Screen that shows a table, a map, and a search bar. Each of those components can contribute to the filter: the table provides column filters (this attribute equals one of these selected items), the map may filter by the currently selected floor of a building, and the search bar provides a free text search of the relevant data. While the backend only cares about the combined filter, the UI needs to know the individual components so it can, e.g., show the correct status of the table filter buttons.
To do this, Molten uses models that encode information about the source of the filter: a FilterSourceModel (a single source’s contribution) and FilterSourcesModel (a combination of filters from various sources).
In most cases, your component will only need to create a FilterSourceModel instance for its individual contribution to the Group Screen filters, and call a onFilterChange method passed down from the Group Screen. The Group Screen will handle the combination operations.