Difference between revisions of "EDT:Tutorial: RUI With DataBase Lesson 8"

From Eclipsepedia

Jump to: navigation, search
(Test the interface)
Line 3: Line 3:
  
 
{| style="float: right"
 
{| style="float: right"
|[[EDT:Tutorial: RUI With DataBase Lesson 7|< Previous]] | [[EDT:Tutorial: RUI With DataBase Lesson 9|Next >]]
+
|[[EDT:Tutorial: RUI With DataBase Lesson 6|< Previous]] | [[EDT:Tutorial: RUI With DataBase Lesson 8|Next >]]
 
|}
 
|}
= Lesson 8: Add variables and functions to the Rich UI handler =
+
= Lesson 7: Create a library of reusable functions =
  
Add source code that supports the user interface.In lessons 8 and 9, you update the EGL source code directly
+
Create a library to format money values and to associate
and review changes in the Preview tab.
+
category numbers with descriptions.Libraries contain functions, constants, and variables that
 +
you can use in multiple locations.  
  
== Add code to support the data grid ==
+
When you reference a declaration
 +
in the library from other logic such as a service or handler, you
 +
can include the library name as a prefix. For example, '''MyLibrary.myLibraryVariable''' is
 +
appropriate if the library name is '''MyLibrary''' and
 +
the library includes the '''myLibraryVariable''' variable.
 +
Alternatively, you can include the library name in a '''use''' statement
 +
in the other logic and avoid the need to qualify every reference.
 +
In that case, '''myLibraryVariable''' is sufficient to
 +
reference that variable.
  
Change the declaration of the data grid for two purposes: to
+
== Create a Library part ==
cause the web page to react when the user selects a cell and to ensure
+
that the grid output is formatted correctly.
+
  
<ol><li>In Project Explorer, open '''PaymentClient''' &gt; '''EGLSource''' &gt; '''handlers''' and double-click '''PaymentFileMaintenance.egl'''.
 
<li>Click on the Source tab.
 
</ol>
 
  
Make the following changes, ignoring the error marks:
 
  
In the '''allPayments_ui''' DataGrid declaration,
+
To create a Library part:
add the following code immediately before the '''columns''' property:  
+
  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 are functions that change the appearance of
+
*Right-click the PaymentClient folder, then click '''New''' &gt; '''Library'''.
the values in DataGrid columns. To demonstrate the feature, find the
+
*In the New EGL Library window, enter the following information:
DataGridColumn declaration for category. To ensure that the user sees
+
**In the '''EGL source file name''' field, enter the name '''PaymentLib'''.
a category description rather than an integer, add this code after '''width=90''':
+
**In the '''Package''' field, enter the name '''libraries'''.
  , formatters = [ formatCategory ]
+
**Under '''EGL Library Type''', leave the default value of '''Basic''' selected.
When you display dollar amounts in a column, you typically
+
:The new Library part opens in the EGL editor.
right-align the values. You do not need to code a function to cause
+
*Replace the boilerplate code in the Library part with the following lines:  
right-alignment. Instead, add this code after the '''width''' entry
+
   package libraries;
for amount:
+
 
  , alignment = DataGridLib.ALIGN_RIGHT
+
  library PaymentLib {}
The '''allPayments_ui''' declaration
+
   
is now as follows, with error marks for '''cellClicked''' and '''formatCategory''':
+
      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};
+
 
+
Save the file before going on to the next step.
+
 
+
== Code the function that responds when the user clicks the data grid ==
+
 
+
The '''cellClicked''' function is invoked when
+
the user clicks a cell in the data grid.
+
 
+
Immediately below the '''start''' function,
+
add the following lines:
+
   function cellClicked(myGrid DataGrid in)
+
      selectedPayment = allPayments_ui.getSelection()[1] as paymentRec;
+
      selectedPayment_form.publish();
+
 
   end
 
   end
 +
*Save the file.
  
First, the '''cellClicked''' function
+
== Create the categories array ==
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.
+
  
Second,
+
Add the following code before the final '''end''' statement:
the '''publish''' function causes the transfer
+
<code>
of data from the '''selectedPayment''' record to the '''selectedPayment_ui''' layout.
+
       categories string[] =[
That transfer is made possible by code that was provided for you when
+
you created the '''selectedPayment_ui''' layout, which
+
is the single-record layout at the right of your web page. If you
+
review the code, you can trace the relationships: 
+
 
+
<ul><li>A Form Manager declaration includes form fields.
+
<li>Each form field references a controller declaration.
+
<li>The controller declaration relates a model to a view; in this
+
case, a field of the '''selectedPayment''' record to a
+
child of the '''selectedPayment_ui''' layout.
+
</ul>
+
 
+
The Form Manager provides various benefits but is essentially
+
a collection of controllers.
+
 
+
Here is an explanation of two other
+
issues&quot;”the use of the bracketed array index ('''[1]'''),
+
and the use of the '''as''' operator:
+
 
+
<ol><li>The '''getSelection''' function always returns
+
a subset of the rows in the '''data''' array of
+
the data grid. However, when you declared the data grid, you specified
+
the following setting to indicate that the user can select only one
+
row at a time: '''selectionMode = DataGridLib.SINGLE_SELECTION'''.
+
When the user can select only one row, only one element is available.
+
<li>Every element in the array returned by a '''getSelection''' function
+
is of type ANY. You typically use the same Record part to process
+
input to the grid and to process output from the grid, and in this
+
tutorial, the Record part is '''paymentRec'''. The Record
+
part has the following uses:
+
</ol>
+
:*To be the basis of the array elements that you assign to the '''data''' property of the data grid, as shown in the following setting:
+
  data = allPayments as any[]
+
:*To cast the array element that is returned by the '''getSelection''' function of the data grid, as shown here:
+
  allPayments_ui.getSelection()[1] as paymentRec
+
 
+
In each case, the '''as''' clause provides
+
the necessary cast.
+
 
+
== Format column values in the grid ==
+
 
+
To add the formatter function:
+
 
+
*Add the following code before the final '''end''' statement in the file:  
+
  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.
+
*Press Ctrl-Shift-O to organize the required import statements and save the file. All the error marks disappear.
+
 
+
== Test the formatting of the data grid and the transfer of data to the single-record layout ==
+
 
+
You can test your recent changes even before you gain
+
access to the database.
+
 
+
*Click the Preview tab and note that the categories are now descriptions (for example, '''Rent''' rather than '''1'''). [[Image:EDT_Tutorial_edt_richui_sql08_formatted_grid.jpg|The formatted data grid]]
+
*Click one or another row in the data grid and note that the single-row layout is updated appropriately. However, the formatter affected only the data grid, and the description field in the single-row layout contains a numeric. The tutorial will address that issue later.
+
*Click the Source tab and change the '''start''' function so that the first record in the prototype data includes a value for '''payeeName''', which is a '''paymentRec''' record field that is not displayed by the data grid: 
+
  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
+
*Click the Preview tab and click the first row in the data grid. [[Image:EDT_Tutorial_edt_richui_sql08_prototype_and_all_plus.jpg|The data transferred from data grid to the single-record layout]]
+
 
+
As shown, you can switch quickly from one tab in the Rich
+
UI editor to another, to test even a small change.
+
 
+
== Comment the prototype data ==
+
 
+
You can comment or uncomment code quickly, as shown in this
+
step.
+
 
+
*Click the Source tab.
+
*In the '''start''' function, select the complete assignment statement, right-click the area selected, and click '''EGLSource > Toggle Comment'''. [[Image:EDT_Tutorial_edt_richui_sql08_toggle_comments.jpg|The selection of code and the Comment menu item]]
+
*Comment marks (//) are now at the start of each line. You could remove the comments by selecting the commented statements and repeating the task. However, leave the comments in place.  EGL also supports the use of slash asterisk (/*) and asterisk slash (*/) delimiters, as shown here:
+
  /*
+
       You can add comments in either of two ways.
+
  */
+
 
+
== Declare a service-access variable ==
+
 
+
You now declare a service-access variable, which will
+
let you communicate with the service that you defined earlier.
+
 
+
To create the variable:
+
 
+
*Near the top of the EGL source code, find the handler declaration for '''PaymentFileMaintenance'''. Add a blank line, and immediately before the '''ui''' GridLayout declaration, add the following statement:
+
  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: [[Image:EDT_Tutorial_edt_richui_sql08_red_x.jpg|The declaration of the service-access variable, in code]]
+
 
+
:To see the error message, move the cursor over the X.
+
 
+
*Fix the '''unresolved type''' error by pressing Ctrl+Shift+O. The new '''import''' statement provides access to the '''services''' package, '''SQLService''' part, which is in the '''PaymentService''' project. The reference to '''SQLService''' is resolved because that project is on the EGL build path of the '''PaymentClient''' project.
+
*Save the file.
+
 
+
== Create functions that use the service-access variable to invoke the service ==
+
 
+
You now create several functions to invoke different functions
+
in the dedicated service. Once you understand how to set up one invocation,
+
the others are straightforward.
+
 
+
First add a service exception handler and logging functions prior to the final '''end''' statement.  Include the following code:
+
  function serviceExceptionHandler(ex anyException)
+
        try
+
            throw ex;
+
        onException(serviceEx ServiceInvocationException)
+
            log("Failure:  service invocation, exception = " +
+
                            serviceEx.message);
+
            log("Detail 1:  " + serviceEx.detail1);
+
            log("Detail 2:  " + serviceEx.detail2);
+
            log("Detail 3:  " + serviceEx.detail3);
+
        onException(anyex anyException)
+
            log("Failure:  service invocation, exception = " + anyex.message);
+
        end
+
        throw ex;
+
  end
+
 
    
 
    
  logActive boolean = true;
+
                      "Rent",          // 1
 
+
                      "Food",          // 2
   function log(text string in)
+
                      "Entertainment", // 3
        if(logActive)
+
                      "Automotive",   // 4
            sysLib.writeStderr(text);
+
                      "Utilities",    // 5
        end
+
                      "Clothes",      // 6
  end
+
                      "Other"          // 7
 +
              ];
 +
</code>
 +
The value is an array, and as is true of all arrays
 +
in EGL, the index of the first element is 1, not 0.
  
Then include the function that reads all data from the table.  Leave a blank line after the ''cellClicked''' function and add the following code:   
+
The array
  function readFromTable()
+
is used in logic that acts as follows:
      call dbService.getAllPayments() returning to updateAll
+
        onException serviceExceptionHandler;
+
  end
+
 
+
'''Notes:'''
+
<ol><li>The '''call''' statement in Rich UI is a variation
+
used only to access services. The runtime communication in this case
+
is asynchronous, which means that the user can continue to interact
+
with the handler while the service is responding.
+
<li>The asynchronous '''call''' statement includes
+
two function names:
+
  
<ul><li>'''updateAll'''
+
<ul><li>Places an expense category into the database in integer form,
<li>'''serviceExceptionHandler'''
+
to save space.
 +
<li>Places the expense category onto the web page in string form,
 +
for clarity.
 
</ul>
 
</ul>
  
The two are ''callback functions'', which are invoked
+
== Create the get functions for categories ==
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 the function
+
named '''serviceExceptionHandler'''.
+
  
Our example exception handler function just displays the exception messages
+
The next functions convert between the following two formats
in the display of error information in the
+
for expense categories: integer and string.
at the bottom of the web page
+
(at run time). However, you would typically an error handler of your own that might log the error information, but display a message to the user saying something like &quot;Your request cannot be completed at this time.&quot;
+
</ol>
+
Now, to create the '''updateAll''' callback function, click anywhere in the '''call''' statement,
+
right-click, and click '''Create Callback Functions'''.
+
Alternatively, you could clicked anywhere in the statement, held down
+
the Ctrl key, and pressed 1. [[Image:EDT_Tutorial_edt_richui_sql08_callback.jpg|The Create Callback Functions option]]
+
EGL creates an empty '''updateAll''' function.
+
An error handler would have been created as well if you had not already included a function named '''serviceExceptionHandler''' in the program.
+
  
The
+
Add the following code before the final '''end''' statement:
parameter list in the created '''updateAll''' function
+
<code>
is equivalent to the type of return value that is expected from the
+
      function getCategoryDesc(cat int in) returns(string)
service. Here are the relationships that explain the behavior of the
+
          if(cat != 0)      // the integer is not 0
Rich UI editor:
+
              return(categories[cat]);
 +
          else
 +
              return("");
 +
          end
 +
      end
 +
</code>
 +
The function receives the integer format of an expense
 +
category and returns the related array element. If the input value
 +
is 0, the function returns an empty string.
  
<ul><li>The parameter list in the callback function is correct because
+
Add the following code before the final '''end''' statement:
the '''getAllPayments''' function in the Service part is
+
<code>
available to the editor.
+
      function getCategoryNum(desc string in) returns(int)
<li>The function is available because you resolved the reference to
+
          for(i int from 1 to categories.getSize())
the '''SQLService''' part in a previous step.
+
              if(categories[i] == desc)
</ul>
+
                  return(i);
+
              end
Next, create the function that adds sample data.  Click Ctrl-F to gain access to the Find/Replace dialog,
+
          end
type '''SampleData''', and click '''Find'''.
+
          return(0); // no match
Update the '''sampleData''' function so that
+
      end
the code is as follows:
+
</code>
  function sampleData(event Event in)
+
This function receives the string format of an expense
      call dbService.createDefaultTable() returning to updateAll
+
category and returns the integer format, if possible. If no match
        onException serviceExceptionHandler;
+
is found for the received string, the function returns 0.
  end
+
You do not use the '''Create Callback Functions''' feature
+
because the callback functions exist.  
+
  
Next, create the function that adds data.  Update the '''addRow''' function so that the
+
== Save your changes ==
code is as follows:
+
  function addRow(event Event in)
+
      call dbService.addPayment(new paymentRec) returning to recordAdded
+
        onException serviceLib.serviceExceptionHandler;
+
  end
+
Click anywhere in the '''call''' statement,
+
right-click, and click '''Create Callback Functions'''. EGL adds the '''recordAdded''' function.
+
  
Now create the function that deletes data.  Update the '''deleteRow''' function so that
+
The complete your coding of the payment library:
the code is as follows:  
+
  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  serviceExceptionHandler;
+
  end
+
  
The function acts as follows:
+
#Format the file.
<ul><li>Deletes the selected row from the local array of records
+
#Save and close the '''PaymentLib''' Library. If you see errors in your source file, compare your code to the file contents in [[EDT:Tutorial: RUI With DataBase Lesson 7 Code|Code for PaymentLib.egl after lesson 7]].
<li>Calls the database service to delete the row from the database
+
itself
+
</ul>
+
 
+
Now click anywhere in the '''call''' statement,
+
right-click, and click '''Create Callback Functions'''. EGL adds the '''recordRevised''' function.
+
 
+
To complete this step,
+
<ul>
+
<li>Press Ctrl-Shift-F to format the code.
+
<li>Save the file.
+
</ul>
+
''' Related information '''<br>
+
[../../com.ibm.egl.pg.doc/topics/pegl_ui_richui_rest_call_statement.html Invoking a service asynchronously from a Rich UI application]
+
 
+
== Update the start function to initialize the data grid with database rows ==
+
 
+
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.
+
 
+
== Complete the callback functions ==
+
 
+
You now complete the callback functions that were created
+
automatically:
+
 
+
<ul><li>'''updateAll'''
+
<li>'''recordAdded'''
+
<li>'''recordRevised'''
+
</ul>
+
 
+
The '''updateAll''' function receives an array
+
of '''paymentRec''' records from the dedicated service.
+
The function is called in the following ways:
+
 
+
<ul><li>As a callback function at startup, after the '''readFromTable''' function
+
calls the service.
+
<li>As a callback function whenever the user clicks the '''Sample''' button
+
to invoke the '''sampleData''' function.
+
</ul>
+
 
+
Update the '''updateAll''' function so that
+
the code is as follows:
+
  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'''. Update the '''recordAdded''' function so that
+
the code is as follows:
+
  function recordAdded()
+
      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'''.Update the '''recordRevised''' function so that
+
the code is as follows:
+
  function recordRevised()
+
      allPayments_ui.data = allPayments as any[];
+
  end
+
The function refreshes the data grid.
+
 
+
Clean up this step by formatting your code and saving the file.
+
If you see errors
+
in your source file, compare your code to the file contents in [[EDT:Tutorial: RUI With DataBase Lesson 8 Code|Code for PaymentLib.egl after lesson 8]].
+
 
+
== Test the interface ==
+
 
+
Preview your work now that you are accessing a database.
+
 
+
<ol><li>Click the Preview tab. The data grid has
+
no content because you commented out the prototype data, and the database
+
has no rows.<br />[[Image:EDT_Tutorial_edt_richui_sql08_initial_ui.jpg|The initial data grid]]
+
 
+
<li>Click '''Sample''' to create sample data.
+
<li>If EGL requests a password, enter '''admin''' for
+
both the '''User ID''' and '''Password''' fields.
+
Select '''Remember my user ID...''' and click '''OK'''.<br /> [[Image:EDT_Tutorial_edt_richui_sql08_pwd.jpg|The ID and password window]]
+
 
+
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.<br /> [[Image:EDT_Tutorial_edt_richui_sql08_sample_data.jpg|Three payment entries, &quot;œApartment,&quot;? &quot;œGroceries,&quot;? and &quot;œISP&quot;? are displayed]]
+
<li>Click the '''Add''' button.  A new row with a single default value is displayed at
+
the bottom of the grid.<br />[[Image:EDT_Tutorial_edt_richui_sql08_added.jpg|A new row is added]]
+
<li>Select the Apartment row and click '''Delete'''. The row is deleted from both the display and the database.<br /> [[Image:EDT_Tutorial_edt_richui_sql08_deleted.jpg|The &#34;Apartment&#34; row is now gone.]]
+
<li>Click the first row of the data grid.<br />  [[Image:EDT_Tutorial_edt_richui_sql08_transfer_database.jpg|The data grid and single-record layout both contain data from the database.]]
+
Data from the database was transferred
+
from the data grid to the single-record layout. Note that the value
+
of the '''Key''' field reflects how many rows were
+
added to the database and will probably not match the value on your
+
web page.
+
</ol>
+
  
 
== Lesson checkpoint ==
 
== Lesson checkpoint ==
Line 417: Line 113:
 
You learned how to complete the following tasks:
 
You learned how to complete the following tasks:
  
<ul><li>To create formatters.
+
<ul><li>Create a Library part.
<li>To respond to the user's selection in a data grid.
+
<li>Add functions and a variable to a library.
<li>To transfer data from the data grid to a grid layout.
+
<li>To comment and uncomment code.
+
<li>To access services from a Rich UI application.
+
 
</ul>
 
</ul>
 
In the next lesson, you will complete the code for the Rich
 
UI handler.
 
  
 
{| style="float: right"
 
{| style="float: right"
|[[EDT:Tutorial: RUI With DataBase Lesson 7|&lt; Previous]] | [[EDT:Tutorial: RUI With DataBase Lesson 9|Next >]]
+
|[[EDT:Tutorial: RUI With DataBase Lesson 6|&lt; Previous]] | [[EDT:Tutorial: RUI With DataBase Lesson 8|Next >]]
 
|}
 
|}
  
 
[[Category:EDT]]
 
[[Category:EDT]]

Revision as of 15:57, 1 December 2011

Access a database with EGL Rich UI


< Previous | Next >

Contents

Lesson 7: Create a library of reusable functions

Create a library to format money values and to associate category numbers with descriptions.Libraries contain functions, constants, and variables that you can use in multiple locations.

When you reference a declaration in the library from other logic such as a service or handler, you can include the library name as a prefix. For example, MyLibrary.myLibraryVariable is appropriate if the library name is MyLibrary and the library includes the myLibraryVariable variable. Alternatively, you can include the library name in a use statement in the other logic and avoid the need to qualify every reference. In that case, myLibraryVariable is sufficient to reference that variable.

Create a Library part

To create a Library part:

  • Right-click the PaymentClient folder, then click New > Library.
  • In the New EGL Library window, enter the following information:
    • In the EGL source file name field, enter the name PaymentLib.
    • In the Package field, enter the name libraries.
    • Under EGL Library Type, leave the default value of Basic selected.
The new Library part opens in the EGL editor.
  • Replace the boilerplate code in the Library part with the following lines:
  package libraries;
  
  library PaymentLib {}
    
  end
  • Save the file.

Create the categories array

Add the following code before the final end statement:

      categories string[] =[
  
                      "Rent",          // 1
                      "Food",          // 2
                      "Entertainment", // 3
                      "Automotive",    // 4
                      "Utilities",     // 5
                      "Clothes",       // 6
                      "Other"          // 7
              ];

The value is an array, and as is true of all arrays in EGL, the index of the first element is 1, not 0.

The array is used in logic that acts as follows:

  • Places an expense category into the database in integer form, to save space.
  • Places the expense category onto the web page in string form, for clarity.

Create the get functions for categories

The next functions convert between the following two formats for expense categories: integer and string.

Add the following code before the final end statement:

      function getCategoryDesc(cat int in) returns(string)
          if(cat != 0)       // the integer is not 0
              return(categories[cat]);
          else
              return("");
          end
      end

The function receives the integer format of an expense category and returns the related array element. If the input value is 0, the function returns an empty string.

Add the following code before the final end statement:

      function getCategoryNum(desc string in) returns(int)
          for(i int from 1 to categories.getSize())
              if(categories[i] == desc)
                  return(i);
              end
          end
          return(0);	// no match
      end

This function receives the string format of an expense category and returns the integer format, if possible. If no match is found for the received string, the function returns 0.

Save your changes

The complete your coding of the payment library:

  1. Format the file.
  2. Save and close the PaymentLib Library. If you see errors in your source file, compare your code to the file contents in Code for PaymentLib.egl after lesson 7.

Lesson checkpoint

You learned how to complete the following tasks:

  • Create a Library part.
  • Add functions and a variable to a library.
< Previous | Next >