The bajaux framework enables developers to create widgets for Niagara using HTML5 and JavaScript.
Why bajaux?
bajaui is the existing, Java-based, Niagara UI framework for use in Workbench. It has been in use since the very first release of Niagara AX. It is still in widespread use and will be supported for some time. But it has two primary shortcomings that bajaux solves.
With bajaux, Workbench is no longer a requirement.
If you write a view using bajaui, then the only way your customer can access it is through Workbench or a standalone Java application. In many cases, we want them to be able to just open their laptop or phone and start using the software right away, in their web browser. Because bajaux is based on HTML5 and JavaScript, it works natively in the web browser - no Java required.
Write your view once, run it anywhere.
Previously, if you wanted your UI to work natively in both Workbench and the browser, you had to write it at least twice: once using bajaui for use in Workbench, and once using hx for use in the browser. (If you wanted to target the now-deprecated Niagara Mobile framework as well, make that three times!)
Now, bajaux works natively in the web browser. But it also works natively in Workbench! Workbench supports bajaux views through the use of a web browser embedded directly into Workbench. You can write one bajaux view and have it work in Workbench, Px, and the browser. This reduces development effort and ensures that your users get a consistent user experience.
Not only will your widget display in Workbench, it will also integrate into the given environment. For instance, commands defined for any widgets will render in Workbench's Java toolbar. Also, users can drag and drop from the nav tree onto a bajaux widget, both in Workbench and the browser!
Widget
Widget is the core API of bajaux. Adhering to the Widget APIs will ensure your UI works consistently in all supported environments.
A Widget instance is bound to one DOM element. It defines what the contents of that DOM element should be, and how it should behave as the user interacts with it. A Widget can be a single unit, or it can incorporate additional child Widgets for richer functionality.
A Widget has the following behaviors:
- Initialize: when a
Widgetis bound to a DOM element, it can define its initial structure and attach any event handlers needed. - Load: a value (BajaScript or otherwise) can be loaded into a
Widget. - Enable/Disable: a
Widgetcan be enabled/disabled. - Modify: a
Widgetcan be marked modified so the UI knows it has user-entered changes that need to be saved. - Read: the value currently entered by the user can be read from a
Widget. - Save: if a
Widgethas been modified, its changes can be saved. - Validate: a
Widgetcan validate changes entered by the user. - Destroy: a
Widgetcan release any resources it holds when removed from the DOM. - Properties: a
Widgethas Properties that can be used for many applications. - Resolve: a
Widgethas callbacks for resolving specialized data to be loaded. - Commands: a
Widgetcan have Commands added that can be invoked by the user. - Additional Data: a
Widgethas a Form Factor, display name, description, and icon.
Form Factors
In Niagara AX...
- A View is something that occupies most of the UI area in Workbench.
- A Field Editor is quite small and appears alongside other Field Editors on a Property Sheet.
However, these extend from different classes and inherit different sets of functionality. In bajaux, we've separated out the form factor from the capabilities of the Widget. The form factor describes the kind of element in which a Widget may be instantiated, not the behavior of that Widget. This allows Widgets to alter their behavior and layout to function appropriately, whether taking up the full browser window or just one row in a property sheet.
For instance, in bajaux...
- An AX View corresponds to a
Widgetwith a Form Factor of "Max." - An AX Field Editor correspond to a
Widgetwith a Form Factor of "Mini." - For Widgets that appear in a modal dialog - larger than a field editor but smaller than a fullscreen View - there is the Compact Form Factor.
Properties
A Widget has a Properties API which allows it to declare a public set of properties and their values. These Properties will typically be used internally by the Widget to configure its behavior. For instance, when a Widget creates a DOM element of <input type="range">, it may declare properties of min and max to define the range of the input. But the Properties declared by a Widget also form a type of public API for that Widget, one that is used in many different ways:
- When your Widget is embedded in a Px page, its Properties can be edited by the page designer.
- When your Widget is used to edit a Slot value, it will receive the Slot Facets as Properties.
- When a parent Widget creates child Widgets, it can configure the Properties of the children for customized behavior.
- When a Widget is placed on a Dashboard, it can declare Properties as dashboardable and they can be saved per-user.
Subscription
One of the nice features of Niagara AX is BWbComponentView. When extending this Java class, any subclasses automatically get Component subscription/unsubscription handled for them.
The bajaux framework has the same concept. A Widget can be made into a Subscriber Widget by a special Subscriber MixIn. A Subscriber MixIn will use BajaScript to automatically ensure a Component is subscribed and ready before it's loaded. It will also ensure any Components are unsubscribed when the UI is destroyed.
Commands
A module:bajaux/commands/Command is a function that belongs to a Widget, but can be seen and invoked by the user. It is very similar to the existing Command API in bajaui. Some examples are a Save Command, which allows the user to save changes to the Widget, or the Property Sheet's Add Slot Command.
When a Widget exposes Commands, they will appear in the Workbench toolbar or in the main profile's toolbar in the browser. Each Command has metadata to define how it is displayed to the user:
- Display name: formatted in the user's locale.
- Enabled/Disabled: commands that cannot be currently invoked are disabled.
- Flags: a
Commandcan have some flags to indicate whether it should appear in a menu bar, tool bar or both. - Icon: gives the
Commandan icon to make it easily identifiable by the user.
As well as a standard Command, there's also ToggleCommand. A ToggleCommand can have its state toggled. Think of it like a tick box that can be turned on or off.
A number of Command and ToggleCommand objects can be arranged into a tree-like structure by use of a CommandGroup.
Asynchronous Programming
Any modern JavaScript framework has to deal with asynchronous behavior. The bajaux framework has been designed with this in mind from the ground up. Therefore, most of the callbacks that can be overridden can optionally return a promise that can perform an asynchronous operation before resolving. For instance, let's say some extra network calls have to be made during a widget's loading process. The widget's doLoad method can return a promise. The promise can then be resolved when the network calls have completed.
Responsive Layout
Many Widgets need some sort of responsive behavior: they'll need to lay themselves out differently depending on the width and height allotted to them. A Widget in a desktop browser at fullscreen will likely look very different from when it is displayed on a mobile phone.
Most responsive behavior can be handled through pure CSS, which every Widget supports. But one shortcoming of the CSS approach is that one common technique - Media Queries - won't always work. This is because Media Queries target the screen size of the device, while the dimensions of a Widget vary independent of the screen size. For instance, your Widget might be embedded on a Px page, or within the resizable main view pane of Workbench.
Where Media Queries fall short, or just where more complex layout calculations are needed, responsiveMixIn makes it easy to implement responsive behavior in any scenario.
Composition
Many Widgets will want to add additional child Widgets for richer functionality. Although the core Widget API has the built-in capability to initialize child Widgets, the spandrel API makes it even easier to assemble child Widgets and HTML. This increases code reuse and improves maintainability.
Getting Started
Click here to get started!
Also try opening the docDeveloper palette in Niagara to start working with our sample bajaux playground components!