Show Table of Contents
2.6. Extending Business Central
Starting with version 6.1 of JBoss BPM Suite, Business Central can be configured to add new screens, menus, editors, splashscreens and perspectives by the Administrator. These elements can extend functionality of Business Central and can be accessed through the menu and are classified under
Plugin Management.
You can now define your own Javascript and HTML based plugins to extend Business Central and add them without having to worry about copying files in the underlying filesystem. Let's add a new screen in the system to show you the basics of this functionality.
2.6.1. Plugin Management
You access the
Plugin Management screen by clicking on → . This brings up the Plugin Explorer screen that lists all the existing plugins under their respective categories: Perspective Plugin, Screen Plugin, Editor Plugin, Splashscreen Plugin and Dynamic Menu. Open up any of these and you will see the existing plugins in each category, including the uneditable system generated ones.
Let's create a new plugin that echoes "Hello World" when users visit the screen for that plugin. In general, the steps to creating a new plugin are:
- Create a new screen
- Create a new perspective (and add the new screen to it)
- Create a new menu (and add the new perspective to it)
- Apps (optional)
Adding a new Screen
Click on button and select . You will be prompted to enter the name of this new screen. Enter "HelloWorldJS" and press the button. The Screen plugin editor will open up, divided into 4 sections: Template, CSS, JavaScript and Media.
Note
All manually created elements go into their respective categories in case you want to edit them later. In this case, to open up the Screen plugin editor again if you close it, open up the Screen Plugin category and scroll past the system generated screens to your manually created plugin and click on it to open up the Screen plugin editor again.
Template is where your HTML goes, CSS is for styling, JavaScript is for your functions and Media is for uploading and managing images.
Since we are making a simple Hello World plugin, enter the following code in the Template section:
<div>My Hello World Screen</div>. This can be any HTML code, and you can use the supplied Angular and Knockout frameworks. For the purposes of this example, we are not using any of those frameworks, but you can choose to by selecting them from the drop down in the Template section.
Enter your JavaScript code in the JavaScript section. Some common methods and properties are defined for you, including
main, on_close and on_open. For this demo, select the on_open and enter the following: function () { alert('Hello World'); }
Click the button to finish creating the screen.
Adding a new Perspective
Once a screen has been created, you need to create a perspective on which this screen will reside. Perspectives can also be created similar to the way a screen is created by clicking on button and then selecting, . This will open up the Perspective plugin editor, similar to the Screen plugin editor. .
The Perspective Editor is like a drag and drop grid builder for screens and HTML components. Remove any existing grids in the right hand side and then drag a
6 6 grid on the right hand side.
Next, open up the Components category and drag a Screen Component to the right hand side (in any grid). This will open up the Edit Component dialog box where you can enter your screen created in the previous step (
button to save this perspective. Enter
HelloWorldJS). Click the button and then click the
button to save this perspective. Enter HelloWorldPerspective, enter Home in the tag name field (and click the button), and click the button to finish the save.
If you need to load this perspective again, you will require the name you have given it as this perspective doesn't appear in the list of perspectives. To load, click the
button and enter the perspective name.
button and enter the perspective name.
Adding a new menu
The final step in creating our plugin is to add a dynamic menu from where the new screen/perspective can be called up. To do so, go to → and then click on button to select . Give this dynamic menu a name (HelloWorldMenu) and then click the button. The dynamic menu editor opens up.
Enter the perspective name (HelloWorldPerspective) as the Activity Id and the name for the drop down menu (HelloWorldMenuDropDown). Click and then click the button.
This new menu will be added to your workbench the next time you refresh Business Central. Refresh it now to see added to your top level menu. Click on it to reveal which when clicked will open up your perspective/screen with the message
Hello World.
You have created your first Plugin!
Working with Apps (Optional)
If you create multiple plugins, you can use the Apps directory feature to organize your own components and plugins, instead of having to rely on just the top menu entries.
When you save a new perspective, you can add labels (tags) for them and these labels (tags) are used to associate a perspective with an App directory. You can open up the App directories by clicking on → .
The Apps directory provides an alternate way to open up your perspective. When you created your
HelloWorldPerspective, you entered the tag Home. The Apps directory by default contains a single directory called Home with which you associated your perspective. This is where you will find it when you open the Apps directory. You can click on it to run the perspective now.
You can create multiple directories and associate perspectives with those directories depending on functional and vertical business requirements. For example, you could create an HR directory and then associate all HR related perspectives with that directory to better manage Apps.
You can create a new directory by clicking on:
2.6.2. The JavaScript (JS) API for Extensions
The extensibility of Business Central is achieved by an underlying JavaScript (JS) API which is automatically loaded if it is placed in the
plugins folder of the Business Central webapp (typically: {INSTALL_DIR}/business-central.war/plugins/) or it can be loaded via regular JavaScript calls.
This API is divided into multiple sets depending on the functionality it performs.
- Register Perspective API: allows for the dynamic creation of perspectives. The example below creates a panel using the
registerPerspectivemethod:$registerPerspective({ id: "Home", is_default: true, panel_type: "org.uberfire.client.workbench.panels.impl.MultiListWorkbenchPanelPresenter", view: { parts: [ { place: "welcome", min_height: 100, parameters: {} } ], panels: [ { width: 250, min_width: 200, position: "west", panel_type: "org.uberfire.client.workbench.panels.impl.MultiListWorkbenchPanelPresenter", parts: [ { place: "YouTubeVideos", parameters: {} } ] }, { position: "east", panel_type: "org.uberfire.client.workbench.panels.impl.MultiListWorkbenchPanelPresenter", parts: [ { place: "TodoListScreen", parameters: {} } ] }, { height: 400, position: "south", panel_type: "org.uberfire.client.workbench.panels.impl.MultiTabWorkbenchPanelPresenter", parts: [ { place: "YouTubeScreen", parameters: {} } ] } ] } }); - Editor API: allows you to dynamically create editors and associate them with a file type. The example below creates a sample editor and associates it with
filenamefile type.$registerEditor({ "id": "sample editor", "type": "editor", "templateUrl": "editor.html", "resourceType": "org.uberfire.client.workbench.type.AnyResourceType", "on_concurrent_update":function(){ alert('on_concurrent_update callback') $vfs_readAllString(document.getElementById('filename').innerHTML, function(a) { document.getElementById('editor').value= a; }); }, "on_startup": function (uri) { $vfs_readAllString(uri, function(a) { alert('sample on_startup callback') }); }, "on_open":function(uri){ $vfs_readAllString(uri, function(a) { document.getElementById('editor').value=a; }); document.getElementById('filename').innerHTML = uri; } });In addition toon_startupandon_openmethods seen in the previous example, the API exposes the following callback events for managing the editor's lifecycle:You can display this editor via an html template:- on_concurrent_update;
- on_concurrent_delete;
- on_concurrent_rename;
- on_concurrent_copy;
- on_rename;
- on_delete;
- on_copy;
- on_update;
- on_open;
- on_close;
- on_focus;
- on_lost_focus;
- on_may_close;
- on_startup;
- on_shutdown;
<div id="sampleEditor"> <p>Sample JS editor (generated by editor-sample.js)</p> <textarea id="editor"></textarea> <p>Current file:</p><span id="filename"></span> <button id="save" type="button" onclick="$vfs_write(document.getElementById('filename').innerHTML, document.getElementById('editor').value, function(a) {});">Save</button> <br> <p>This button change the file content, and uberfire send a callback to the editor:</p> <button id="reset" type="button" onclick="$vfs_write(document.getElementById('filename').innerHTML, 'Something else', function(a) {});">Reset File</button> </div> - PlaceManager API: the methods of this API allow you to request that the Business Central display a particular component associated with a target:
$goToPlace("componentIdentifier"); - Register plugin API: the methods of this API allow you to create dynamic plugins (that will be transformed in Business Central screens) via the JS API.
$registerPlugin( { id: "my_angular_js", type: "angularjs", templateUrl: "angular.sample.html", title: function () { return "angular " + Math.floor(Math.random() * 10); }, on_close: function () { alert("this is a pure JS alert!"); } });The plugin references theangular.sample.htmltemplate:<div ng-controller="TodoCtrl"> <span>{{remaining()}} of {{todos.length}} remaining</span> [ <a href="" ng-click="archive()">archive</a> ] <ul class="unstyled"> <li ng-repeat="todo in todos"> <input type="checkbox" ng-model="todo.done"> <span class="done-{{todo.done}}">{{todo.text}}</span> </li> </ul> <form ng-submit="addTodo()"> <input type="text" ng-model="todoText" size="30" placeholder="add new todo here"> <input class="btn-primary" type="submit" value="add"> </form> <form ng-submit="goto()"> <input type="text" ng-model="placeText" size="30" placeholder="place to go"> <input class="btn-primary" type="submit" value="goTo"> </form> </div>A plugin can be hooked to Business Central events via a series of JavaScript callbacks:- on_concurrent_update;
- on_concurrent_delete;
- on_concurrent_rename;
- on_concurrent_copy;
- on_rename;
- on_delete;
- on_copy;
- on_update;
- on_open;
- on_close;
- on_focus;
- on_lost_focus;
- on_may_close;
- on_startup;
- on_shutdown;
- Register splash screens API: use the methods in this API to create splash screens.
$registerSplashScreen({ id: "home.splash", templateUrl: "home.splash.html", body_height: 325, title: function () { return "Cool Home Splash " + Math.floor(Math.random() * 10); }, display_next_time: true, interception_points: ["Home"] }); - Virtual File System (VFS) API: with this API, you can read and write a file saved in the file system using an asynchronous call.
$vfs_readAllString(uri, function(a) { //callback logic }); $vfs_write(uri,content, function(a) { //callback logic })

Where did the comment section go?
Red Hat's documentation publication system recently went through an upgrade to enable speedier, more mobile-friendly content. We decided to re-evaluate our commenting platform to ensure that it meets your expectations and serves as an optimal feedback mechanism. During this redesign, we invite your input on providing feedback on Red Hat documentation via the discussion platform.