### 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( `
${_.escape(point.getDisplayName() + ': ' + point.getOutDisplay())}
` ); } }); }) .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.