Skip to main content

Upgrading BBjGrids

Learn about the steps needed to upgrade existing code written for BBjStandardGrid to BBjGridExWidget.

Overview​

The DWC does not offer a direct 1:1 API compatible implementation of the BBjStandardGrid and its siblings, BBjDataAwareGrid and BBjDataBoundGrid.

Why No Direct Compatibility?​

These grids were written with a legacy 1-tier architecture in mind. When they were brought over to BBj with its Thin Client Architecture, their API could not be implemented with the same performance. The event callbacks and routines these grids offered through their API result in a substantial amount of round trips between the server and the client.

BBjGridExWidget Plug-in​

The BBjGridExWidget Plug-in has been written with best-possible performance for the Thin Client and the Web Browser in mind. It's built on a leading third-party implementation of a powerful data grid, built in JavaScript and TypeScript.

The BBjGridExWidget works well in the DWC, which is why this course proposes it as one potential upgrade path for your existing data grids.

Resources​

Differences Between BBjStandardGrid and BBjGridExWidget​

Data Structure​

BBjStandardGridBBjGridExWidget
Filled cell-by-cell or using BBjVectorBuilt as a data grid based on a collection of records
Records correspond to rows, field list defines columns

Supported Data Types​

The BBjGridExWidget and the basiscomponents library support:

  • Core BBx types: String, Numeric, Integer values
  • Common SQL data types: Boolean, Dates, Timestamps

This means:

  • No separate code needed to convert from/to Strings
  • Data flows efficiently between database and UI when using standard SQL databases (BBj ESQL, MySQL, Postgres, etc.)

Additional Features​

The BBjGridExWidget offers user convenience features:

  • Drag and drop of columns
  • Switching column visibility
  • Many more built-in features

Enhanced Version​

The enhanced version (available for rent) provides additional features:

  • Pivot tables
  • Tree grid display
  • Charting capabilities

Refer to the plug-in's homepage and the overview document to learn more.

Install the Plug-In​

Use the Plug-In Manager to install the BBjGridExWidget on your system. You can find the Plug-In Manager in the start menu, or type RUN "PM" in a BBj console. This assumes you use the default PREFIX, which contains the <bbx>/plugins directory.

The Plug-In Manager comes with a getting started document that describes the steps to install a plug-in.

Inspect the Demos​

The BBjGridExWidget comes with demo programs that you can start from the Plug-In Manager. The demos show how to implement functionality that this course does not cover. To read the source code, open the BBjGridExWidget plug-in folder in your IDE, then load and run the demo programs.

Review the JavaDoc​

The BBjGridExWidget API is documented in JavaDoc format. Besides the demos, the JavaDoc pages are the most important source of information about the grid and the methods it exposes.

Working with ResultSet and DataRow​

The central classes for data handling, not only for the BBjGridExWidget, live in the basiscomponents library.

A DataRow holds an entire record of a data table. It consists of fields that each have a name and a type. The supported data types are the ones most current SQL databases know, not just the numbers and strings of the legacy BBx language. If you know the BBjTemplatedString, think of a DataRow as its counterpart: it implements most of the same methods. It can also convert from and to BBj strings by using the string templates you know from the BBx language.

A ResultSet is a collection of DataRows. Besides holding the data, it offers convenience methods that convert to and from JSON, to Excel, to CSV, or to a JRDataSource for use with JasperReports.

Creating a new DataRow from code

The following snippet creates a DataRow and sets two string fields and one field that contains a java.sql.Date. Like BBjTemplatedStrings, the DataRow can also hold field attributes.

use com.basiscomponents.db.DataRow
record! = new DataRow()
record!.setFieldValue("LAST_NAME","Picard")
record!.setFieldValue("FIRST_NAME","Jean-Luc")
record!.setFieldValue("DOB",java.sql.Date.valueOf("2305-07-23"))
record!.setFieldAttribute("DOB","DATEMASK","%Dl, %Dz. of %Ml, %Yl")
PRINT
: record!.getFieldAsString("LAST_NAME")+", "+
: record!.getFieldAsString("FIRST_NAME")+", born "+
: DATE(record!.getFieldAsNumber("DOB"):
: record!.getFieldAttribute("DOB","DATEMASK"))

You instantiate the DataRow with the new keyword, like most Java classes. Then you use setFieldValue to set the field contents. Unlike the classic BBj templated strings, the DataRow can add fields dynamically and does not need to be initialized with DIM.

Upgrading existing code that uses BBx templated strings

The DataRow class has a factory method, fromTemplate, that creates a DataRow from a BBx string template and a plain string. The string is typically a record that comes from a data file. Changing the previous sample to start from a BBx string template shows the concept:

use com.basiscomponents.db.DataRow
TPL$="LAST_NAME:C(25*),FIRST_NAME:C(25*),DOB:N(7)"
DIM R$:TPL$

R.LAST_NAME$="Picard"
R.FIRST_NAME$="Jean-Luc"
R.DOB=JUL(2305,7,23)

record! = DataRow.fromTemplate(TPL$,R$)
PRINT
: record!.getFieldAsString("LAST_NAME")+", "+
: record!.getFieldAsString("FIRST_NAME")+", born "+
: DATE(record!.getFieldAsNumber("DOB"):"%Dl, %Dz. of %Ml, %Yl")

Combining DataRows into a ResultSet

To load a grid with data, you combine the single records into a ResultSet. Create the ResultSet with new, then use the add method to add the records:

use com.basiscomponents.db.DataRow
use com.basiscomponents.db.ResultSet
rs! = new ResultSet()

record! = new DataRow()
record!.setFieldValue("LAST_NAME","Picard")
record!.setFieldValue("FIRST_NAME","Jean-Luc")
rs!.add(record!)

record! = new DataRow()
record!.setFieldValue("LAST_NAME","Spock")
record!.setFieldValue("FIRST_NAME","S'Chn T'Gai")
rs!.add(record!)

record! = new DataRow()
record!.setFieldValue("LAST_NAME","Uhura")
record!.setFieldValue("FIRST_NAME","Nyota")
rs!.add(record!)

You can give the resulting rs! variable to the BBjGridExWidget to load it with data.

Loading a ResultSet from SQL

If your data comes from SQL, you can create a ResultSet directly with SqlQueryBC:

use com.basiscomponents.db.ResultSet
use com.basiscomponents.bc.SqlQueryBC
sbc! = new SqlQueryBC(BBjAPI().getJDBCConnection("CDStore"))
rs! = sbc!.retrieve("SELECT * FROM CDINVENTORY")

The CDStore sample of the BBjGridExWidget uses this method to retrieve the data and post it to the grid.

Set Up a Simple BBjGridExWidget​

You can load the ResultSet from the previous section into a BBjGridExWidget with the setData method of its API:

use ::BBjGridExWidget/BBjGridExWidget.bbj::BBjGridExWidget
use com.basiscomponents.db.ResultSet
use com.basiscomponents.db.DataRow

wnd! = BBjAPI().openSysGui("X0").addWindow("Hello BBj DWC", $01111083$)
wnd!.setPanelStyle("height","100%")

cw! = wnd!.addChildWindow("",$00108000$,BBjAPI().getSysGui().getAvailableContext())
cw!.setStyle("height","100%")
cw!.setStyle("width","100%")
grid! = new BBjGridExWidget(cw!)

rs! = new ResultSet()

record! = new DataRow()
record!.setFieldValue("LAST_NAME","Picard")
record!.setFieldValue("FIRST_NAME","Jean-Luc")
rs!.add(record!)

record! = new DataRow()
record!.setFieldValue("LAST_NAME","Spock")
record!.setFieldValue("FIRST_NAME","S'Chn T'Gai")
rs!.add(record!)

record! = new DataRow()
record!.setFieldValue("LAST_NAME","Uhura")
record!.setFieldValue("FIRST_NAME","Nyota")
rs!.add(record!)

grid!.setData(rs!)

process_events

Run this program in the DWC. The grid takes the full browser canvas to display the BBjGridExWidget.

Styling and Configuring the Grid​

With the basic loading of data working, you can look at examples for often needed functionality. You find the demos in the demo subfolder of the BBjGridExWidget plug-in on your disk, or you can browse them online on GitHub.

Migration Steps​

When migrating from BBjStandardGrid to BBjGridExWidget:

  1. Review your data structure - Convert cell-by-cell population to record-based approach
  2. Update data types - Take advantage of native type support
  3. Adapt event handling - Update callbacks to use BBjGridExWidget events
  4. Test thoroughly - Ensure all grid functionality works in DWC