Adaptable Predicate

A Predicate is a type that returns a boolean value and is used in 3 AdapTable Modules:

note

Column Filters only supports Predicates while the other Modules allow objects to use either Predicates or Expressions depending on the complexity required

Predicates are evaluted by AdapTable using AdapTableQL.

Using Predicates

The AdaptablePredicate object has just 2 properties:

PropertyDescription
InputsOptional inputs - needed to evaluate some Predicates (e.g. 'GreaterThan')
PredicateIdId of Predicate (e.g. 'Equals', 'GreaterThan')
note

The Inputs property is required when the Predicate needs additional information for evaluation.

Referencing a Predicate

It is straightforward to create a Predicate in Predefined Config:

predefinedConfig: {
Filter: {
ColumnFilters: [
{
// Using no inputs
ColumnId: 'Price',
Predicate: {
PredicateId: 'Positive',
},
},
{
// Using 1 input
ColumnId: 'OrderId',
Predicate: {
PredicateId: 'GreaterThan',
Inputs: [15],
},
},
{
// Using 2 inputs
ColumnId: 'Age',
Predicate: {
PredicateId: 'Between',
Inputs: [18, 65],
},
},
{
// Providing Values
ColumnId: 'Currency',
Predicate: {
PredicateId: 'Values',
Inputs: ['GBP', 'USD'],
},
],
},
ConditionalStyle: {
ConditionalStyles: [
{
Scope: {
DataTypes: ['Number'],
},
Style: {
ForeColor: 'Green',
},
Rule: {
Predicate: {
PredicateId: 'Positive',
},
},
},
],
},
};

Case Sensitivity

By default text comparisons in Predicates are case insensitive.

Case sensitivity can be applied by setting caseSensitiveTextComparisons to false in General Options.

caution

This will affect Expressions as well as Predicates

generalOptions = {
caseSensitiveTextComparisons: false
};

System Predicates

AdapTable ships with a number of Predicates which are available to use across the product.

Most of these are available in all Modules that use Predicates but there are one or two exceptions. See the list below for more details.

Multiple Variations

warning

Because we wish to ensure that each Predicate is used by one DataType only - we sometimes have more than one predicate for the same type of operation but with a different name

For example AdapTable offer an 'equality' type valuation in 3 different predicates:

  • Number: Equals
  • String: Is
  • Date: On

Likewse there is a Numeric 'GreaterThan' and a Date 'After'

Values Predicate

Most Predicates are relatively straightforward: they take either no inputs (e.g. Blanks) or just 1 (e.g. GreaterThan).

The one exception is the Values Predicate which works like the SQL 'IN' operator.

note

The Values Predicate is only available in Column Filter

It receives an array of values and returns true for each row where the Column contains one of the values.

tip

When selected, AdapTable provides a popup form with a checkbox list of all distinct Column values

System Predicate Example

This definition of the 'GreaterThan' Predicate shows how a Predicate is defined. It has a Column Scope of 'Number' and wide Function Scope, and receives a single input (of type 'number'):

id: 'GreaterThan',
label: 'Greater Than',
icon: { path: 'greater-than' },
columnScope: { DataTypes: ['Number'] },
moduleScope: ['filter', 'alert', 'conditionalstyle'],
inputs: [{ type: 'number' }],
handler: ({ value, inputs }) => Number(value) > Number(inputs[0]),
toString: ({ inputs }) => `> ${inputs[0]}`,
shortcuts: ['>'],

System Predicate List

The Predicates shipped by AdapTable are:

PredicateColumn Data TypeInputsColumn FilterAlertConditional Style
ValuesAll0โœ…
BlanksAll0โœ…โœ…โœ…
NonBlanksAll0โœ…โœ…โœ…
EqualsNumber1โœ…โœ…โœ…
NotEqualsNumber1โœ…โœ…โœ…
GreaterThanNumber1โœ…โœ…โœ…
LessThanNumber1โœ…โœ…โœ…
PositiveNumber0โœ…โœ…โœ…
NegativeNumber0โœ…โœ…โœ…
ZeroNumber0โœ…โœ…โœ…
BetweenNumber2โœ…โœ…โœ…
NotBetweenNumber2โœ…โœ…โœ…
PercentChangeNumber0โœ…
IsNumericNumber0โœ…
IsString1โœ…โœ…โœ…
IsNotString1โœ…โœ…โœ…
ContainsString1โœ…โœ…โœ…
NotContainsString1โœ…โœ…โœ…
StartsWithString1โœ…โœ…โœ…
EndsWithString1โœ…โœ…โœ…
RegexString1โœ…โœ…โœ…
TodayDate0โœ…โœ…โœ…
YesterdayDate0โœ…โœ…โœ…
TomorrowDate0โœ…โœ…โœ…
ThisWeekDate0โœ…โœ…โœ…
ThisMonthDate0โœ…โœ…โœ…
ThisQuarterDate0โœ…โœ…โœ…
ThisYearDate0โœ…โœ…โœ…
InPastDate0โœ…โœ…โœ…
InFutureDate0โœ…โœ…โœ…
BeforeDate1โœ…โœ…โœ…
AfterDate1โœ…โœ…โœ…
OnDate1โœ…โœ…โœ…
NotOnDate1โœ…โœ…โœ…
NextWorkDayDate0โœ…โœ…โœ…
LastWorkDayDate0โœ…โœ…โœ…
RangeDate2โœ…โœ…โœ…
TrueBoolean0โœ…โœ…โœ…
AnyAll0โœ…
ExistingValuesOnlyAll0โœ…
NoDuplicateValuesAll0โœ…
PrimaryKeyDuplicatePK Column0โœ…

Custom Predicates

Developers are encouraged to create their own Predicates at DesignTime via the Custom Predicate Defs section of Adaptable Options.

Once created, they are used in exactly the same way as System Predicates and available in the same Modules.

A Predicate Definition is defined as follows:

PropertyDescription
columnScopeColumns (or DataTypes) where Predicate is active
handlerActual boolean function invoked when evaluating the Predicate
iconIcon to show (primarily used in Filter dropdown)
idUnique Id for the object
inputsInputs the Predicate can take
labelName of the Predicate
moduleScopeAdaptable Modules where Predicate can run
onlyQuickFilterWether to display this predicate only in QuickFilter (and NOT in Column Filter)
shortcutsKeyboard shortcuts to initiate predicate - used in Quick Filter bar
toStringString representation of the Predicate

Id

The name given to the Predicate and how it is referenced in the AdapTable UI

note

The id is the unique identifier for the Predicate - label is used when a more friendly way of identifying the Predicate in the UI is required

Handler

A predicate definition includes a handler function which is invoked each time the predicate is required, and evaluates the contents of the given cell (or alert or data change) against the predicate type and returns either true or false.

note

For instance the Blanks predicate will check all column types to see if the value is empty, while the 'Positive' predicate will check the value of a number cell to see if its greater than 0.

caution

The handler function is a mandatory property

The function receives a PredicateDefHandlerParams object and returns a boolean.

handler: (params: PredicateDefHandlerParams) => boolean;

The PredicateDefHandlerParams is defined as follows:

PropertyDescription
apiThe Adaptable Api
columnColumn which contains the cell
displayValueDisplay value in cell being evaluated
inputsAny inputs required to perform evaluation
nodeRow node which contains the cell
oldValuePrevious value in cell (e.g. if evaluating an edit)
valueRaw value in cell being evaluated

Inputs

Some Predicates require an additional input value in order to perform the evaluation.

For instance 'GreaterThan' compares the input value against base value and returns true if the latter is larger.

The input is passed in as an array. The reason is that while most inputs are a single value, some require 2 inputs (e.g. between) while the 'In' Predicates (also known as 'Values') can take an array of unlimited length.

Column Scope

Each Predicate has a ColumnScope property of type Scope which defines where it can be applied.

note

For System Predicates the Scope is always of type 'DataType' but for Custom Predicates (see below) the Scope can be limited to particular ColumnId(s)

Module Scope

A Predicate also has a ModuleScope which defines in which Modules the Predicate is available.

note

The value will be one, some, or all of Filter, Alert and ConditionalStyle

Custom Predicates Example

/// Create 3 Custom Predicate Defs
// 'High Invoice' which will have a column scope of the 'OrderId' Column
// 'New Starter' which will have a column scope of the 'Employee' Column
// 'Post Takeover' which will have a column scope of all Date Columns
const adaptableOptions: AdaptableOptions = {
customPredicateDefs: [
{
id: 'high_invoice',
label: 'High Invoice',
columnScope: {
ColumnIds: ['OrderId'],
},
moduleScope: ['filter'],
handler(params: PredicateDefHandlerParams) {
const invoiced: number = params.node.data.InvoicedCost;
const itemCount: number = params.node.data.ItemCount;
return invoiced > 100 && itemCount > 10 ? true : false;
},
}
{
id: 'new_starter',
label: 'New Starter',
columnScope: {
ColumnIds: ['Employee'],
},
moduleScope: ['filter', 'conditionalstyle'],
handler(params: PredicateDefHandlerParams) {
return (
params.value == 'Robert King' ||
params.value == 'Laura Callahan' ||
params.value == 'Andrew Fuller'
);
},
},
{
id: 'post_takeover',
label: 'Post Takeover',
columnScope: {
DataTypes: ['Date'],
},
moduleScope: ['filter', 'alert'],
handler(params: PredicateDefHandlerParams) {
const takeOverDate = new Date('2019-09-21');
return (params.value as Date) > takeOverDate;
},
},
],
};
// Create a Column Filter in Predefined Config
// and use the Custom Predicate defined above
predefinedConfig: {
Filter: {
ColumnFilters: [
{
ColumnId: 'OrderId',
Predicate: { PredicateId: 'high_invoice' },
},
],
},
};

Predicate API

The Predicate API section of Adaptable API has a number of functions providing access to Predicates.

caution

Most of these methods are intended for internal use

MethodDescription
getCustomPredicateDefById(predicateId)Gets Predicate Definition provided by users for given Id
getCustomPredicateDefs()Returns Predicate Definitions provided by users
getPredicateDefById(predicateId)Gets the Predicate Definition for a given Id
getPredicateDefs()Returns all current Predicate Definitions
getPredicateDefsByModuleScope(moduleScope)Retrieves all Predicate Definitions for given Module Scope
getSystemPredicateDefById(predicateId)Gets Predicate Definition provided by AdapTable for given Id
getSystemPredicateDefs()Returns Predicate Definitions provided by AdapTable
handlePredicate(predicate, params, defaultReturn)Main Handler function for a Predicate Definition - used by AdapTableQL
isValidPredicate(predicate)Checks whether a given Predicate Definition is valid
predicateToString(predicate)Stringifies a given Predicate Definition

More Information