### Runtime Usage Example
Source: https://context7.com/tridium/code-samples/llms.txt
This section outlines the steps to set up and observe the implied tag functionality in the Workbench.
```text
// ---- Runtime usage ----
// 1. Add the TagDictionary from the palette to Tag Dictionary Service in Workbench.
// 2. Add a direct tag "townTag" = "London" to any component.
// 3. The framework triggers BCountryRule → BHasTownTagCondition → BCountryTag.
// 4. An implied "countryTag" = "England" automatically appears on that component.
```
--------------------------------
### Usage Example for BCompassEnum
Source: https://context7.com/tridium/code-samples/llms.txt
Demonstrates how to create BCompassEnum instances using the make() method with a tag string or by accessing the DEFAULT constant. Launching Workbench in a German locale will show translated dropdown values.
```java
// ---- Usage ----
BCompassEnum dir = BCompassEnum.make("north"); // => BCompassEnum(0)
BCompassEnum def = BCompassEnum.DEFAULT; // => south (ordinal 1)
// Launch Workbench in German locale to see dropdown show "Nord / Süd / Ost / West":
// wb -locale:de
```
--------------------------------
### Invoke Dynamic Action Programmatically
Source: https://github.com/tridium/code-samples/blob/main/bajaSamples/bajaSamples-rt/src/com/tridiumSamples/bajaSamples/dynamicAction/README.md
Use BComponent#invoke and BComplex#getAction to programmatically run a dynamic action. Pass the action object and any required parameters.
```java
invoke(getAction("myAction"), BString.make("my string value"));
```
--------------------------------
### BRpcUtil.java (Server-side Java)
Source: https://context7.com/tridium/code-samples/llms.txt
This Java class demonstrates how to expose a static method as an RPC endpoint using the @NiagaraRpc annotation. The `findRecordSize` method is made available to BajaScript, allowing it to retrieve the record size of a BHistoryConfig by its ORD.
```APIDOC
## BRpcUtil.java (Server-side Java)
### Description
This class provides a static method `findRecordSize` that can be called remotely from BajaScript. It resolves a given ORD to a `BHistoryConfig` and returns its record size. The `@NiagaraRpc` annotation makes this method accessible.
### Method
`public static int findRecordSize(String targetOrd, Context cx)`
### Parameters
#### Path Parameters
None
#### Query Parameters
None
#### Request Body
None
### Request Example
None (This is a server-side implementation)
### Response
#### Success Response (200)
- **int** - The record size of the `BHistoryConfig`.
#### Response Example
```
35
```
### Error Handling
- `IllegalArgumentException`: If the supplied Ord is blank or if a `BHistoryConfig` is not found at the specified Ord.
- `PermissionException`: If the caller does not have read permissions for the target Ord.
```
--------------------------------
### NEQL and BQL Query Widget in BajaScript
Source: https://context7.com/tridium/code-samples/llms.txt
Implement a widget to query control points using either NEQL or BQL. It subscribes to point changes for live updates and sanitizes display text to prevent XSS.
```javascript
// ---- NeqlAndBqlWidget.js ----
define([
'baja!', 'bajaux/mixin/subscriberMixIn', 'bajaux/Widget', 'underscore'
], function (baja, subscriberMixIn, Widget, _) {
'use strict';
return class NeqlAndBqlWidget extends Widget {
constructor(params) {
super({ params, defaults: { properties: { runNeqlQuery: true } } });
subscriberMixIn(this); // adds this.getSubscriber()
}
doInitialize(jq) {
jq.html(`
NeqlAndBqlWidget
Query Results:
`);
return this.$runQuery();
}
$runQuery() {
const jq = this.jq();
const sub = this.getSubscriber();
const doNeqlQuery = this.properties().getValue('runNeqlQuery');
// Switch between NEQL and BQL ords
const queryOrd = doNeqlQuery
? 'station:|slot:|neql: n:point'
: 'station:|slot:|bql:select from control:ControlPoint';
const ords = [];
return baja.Ord.make(queryOrd).get({
cursor: {
each: (result) => {
if (doNeqlQuery) {
// NEQL result is a BasicEntity → extract the ORD string
ords.push(result.getOrdToEntity().toString());
} else {
// BQL result is a component → get its navOrd property
ords.push(result.get('navOrd'));
}
}
}
})
.then(() => {
// Batch-resolve all collected ORDs and subscribe for live updates
const resolve = new baja.BatchResolve(ords);
const resultsDiv = jq.find('.query-results');
return resolve.resolve({
subscriber: sub,
each: (point) => {
// Escape before inserting into the DOM (XSS protection)
resultsDiv.append(
`
`
);
}
});
})
.then(() => {
// Subscribe to live 'out' changes on each resolved point
sub.attach('changed', function (prop) {
if (prop.getName() === 'out') {
jq.find('.row-' + this.getName())
.text(_.escape(this.getDisplayName() + ': ' + this.getOutDisplay()));
}
});
});
}
};
});
```
```javascript
// ---- Jasmine test ----
const widget = new NeqlAndBqlWidget();
widget.properties().setValue('runNeqlQuery', true); // or false for BQL
return widget.initialize($('')).then(() =>
// Wait until the query results container has 2 rows (test station has 2 control points)
waitForTrue(() => widget.jq().find('.query-results').children().length === 2)
);
```
--------------------------------
### RpcLookupWidget.js (BajaScript / BajaUX front-end)
Source: https://context7.com/tridium/code-samples/llms.txt
This JavaScript code defines a BajaScript widget that invokes the `findRecordSize` RPC method exposed by `BRpcUtil`. It demonstrates how to use `baja.rpc()` to call the Java method and display the returned record size.
```APIDOC
## RpcLookupWidget.js (BajaScript / BajaUX front-end)
### Description
This widget allows users to trigger an RPC call to fetch the record size of a bound `BHistoryConfig`. It uses the `baja.rpc()` function to communicate with the Java backend and updates the UI with the retrieved record size.
### Method
`$lookup()`
### Endpoint
None (This is a client-side JavaScript function)
### Parameters
None
### Request Example
```javascript
// Inside the widget class:
this.$lookup();
```
### Response
#### Success Response
- **recordSize** (string) - The record size obtained from the RPC call, displayed in the UI.
#### Response Example
```
"35"
```
### RPC Invocation Details
#### `retrieveRecordSizeByRpc(config)`
- **Purpose**: Calls the Java `@NiagaraRpc` method `findRecordSize` via `baja.rpc()`.
- **Arguments**: Takes a `config` object (expected to be a `BHistoryConfig`) and uses its navigation ORD.
- **RPC Call**:
```javascript
baja.rpc({
typeSpec: 'rpcSamples:RpcUtil',
method: 'findRecordSize',
args: [ config.getNavOrd().toString() ]
});
```
- **Resolution**: Resolves with the integer record size returned by the Java method.
```
--------------------------------
### Register Lexicon Files in XML
Source: https://context7.com/tridium/code-samples/llms.txt
Registers lexicon files with the Niagara framework, specifying language, module, and resource path.
```xml
// ---- module-include.xml (register lexicon files with the framework) ----
//
//
//
//
```
--------------------------------
### Implement Dynamic Action Slot in Niagara Component
Source: https://context7.com/tridium/code-samples/llms.txt
Demonstrates how to add a dynamic action slot to a Niagara component at runtime. The action accepts a BString parameter and its logic is defined in the invoke method. Ensure the parameter type matches when invoking the action.
```java
// ---- BDynamicAction.java ----
@NiagaraType
public class BDynamicAction extends BAction {
@Override
public Type getParameterType() {
return BString.TYPE; // action accepts a BString argument
}
@Override
public BValue getParameterDefault() {
return BString.DEFAULT;
}
/** Core logic executed when the action is triggered. */
@Override
public BValue invoke(BComponent target, BValue arg) throws Exception {
if (!arg.getType().is(getParameterType())) {
throw new IllegalArgumentException("Invalid type " + arg.getType());
}
// ... business logic here ...
LOG.info("dynamic action running with argument: " + arg);
return null; // void return
}
@Override
public Type getReturnType() { return null; }
private static final Logger LOG = Logger.getLogger(BDynamicAction.class.getSimpleName());
}
```
```java
// ---- BComponentWithDynamicAction.java ----
@NiagaraType
public class BComponentWithDynamicAction extends BComponent {
@Override
public void started() throws Exception {
// Add the action as a TRANSIENT (non-persisted) dynamic slot on every startup
add(
DYNAMIC_ACTION_NAME,
new BDynamicAction(),
Flags.TRANSIENT
);
// Override the display name shown in Workbench right-click menu
setDisplayName(getProperty(DYNAMIC_ACTION_NAME), BFormat.make(DYNAMIC_ACTION_DISPLAY_NAME), null);
}
public static final String DYNAMIC_ACTION_NAME = "dynamicAction";
private static final String DYNAMIC_ACTION_DISPLAY_NAME = "Run My Dynamic Action";
}
```
```java
// ---- Invoking the action programmatically (e.g., in a test or another component) ----
BComponentWithDynamicAction comp = new BComponentWithDynamicAction();
station.add("myComp", comp);
// After station start, the dynamic action slot exists:
comp.invoke(
comp.getAction(BComponentWithDynamicAction.DYNAMIC_ACTION_NAME),
BString.make("hello world") // => logs "dynamic action running with argument: hello world"
);
// Wrong parameter type throws ActionInvokeException:
// comp.invoke(comp.getAction(DYNAMIC_ACTION_NAME), BInteger.DEFAULT); // throws
```
--------------------------------
### Expose Java Method as RPC Endpoint with @NiagaraRpc
Source: https://context7.com/tridium/code-samples/llms.txt
Annotate a static Java method with @NiagaraRpc to make it callable from BajaScript. Ensure the method signature includes necessary context like 'Context cx'. Permissions and transport types can be specified.
```java
// ---- BRpcUtil.java (server-side Java) ----
@NiagaraType
public class BRpcUtil extends BObject {
/**
* Returns the record size of the BHistoryConfig at the supplied ORD.
* Annotated with @NiagaraRpc so BajaScript can call it via baja.rpc().
*/
@NiagaraRpc(
permissions = "unrestricted",
transports = { @Transport(type = TransportType.box) }
)
public static int findRecordSize(String targetOrd, Context cx) throws IOException {
if (targetOrd.isEmpty()) {
throw new IllegalArgumentException("Supplied Ord is blank");
}
OrdTarget ordTarget;
try {
ordTarget = BOrd.make(targetOrd).resolve(null, cx);
} catch (UnresolvedException ex) {
throw new IllegalArgumentException("Invalid Ord: " + targetOrd);
}
if (!ordTarget.canRead()) { throw new PermissionException(); }
BObject target = ordTarget.get();
if (target instanceof BHistoryConfig) {
return ((BHistoryConfig) target).getRecordSize();
}
throw new IllegalArgumentException("HistoryConfig expected: " + targetOrd);
}
}
```
--------------------------------
### Call Java RPC Method from BajaScript with baja.rpc()
Source: https://context7.com/tridium/code-samples/llms.txt
Use baja.rpc() in BajaScript to call Java methods exposed with @NiagaraRpc. Provide the typeSpec (module:TypeName), method name, and serialized arguments. The RPC call resolves with the return value from the Java method.
```javascript
// ---- RpcLookupWidget.js (BajaScript / BajaUX front-end) ----
define(['baja!', 'bajaux/spandrel', 'log!...'], function (baja, spandrel, log) {
'use strict';
return class RpcLookupWidget extends spandrel((component, { self }) => (
{self.$recordSize}
)) {
/** Trigger an RPC call using the bound HistoryConfig's nav ord. */
$lookup() {
const historyConfig = this.value(); // bound BHistoryConfig
return this.retrieveRecordSizeByRpc(historyConfig)
.then((recordSize) => {
this.$recordSize = String(recordSize); // e.g. "35"
this.$componentWithHistoryName = historyConfig.getParent().getParent().getName();
return this.rerender();
});
}
/**
* Call the Java @NiagaraRpc method via baja.rpc().
* typeSpec must match the module:TypeName registered in module-include.xml.
*/
retrieveRecordSizeByRpc(config) {
return baja.rpc({
typeSpec: 'rpcSamples:RpcUtil', // module:TypeName
method: 'findRecordSize', // @NiagaraRpc method name
args: [ config.getNavOrd().toString() ] // serialized ORD string
});
// Resolves with the int returned by BRpcUtil#findRecordSize, e.g. 35
}
};
});
// ---- Jasmine test showing the contract ----
const widget = new RpcLookupWidget();
spyOn(widget, 'retrieveRecordSizeByRpc').andResolve('35');
return widget.initialize($('')).then(() => widget.load(historyConfig))
.then(() => widget.$lookup())
.then(() => {
expect(widget.$recordSize).toBe('35');
expect(widget.jq().find('.record-size').text()).toBe('35');
});
```
--------------------------------
### English Overrides for BCompassEnum
Source: https://context7.com/tridium/code-samples/llms.txt
Overrides the default English display names for BCompassEnum values to single letters.
```properties
// ---- module.lexicon (English overrides – abbreviate to single letters) ----
// north=N
// south=S
// east=E
// west=W
```
--------------------------------
### BCountryRule: Wire Condition and Implied Tag
Source: https://context7.com/tridium/code-samples/llms.txt
This class wires together a condition and an implied tag. It sets the condition to check for a 'townTag' and defines the 'countryTag' to be implied.
```java
// ---- BCountryRule.java – wires condition + implied tag together ----
@NiagaraType
public class BCountryRule extends BTagRule {
public BCountryRule() {
setCondition(new BHasTownTagCondition()); // fires when townTag is present
getTagList().add("countryTag", new BCountryTag()); // implied tag to inject
}
}
```
--------------------------------
### German Translations for BCompassEnum
Source: https://context7.com/tridium/code-samples/llms.txt
Provides German translations for the BCompassEnum values. Note the unicode escape for 'ü' in 'Süd'.
```properties
// ---- src/lexicons/bajaSamples.lexicon.de (German translations) ----
// north=Nord
// south=S\u00FCd (Süd – note unicode escape for ü)
// east=Ost
// west=West
```
--------------------------------
### French Translations for BCompassEnum
Source: https://context7.com/tridium/code-samples/llms.txt
Provides French translations for the BCompassEnum values.
```properties
// ---- src/lexicons/bajaSamples.lexicon.fr (French translations) ----
// north=Nord
// south=Sud
// east=Est
// west=Ouest
```
--------------------------------
### BCountryTag: Compute Implied Tag Value
Source: https://context7.com/tridium/code-samples/llms.txt
This class computes the value for the implied 'countryTag' based on the town name. It maps specific town names to their corresponding country names.
```java
// ---- BCountryTag.java – computes the implied tag value from the town name ----
@NiagaraType
public final class BCountryTag extends BSimpleTagInfo {
@Override
public Tag getTag(Entity entity) {
return new Tag(getTagId(), calculateTagValue(entity));
}
private BString calculateTagValue(Entity entity) {
// ... resolve townTag from the entity's component ...
String town = /* value of townTag slot */ "";
switch (town) {
case "London": case "Birmingham": case "Brighton": case "Preston": return ENGLAND;
case "Oban": case "Inverness": return SCOTLAND;
case "Llanfairpwllgwyngyllgogeryrchwyrndrobwllllantysiliogogogoch": return WALES;
case "Paris": return FRANCE;
default: return DEFAULT_VALUE;
}
}
// "London" → "England", "Oban" → "Scotland", "Paris" → "France", unknown → "not known"
private static final BString ENGLAND = BString.make("England");
private static final BString SCOTLAND = BString.make("Scotland");
private static final BString WALES = BString.make("Wales");
private static final BString FRANCE = BString.make("France");
private static final BString DEFAULT_VALUE = BString.make("not known");
}
```
--------------------------------
### Define BCompassEnum in Java
Source: https://context7.com/tridium/code-samples/llms.txt
Defines a lexiconized enum BCompassEnum with north, south, east, and west values. Includes methods to create enum instances from ordinal or tag string. The default value is south.
```java
// ---- BCompassEnum.java ----
@NiagaraType
@NiagaraEnum(
range = {
@Range("north"),
@Range("south"),
@Range("east"),
@Range("west")
},
defaultValue = "south"
)
public final class BCompassEnum extends BFrozenEnum {
public static final int NORTH = 0, SOUTH = 1, EAST = 2, WEST = 3;
public static final BCompassEnum north = new BCompassEnum(NORTH);
public static final BCompassEnum south = new BCompassEnum(SOUTH);
public static final BCompassEnum east = new BCompassEnum(EAST);
public static final BCompassEnum west = new BCompassEnum(WEST);
/** Look up by ordinal */
public static BCompassEnum make(int ordinal) {
return (BCompassEnum) north.getRange().get(ordinal, false);
}
/** Look up by tag string */
public static BCompassEnum make(String tag) {
return (BCompassEnum) north.getRange().get(tag);
}
public static final BCompassEnum DEFAULT = south;
private BCompassEnum(int ordinal) { super(ordinal); }
}
```
--------------------------------
### BHasTownTagCondition: Check for Town Tag
Source: https://context7.com/tridium/code-samples/llms.txt
This condition checks if an entity has a 'townTag'. If the condition is met, the associated rule fires, implying a 'countryTag'.
```java
// ---- BHasTownTagCondition.java – condition: does this entity have a townTag? ----
@NiagaraType
public class BHasTownTagCondition extends BTagRuleCondition {
@Override
public boolean test(Entity entity) {
Optional entityOrd = entity.getOrdToEntity();
if (!entityOrd.isPresent()) { return false; }
Optional dict = CompUtil.closestAncestor(asComplex(), BTagDictionary.class);
if (!dict.isPresent()) { return false; }
Id townTagId = Id.newId(dict.get().getNamespace(), BTownTag.TAG_NAME);
BComponent comp = (BComponent) entityOrd.get().get();
BValue tagValue = comp.get(SlotPath.escape(townTagId.getQName()));
return tagValue != null; // true => rule fires => BCountryTag is implied
}
}
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.