Make the following changes, ignoring the error marks:
selectionListeners ::= cellClicked,
The selectionListeners property specifies one or more functions that are called whenever the user selects a cell in the grid. In this case, you are appending a function name to a pre-existing array. You will write the cellClicked function later in this lesson.
, formatters = [ formatCategory ]
, alignment = DataGridLib.ALIGN_RIGHT
allPayments_ui DataGrid {
layoutData = new GridLayoutData
{row = 2, column = 1,
verticalAlignment = GridLayoutLib.VALIGN_TOP},
selectionListeners ::= cellClicked,
columns =[
new DataGridColumn{name = "category",
displayName = "Type",
width = 90,
formatters = [formatCategory]},
new DataGridColumn{name = "description",
displayName = "Description",
width = 120},
new DataGridColumn{name = "amount",
displayName = "Amount due",
width = 90,
alignment = DataGridLib.ALIGN_RIGHT}
],
data = allPayments as any[],
selectionMode = DataGridLib.SINGLE_SELECTION};
The cellClicked function is invoked when the user clicks a cell in the data grid.
function cellClicked(myGrid DataGrid in)
selectedPayment = allPayments_ui.getSelection()[1] as paymentRec;
selectedPayment_form.publish();
end
First, the cellClicked function updates the selectedPayment record with data from a single data-grid row. That row can include more fields than are displayed to the user. In this application, the single row in the data grid will have come from a single row in the database.
The Form Manager provides various benefits but is essentially a collection of controllers.
data = allPayments as any[]
allPayments_ui.getSelection()[1] as paymentRec
In each case, the as clause provides the necessary cast.
To add the formatter function:
function formatCategory(class string, value string, rowData any in)
value = PaymentLib.getCategoryDesc(value as INT);
end
Formatters have the parameters shown. In this case, the formatter wraps a library function you created earlier.
You can test your recent changes even before you gain access to the database.

function start()
allPayments_ui.data =[
new paymentRec{
category = 1, description = "test01", amount = 100.00
, payeeName = "Someone"},
new paymentRec{category = 2, description = "test02", amount = 200.00},
new paymentRec{category = 3, description = "test03", amount = 300.00}];
end


/*
You can add comments in either of two ways.
*/
You now declare a service-access variable, which will let you communicate with the service that you defined earlier.
To create the variable:
dbService SQLService{@dedicatedService};
The @dedicatedService property indicates that the service being referenced is a dedicated service, which will be deployed with the Rich UI handler.
In the following display, the red X in the margin indicates a problem in the code:

To see the error message, move the cursor over the X.
Begin by creating the function that reads all data.
function readFromTable()
call dbService.getAllPayments() returning to updateAll
onException serviceLib.serviceExceptionHandler;
end
The two are callback functions, which are invoked by the EGL runtime code after the service responds or fails. If the service returns a value successfully, the updateAll function is invoked. If the call fails, the EGL runtime code invokes a function that is associated with the name serviceLib.serviceExceptionHandler.
By default, an error results in the display of error information in the Console view (at development time) or at the bottom of the web page (at run time). However, you can specify an error handler of your own, typically by assigning a function name in place of serviceLib.serviceExceptionHandler.

Next, create the function that adds sample data.
function sampleData(event Event in)
call dbService.createDefaultTable() returning to updateAll
onException serviceLib.serviceExceptionHandler;
end
You do not use the Create Callback Functions feature because the callback functions exist.
Next, create the function that adds data.
function addRow(event Event in)
call dbService.addPayment(new paymentRec) returning to recordAdded
onException serviceLib.serviceExceptionHandler;
end
Create the function that deletes data.
function deleteRow(event Event in)
for(i INT from 1 to allPayments.getSize())
if(allPayments[i].paymentID == selectedPayment.paymentID)
allPayments.removeElement(i);
exit for;
end
end
call dbService.deletePayment(selectedPayment) returning to recordRevised
onException serviceLib.serviceExceptionHandler;
end
To initialize the data grid, add the following code before the end statement of the start function:
readFromTable();
Although you could have assigned the readFromTable function directly to the onConstructionFunction property, you are advised to retain the start function as a separate unit of logic in case you later decide to add other code that runs before the web page is rendered.
Retain the commented code in the start function in case you need to test the web page without accessing the database. You can use the comment and uncomment capability of the Rich UI editor to quickly switch from the function call to the prototype data and back again.
The updateAll function receives an array of paymentRec records from the dedicated service. The function is called in the following ways:
function updateAll(retResult paymentRec[] in)
allPayments = retResult;
allPayments_ui.data = allPayments as any[];
end
The function updates the global
array of payment records with the data received from the service and
then refreshes the data grid.The recordAdded function receives the record that was sent to and returned by the service function addPayment.
function recordAdded(newPayment paymentRec in)
readFromTable();
end
The function readFromTable reads
all the rows from the database. The data stored by the grid can then
contain the new row, including the paymentID value
that was automatically generated by the database and that is otherwise
unavailable to the grid.The recordRevised function receives the record that was sent to and returned by the service function addPayment.
function recordRevised(delPayment paymentRec in)
allPayments_ui.data = allPayments as any[];
end
The function refreshes the data grid.

If you exit and restart the workbench before you complete this tutorial, this window might be re-displayed the next time you attempt to access the database.
Eventually the grid is re-displayed with rows of sample data.



In the next lesson, you will complete the code for the Rich UI handler.