VRAD With Developer/2000: The Next Generation
Dr. Paul Dorsey, Dulcian, Inc.
Peter Koletzke, Millennia
Vision Corp.
Introduction
When building applications in GUI or character mode, much of the work is repetitive. Major portions of each application are similar to many other applications. There has to be a way to re-use all that work. Very Rapid Application Development (VRAD) is possible with Developer/2000 Forms through the smart use of templates. A template form enables developers to generate simple applications in minutes and complex applications in a fraction of the time normally required.
The benefits of using a template are numerous. The most obvious are the immediate productivity gains. However, just as important are the benefits that arise from enforcement of standards throughout your applications. Not only do you automatically get similarity in the visual look and feel of your applications; but you also get similarity in the coding practices. Most of the major triggers are already written, and need only be modified by individual developers.
Another benefit is that the creation of the template forces you to seriously think through the process of GUI standards. There is no way to create the template without going through the process of making decisions about the look and feel of each kind of application and how those application types will interact. We have never had the experience where a company actually thought through their GUI standards to the level necessary to enforce standards without developing a template.
Next, there is a real benefit to the novice developer. Many developers are not comfortable with the amount of latitude that GUI development gives them. They find themselves lost in a daunting list of possible triggers and options. The skilled C++ programmer fights the tool trying to force it to act exactly like their favorite C++ program. Less skilled developers and kids fresh out of college take weeks to build simple forms. With a template approach, novice developers can build simple forms almost as quickly as experienced developers. This frees up the experienced developers to work on the key applications.
Finally, working with a template is fun. The developer does not need to spend hours of tedious time when building an application, but can concentrate his/her time on the interesting parts of the application. It is much more fun to build applications when you don’t have to spend hours doing work that you are sure a less-skilled developer could do just as well.
Levels of Template Development
Our thinking with respect to templates has evolved over the last few years. All four levels of templates that we have developed are all still in use although each has become more sophisticated over time. Each one builds on the previous level of template. Most developers are now using templates when building forms. However, most are still using templates that in this taxonomy would be classified as Level 1 templates. Although all four levels of templating are possible with Forms 4.5, Forms in Developer/2000 2.0 will make it even easier to employ all levels of templates.
In this section we will discuss the three levels of template development and the architecture associated with each one:
Level I – Base template
Level 1 uses a single template for every form. The template contains referenced objects to support GUI standards, example objects and code, and attached libraries. The idea is to provide a starting point for developers that makes development more efficient and helps to encourage consistent application of GUI, coding and development standards. Such templates can be extraordinarily rich and complex but often suffer from being too generic. Because they must support many different kinds of applications, they cannot support any particularly well.
Level II - Specific templates types
Not all modules are the same. Having only one underlying template frequently includes many unnecessary elements that are not customized for each module. For Level 2 template development, you must identify each different kind of application and modify the base template so that it will support only that particular type of application. The idea in Level 2 templating is that the base template is used for core and/or unique form modules; but for recurring types of modules, there is a specialized template for development of these modules Once complete, these specific template types then become base templates for specific applications. Although potentially time-consuming to create, using templates in this way has an incredibly fast payback in all future system development.
Level III - Object Library
Level 3 templating came from a desire to support the building of highly complex core applications that invariably take up much of a project’s development time. Core forms are usually complex and have little in common with other applications. However, such core applications do share common elements.
The idea behind level 3 templating is to identify these common elements and create generic objects so that developers can rapidly bring that functionality into the form being built. But all of these objects are not necessarily used in every form. They act as building blocks for the developer to assemble the components necessary to create a complex application. For example, tab controls, multi-select LOVs and special functions to support high-volume data entry applications are the kinds of objects that are good candidates for a level 3 template. The objects in a level 3 template are used in conjunction with either the general level 1 template or a specific level 2 template to facilitate complex form development.
These reusable objects can be used to assemble major components of very complex applications with incredible ease.
Level IV - Project-Specific Templates
Level I-III templates can be used for any project. However, some specific preparation should be done in base templates at the beginning of a project. These modifications can further reduce the amount of time spent building modules on a specific project. Two types of template modifications must be made:
· First, we will take the basic template and put all of the project-specific information into it. For example, the help-about form may be similar for each module in the project. Depending upon how the directory structure is implemented, these might be hard coded along with lists of specific printers or other project-specific tweaking to the base templates.
· The other kind of Level IV templating entails building project-specific widgets. For example, on one project, we built a client locator that was used in 10-15 places throughout the project. By building that widget once and placing it into the Object Library, overall project development time was decreased.
You can only plan a project-specific template if you have a very clear idea about what the modules will look like before you start building. Level IV templating virtually demands that full screen prototypes be created as part of the Design Phase.
The next sections discuss development and use of each level in more depth.
Development of Level I - Base Template
The basic template is a partially built application that developers can modify for each application they build. It is built to take full advantage of Forms’ object oriented techniques. This template contains many generically written programs that can be accessed as needed by applications. It is only by using such a template that developers can get the full benefit of Forms.
Of course, building a complex set of templates for a major application is not a weeklong task. We had one client where we spent an afternoon with a group of developers deciding just on screen and field colors.
To explain the concepts involved with VRAD using templates,
we will use an example template system we have developed and which is available
from the web site mentioned at the end of the paper. You can download and use
these forms without charge as a basis for your own template work.
Underlying Architecture
The template system consists of a number of files that must be available to developers when creating a new application. The following is a quick look at the files used in the template system. The relationships between the forms are diagrammed in Figure 1.
1.
refer.fmb
A file called refer.fmb, contains all of the property classes (referenced objects), visual attributes, and the default toolbar. This allows skilled developers to create objects in this file and attach the proper code and special properties. Starting-level developers can take advantage of these objects without having to worry about the internal details. These developers would not be given access rights to modify the refer objects.
The refer objects are referenced into the template form. Objects are referenced in Forms by opening the source and the target form at the same time in Forms Designer. Then the objects from the source are dragged into the target form with a specification that they be referenced, not copied. Referencing means that if you make a change in the master form, those changes will be applied when any form that references the master is regenerated. The copy option simply copies the object from one place to the other. Referencing means that you have to open refer to make changes in the objects or create new ones.
2. template.fmb
When a base application is used, as the developer opens the template and saves with a new file name, the developer can then make modifications and add application-specific elements like data blocks and code. This will be discussed more a bit later.
3. objlib.fmb
This file is used for Level III template work and contains
features you might want to regularly include in your forms, but do not always
include in all forms. Possible features in this category are: tabbed canvas
windows implemented with Forms objects, sticky notes, and a calendar object for
entering dates, etc. The method you use for incorporating these into the form
is to copy (not reference) the object from this form into the target working
form.
4. tmpllib.pll
This is the Forms PL/SQL library that is attached to the template.fmb file and that provides all code for the default template functionality as well as generic procedures you can use in your application.
5. tmplmenu.mmb
There is a default menu file attached to the template form that provides features included in the template. You can make changes in this file for your application or copy it and attach the new version to the forms on a one-by-one basis.
6. Other Files
There are icon files for the toolbar buttons that must be available when the form runs. These are considered part of the template system. In addition, a sample helpabt.fmb file gives general information about the form that you supply when you first create it. This form is called from the Help About menu item to parallel the functionality of many Windows programs.
Figure 1. Template System Forms Files
Using the Template
As already mentioned, the template is really a set of Forms modules. One Form (refer.fmb) stores your property classes and unchangeable referenced objects. A second application (template.fmb) has all objects from refer.fmb referenced in it as well as additional triggers and objects that will need to be modified for each application. The third (objlib) has objects you can copy if needed for a specific form.
Applications are built by opening up template.fmb, renaming it and modifying it to be the new
application. All referenced objects are stored in refer.fmb so any changes made there will propagate through
all Forms applications the next time they are generated.
The use of the template is based upon the following model:
1. The organization decides on their GUI standards and basic look and feel of various application types.
2. Lead developers create the template.
3. Junior and senior developers alike can effectively use the template. The idea is that developers start with the development template and simply add functionality to create their own applications. Because the code for most common features is already in the template, applications can be brought to production in record time.
Building the Template System
Two major parts of the template system that you need to carefully consider when building it are property classes and PL/SQL code. We will describe some issues involved with each in context of the sample forms.
Property Classes
Property classes should be replaced with subclassed objects when Developer/2000 2.0 is released. However, the principles of their use remain the same. Since Developer/2000 2.0’s interface design was still being finalized as of the writing of this paper, the discussion will refer to property classes.
A property class is a group of pre-defined attributes. Each property class can be assigned to any object within a form. For example, a property class can be assigned to a text box, a table, a radio button, etc. Actually, each property class is an object itself.
In order to understand how to get the property class to manipulate objects properly, it is necessary to understand each attribute. Instead of boring you with a full description of each one, there is a much easier approach. But first, it is necessary to explain how to create the property class.
The easiest way to create a property class is to define an object (like a text item) and assign appropriate property values to it. Then click on the property class button from the toolbar on the top of the property sheet (the fifth button over from the left). This will create a property class with all the properties and attributes you just defined for the item. You can then open the properties for that property class and delete or modify it as needed.
Another even faster way to create a property class is just to copy another property class from within the Object Navigator. Just select the property class you want to copy by clicking on it in Object Navigator. After this, just press ctrl-d and this will provide you with a copy of the original property class. Almost any object in Forms 4.5 can be duplicated by this procedure. Its list of properties can be obtained by double clicking on the icon to the left of the property class name. In, order to get a description of each properties, click on the property in question, press the F1 key, and a description will appear in the help window.
Once the basic aspects of property classes are understood, the hierarchical structure can be explained. You can base a property class on another property class, which will give you multiple levels of inheritance. You could create, for example, a property class called text_field that has properties for all text items in the form. This might have a default height, font name, font size and color. You could then define a property class called text_field_date that has properties of a format mask and class name of text_field. This property class would inherit all text_field properties (font, color) and additionally have the format mask property. The next step in the hierarchy might include different property classes for various date formats: one for month-date-year and another for just month-year, etc.
Each higher-level property class is dependent upon all of the ones below it. Therefore, if we change text_field, the rest of the property classes connected to it will all take the changes. If we change text_field_date, all property classes depending upon it will be altered; but text_field will remain untouched.
An item’s individual properties and property class creation both use the same screen, meaning that the screen that comes up from the right click menu labeled properties is identical to the properties screen that comes from the Object Navigator.
Property classes are extremely useful because they save time; and in the real world time is money. Instead of setting the same exact attributes twenty different times, a property class can be created once and the user can reference its pre-defined group of attributes as many times as deemed necessary.
We reference other property classes by defining them in the class property, which is the second level down from the top. As with defining any attribute, if there is more than one option to choose from, the text area beneath the toolbar will become a popbox that lists all options pertaining to that one specific attribute. So, when we want to assign a pre-existing property class, we click on the class category and then click on the down arrow button on the right side of the property indicator located beneath the toolbar and scroll down to find the property class that we need.
PL/SQL Code in the Template
Other than property classes, the most important decisions and objects in the form are the PL/SQL program units. This section explains the use of PL/SQL code in our sample template and the strategies used to implement it. Understanding this will allow you to plan your own template system code or modify the sample.
Strategy
All objects in the template (whether created in template or referenced from refer) are supported by PL/SQL code in the tmpllib.pll library file. This library is a rich collection of PL/SQL packages arranged by object. The strategy for the organization and placement of this code is based on the following guidelines and standards:
1. All triggers call procedures and functions contained in PL/SQL packages and there are no blocks of PL/SQL code in the triggers. This gives a central location for all code modification¾the Program Units node in either the form or the library.
2. All packages in the library module tmpllib.pll use an F_ prefix (for local Forms package). They are generically written so they may be used by all forms without having to modify the code. Many packages are organized around Forms objects and supplement the Forms built-in procedures. For example, there are f_item, f_block and f_alert packages for the Item, Block and Alert Forms objects, respectively. These hide some of the complexity of the object and supply additional functionality.
3. All packages that are local to the form, that is, copied to the form so you can modify them, have no F_ prefix. These are available to be customized for the specific form. The default code in these triggers will work without modification in most cases, but there are a few procedures that must be tailored to the form itself (described below as Code to Modify).
4. Package variables (mostly in a package spec called F_GLOBAL) are used throughout to store form-specific values like the list of master blocks in the form. These act as global variables that are available in all procedures. Many of these are set in the when-new-form-instance trigger. See the notes on "Global Variable Use" below for the reasons that standard global variables are avoided.
Menu Code
All items in the menu have PL/SQL code that calls code in the underlying form. All items are of one of the following types:
1. Magic item. Forms uses Windows default features to do functions such as Edit-Copy and Edit-Paste for text. In addition to the Edit menu, there are Magic menu items for the Window and Help menus so they will appear in the standard Windows order.
2. PL/SQL - do_key. Any menu item that is similar to a standard Forms function, like Exit Form or Save Changes (Commit), uses a do_key call. This gives a common call location for the menu item and key press (as well as the toolbar button) so if the user chooses “Remove Record” from the menu, it will fire the KEY-DELREC trigger on the form level. The toolbar button trigger will do the same so all code may be traced to the KEY- triggers.
3. PL/SQL - execute_trigger. The menu items that are not standard Forms functions, like Show Toolbar and Help Contents, call a trigger with a similar name that is written on the form level. This emulates the strategy used for the key- triggers and provides a common call location so that the menu item and button triggers can have the same code.
Toolbar Code
The toolbar buttons are referenced from refer as the toolbar block. You may add to the buttons, but don’t remove them in case they are needed in the future. If there is a button you do not need, add the code in when-new-form-instance to hide it¾
f_item.hide(‘BLOCK.ITEM’);
There is one when-button-pressed trigger on the toolbar block level that calls a procedure in the local toolbar Program Unit package to handle all buttons in the block according to the following rules.
1. If the button item is named after a do_key function, like execute_query or exit_form, the code issues a do_key with that item name. This sends the control into the key- trigger so named so that the toolbar, menu and key press will all have a common calling point.
2. If the item is not named after a do_key function, like finder, the code calls the execute_trigger built-in and passes the name of the item prefixed by a TB_. There is a corresponding trigger on the form level that calls the code. This strategy allows you to put any button function in the toolbar or to create a keypress for it (in Oracle Terminal).
Triggers in the Template
The triggers in the template are divided into two levels: form and block.
The form-level triggers are those you may wish to customize for your form such as when-new-form-instance, when-new-block-instance, when-timer-expired, and when-validate-record. Although they all call library procedures, the calls themselves appear in local PL/SQL packages so you may replace or add to the library code call. Since these triggers are local to the template, any changes you make to one form will not be reflected in any other form. Thus it is important to plan what additional functions these triggers will perform early in the development process. These functions would be placed in the library.
The block-level triggers are attached to the toolbar block and manage activities on the buttons. There are no item-level triggers for these buttons so the block-level triggers provide all of the functions needed. These triggers implement the bubble (micro-help) text on the buttons and the when-button-pressed event discussed in the Toolbar Code section above. The source of these triggers is the refer form as the toolbar block is referenced in template, so any changes are done in refer. All forms, when regenerated, will automatically pick up the new functionality.
There are user-defined triggers for those events that are not key- events like show_hide_toolbar, tb_back, etc. There are also triggers for the on-error and on-message events. All triggers in this property class call procedures in the following packages:
1. toolbar or util packages in the local Program Units for the template form that manage the key-press/menu item/toolbar buttons and the error/message systems. These may be modified on an individual form basis since they are “local” to the form.
2. f_util or f_winhelp packages in the library. These manage the help system and help-about form.
Code Calling Order
The flow of control for code in the template is a bit intricate, but upholds the following principle:
All user events that intend to perform the
same action, should execute the exact same program unit.
This is best explained with an example. If the user presses Ctrl-Q (the Windows
key assignment for exiting the form) the code that executes should be the same
as if the user pressed the Exit button or chose Exit from the File menu. The
means for enforcing this principle is to call packaged library or other
procedures from all triggers. Figure 2 diagrams how this works with a common
trigger set fired to exit the form.
Figure 2: Trigger and procedure calling architecture in the Template
Note that all triggering items (toolbar item, menu item, or key-press) end in the same procedure. If this structure is set up in your template, it is easy to use because you only have one place to modify the code: the TOOLBAR package that is local to the form.
Global Variable Use
Global variables are avoided as they lack sufficient length for some usages, and, in some cases, require creation and destruction. They also require cross-checking for existence. Also, there is no spelling or syntax check for global variables. For example, by mistake, you could use :global.block_name in one trigger and misspell it as :global.blockname in another. You would not get any compile errors and debugging this mistake at runtime would be difficult. Package variables solve all of these drawbacks.
Since package variables are not available outside the scope of the form that is running, you need to use other methods to pass values to another form. Use parameter lists to pass values to another form that you call with call_form, new_form or open_form. Use global variables only if the value that you pass from one form to another is modified by the second form and used again by the first form. If you do use global variables, be sure to track when they are created and destroyed and make use of the default_value Forms built-in to assist.
Code to Modify
The code in the template system is contained either in the library or the template form itself. The code in the library is generic and should not be modified unless there is some behavior you wish to change in all forms in your application. The form is designed around the idea of ease of use for developers, so there are very few packages that need or can be modified in order to customize a form.
When you use the template to create a new form, you need to carefully review the local code in the template, specifically in the STARTUP package and modify it for the blocks and canvases you will create. All codes in this package have samples and comments to explain their use. The following are the packages and procedures to modify:
1. STARTUP Package -
Modification Required
The STARTUP package contains a package spec initialization routine (at the bottom of the package body) that supplies a place to globally set global package variable assignments. Each variable is commented and the defaults will get you a certain ways. Normally, you would assign the values based on the needs in your form. There are also global variables in the F_GLOBAL PACKAGE that you can change if any of the default toolbar buttons have different names. There is also a startup procedure called populate_forms_screen. This initializes the values seen on the screen when you start the form or issue a do_key(‘clear_form’) from the menu or button. This procedure should be customized to the form and also has comments on its use.
The last procedure to look at in the startup package is the setup_objects procedure. This customizes the toolbar and initializes the objects in the template. You would modify or enhance this if you had list items to populate from queries or buttons to hide. There are samples of these in the procedure’s comments.
2. toolbar Package - Modification Optional
This package contains all the code that is called from the toolbar buttons, key triggers and menu items. Since this is local to the form, you may change the procedures to do different things or supplement them with other procedures for additional buttons or menu items. There is one procedure for each key-press/menu item/button call. Each procedure calls a library routine in the f_toolbar package. If needed, you can comment out the actual call and replace it with your own logic.
3. util Package - Modification Optional
This supports form-level triggers that are local to the form. The triggers call this code which you may modify or supplement to do application-specific functions. There is one procedure for each trigger. For example, there is an on_error procedure that is called by the on-error trigger. This captures the message that Forms gives when an error occurs and shows an alert with the message. You may wish to trap specific error numbers and give a message other than the default Forms message by adding code to this procedure.
Another example of a modification would be if you created another timer programmatically and wanted to place it in the when-timer-expired trigger on the form level. This trigger calls a timer_expired procedure in this package that you may change or supplement.
Notes on Adding Code
Whenever forms built-ins are used, the do_key() form of that built-in should be called if available. Therefore, when issuing a call to enter_query, the code uses a do_key(‘enter_query’) instead so that the key triggers will fire and send the control into the corresponding procedure.
In regards to PL/SQL code formatting in the template, all SQL and PL/SQL structure keywords are in upper case and all variable parameter, forms built-in, cursor, table and column names are in lower case. The comment style is /* */ for the header comments on each procedure and -- comments to explain the sections within the code. It is good to maintain one code format style to make the code easier to read.
If you add triggers on a lower level than triggers in the template form (form, toolbar block or property class-levels), be sure to set the trigger property Execution Style to Before, After, or Override based on whether you want your trigger to fire before, after ,or instead of the trigger in the template that is on the higher level, respectively.
Development of Level II - Specific templates types
The previous discussion in explained how templates are constructed and architected in a Level I "simple template" environment. Level II uses all the same components and strategies as Level I with its multiple files and code, but adds the idea of specific templates for specific purposes. Each of these templates will be a stripped-down version of the full Level I template.
Three common types of modules will be discussed here: Navigation, Administration, and Locator. Depending upon your GUI standards, you may or may not find these appropriate but the basic idea of specific templates for specific applications remains the same. Included in each description is a set of instructions on how to develop using the template. You would supplement these with on-line readme files for each template style so the developer would have reference material to use when developing the form. These instructions would include information such as what triggers need to be modified, what properties or which objects need to be filled in and how to safely add or remove form elements.
Navigation Template
A navigator module is a top-level form used to navigate to other applications. If the application is very large, the navigator might involve several canvases including top-level and subordinate canvases for each interest area. In our experience, we have never needed more than two levels of screens for navigation.
The navigation template is constructed with a very light PL/SQL Library. All this navigator form is doing is calling other forms. In addition to including property classes, this template is really a fully built navigation application. All the developer has to do is change the labels on the buttons, enter the names and paths of forms that are called and perhaps duplicate or delete a few buttons to correspond to the exact application.
Having a partially built application greatly minimizes the amount of time needed to build a full application. Normally, a skilled developer would bring up an existing similar application and modify it. For the skilled developer, having a generic template will not significantly improve development speed. The novice developer may have difficulty knowing what to change in an existing application. For this novice developer, the template will increase development speed and efficiency tremendously.
Administration
template
The administration module supports the code description tables. Usually, 20-30% of all tables in a given system are code description tables. There are many ways to build the modules to support these tables. Traditionally, a developer will build one block for each code description table. However, if code description tables are implemented as one large, single table, then a single block can support many different vertical tables merely by altering the default where clause of the block at runtime. If these tables are stored separately, the only way they can be supported through a single block is through the creation of a dynamic view. Of course, if the developer chooses, there can be one block for each table. I believe that this one block for each table approach provides the nicest user interface.
The administration application can be built using tabs. Each tab holds 2-4 administration tables. To speed performance, blocks are only queried when their respective tabs are selected. To create the administration template, start with a very simple base template. Then, a generic object group is created which includes canvases and items for the standard structure for the code description table. Many systems have a few different types of code description tables, for example with/without active flag or history information. Therefore, you may need a few different object groups. The object group includes its own stacked canvas.
To then build the administration application, drag in copies of the appropriate object group from an object library (implemented as a form in Forms 4.5 or in an object library in Forms 5.0). Assuming you are using good column naming conventions, all that remains to be done is to change boilerplate text, canvas position and the name of the base table block.
Locator
template:
A locator application stemmed from the need for greater querying capability than was available through Oracle’s query mode for locating a particular record. For example, to identify a particular employee, all we know is that he works in one of two states, in one of two departments, was hired in the last three years and whose last name starts with “SM.” To support those types of user requests, we built a locator application. On various tabs, the user can select different types of filters. On the final tab, the user can see what records their query retrieved. Users are able to name and save their queries for future retrieval. In addition, by adding criteria for sorts and breaks, also use this type of application to support a flexible reporting system that we include with all of the systems we develop.
The first time we built this type of module, it required several months of developer time. We decided to genericize the triggers and create appropriate object groups similar to those in the Administration template.
Development of Level III - Object Library
With Level I templates, we have a foundation for eliminating the repetitive work that is common to the development of all modules. With Level II templates for specific types of modules, we can build specific applications in a small fraction of the time normally required. Where is the bulk of time in application development really spent? It is spent on the key applications. These highly complex applications often don’t fall into any specific category. However, you will find that complex applications tend to use the same techniques and components. Level III templates provide the building blocks to assemble major components of complex applications.
Examples include tab controls and multi-select LOVs. Tab controls can be implemented by drawing lines in the shape of tabs, adding display objects and associated triggers to control stacked canvases. If you place all of the tab objects on a small stacked canvas, they can be grouped together in an object group and easily copied into a form. Multi-select LOVs (multi-LOVs) are more difficult to support.
Both traditional LOVs and pop-lists suffer from the limitations that a user can only select a single item. Many applications exist where multiple selection is necessary. Forms does not supply a multi-LOV. However, such a structure can be built. This is actually a relatively interesting application. A detailed explanation of how the multi-LOV is created along with some of the code follows:
Currently, with Forms, the only way to support a multi-LOV is through a substantial amount of coding. However, it is possible using Forms to build this object in such a way that developers can take advantage of this powerful feature while only writing a small amount of code. The trick is to think through the process of the multi-select LOV, write the code and build the appropriate objects so that this feature can be created very quickly. The multi-select LOV is comprised of an object group and a library. Therefore, to use a multi-select LOV, you have to bring in the object group and attach the library. The object group is composed of a canvas, two blocks and several iconic buttons with their associated triggers.
The library contains two packages:
1. Functions needed for the developer to use the LOV
2. Functions and procedures used internally within the multi-LOV
From the developer’s perspective, after bringing the appropriate objects into the application, what they have done is effectively extend Forms to support multi-LOVs using only two lines of code. To create the multi-LOV, the developer need only write a single line of code: mlov.create.
It takes as parameters a two-column record group and the name of the LOV. Wherever the multi-LOV is supposed to appear, call mlov.invoke, passing it merely the name of the LOV, the return field and the X and Y coordinates of the LOV, and the return value is a comma delimited list of values. As of this writing, we would have liked to make the return value a PL/SQL table, but that functionality was not yet implemented in the product.
Behind the scenes, the multi-LOV populates a record group and then populates a generic multi-LOV block with the data. When users are selecting items on the block, the multi-LOV simultaneously keeps track of the selected records in the record group. Then, when the user clicks on the OK button, the record group is scanned and the selected records are extracted. There is quite a lot of planning, code and several days of development time required to build this structure but its usefulness in many applications will quickly offset the investment in development effort. To list the entire system documentation for the multi-LOV is beyond the scope of this paper.
The goal in Level III template development is to completely genericize objects such as tabs and multi-select LOVs so that their complexity is hidden from developers. How hard is it to use tabs and multi-select LOVs? Sitting behind the scenes in tabs are many relatively subtle decisions such as ensuring that the appropriate canvas appears in the right place and that the space under the tab looks right. None of these decisions is particularly difficult; but thinking through all of the decisions involved can be time consuming particularly for the novice developer. There is no reason to think that any two developers would arrive at the same decisions.
The multi-LOV example includes very complex code requiring very experienced senior development staff to think through. Sitting behind this apparently simple multi-select LOV object are 10-15 pages of interesting PL/SQL code. From the developer’s perspective, all that needs to be done is to bring in an object group, attach a library and write two lines of code. Thus, Level III templates provide the user with very sophisticated functionality that is easy for even novice developers to use.
Development of Level IV -
Project-Specific Templates
Level IV templating involves taking all Level I and II templates and making them project-specific by adding logos, code setting project-specific defaults for global variables and perhaps adding project-specific boilerplate objects. The project-specific objects can be added to an existing object library but probably should be placed into their own form or object library.
It is important to spend some time thinking through what modifications should be made to the template before getting too far into a project. Ideally, all modules should be storyboarded or prototyped prior to the development of the project-specific template. You need to have a reasonably good idea of modules in order to appropriately identify project-specific reusable objects. The project-specific template and components should be tested by actually building a few modules before the template is released to the development team. Specific examples of potential project-specific objects include:
· Pop-down lists: These lists can be created for objects that recur throughout a project such as an employee pop-down list.
· Multi-select LOVs: As part of the Level IV template, multi-select LOV’s can be created for specific object types reused throughout a project such as for the selection of multiple products used in a purchase, sales of receiving module.
Disadvantages of Template Use
Template use does have a negative side. In a heavy template environment, with senior developers building the objects, novice developers (particularly those new to Forms) never get experience with basic PL/SQL coding. With the template, there is little need to write any code. The only time PL/SQL is ever necessary is for very complex PL/SQL, which is automatically assigned to a senior developer. Thus, junior developers never learn how to code. To combat this, we use novice developers to maintain, document and write exception handling for the templates. We try to make sure that novice developers work on extensions to the templates so that when developers need to go outside the template in creating new modules, they will have the skills to do so. Another negative side is the learning curve needed by novice developers and those new to the environment. This is a double-edged sword as you have to teach not only the template approach itself, but also the specific code and objects that are included in the template system. There is no easy answer to this other than keeping "developer-friendliness" in mind when creating, modifying, and documenting the template files.
Conclusion
We have described the basic considerations you need to have when thinking about developing and using template forms for Very Rapid Application Development. Without the use of a template, Forms is a very good product. It compares favorably with the leading development tools on the market. However, with a well-built template, rich with property classes, triggers and generic objects, Forms is an extraordinary product. With a good template and a handful of good developers, projects can be brought to production in a period of time that appears almost magical.
Sample Template
Please feel free to download the sample files mentioned from the web site: http://ourworld.compuserve.com/homepages/Peter_Koletzke