Develop code to extend a framework
When you need to change the behavior of an element, you create an extension of that element. Some elements require code to be written to change their behavior, such as adding an event handler. In other cases, you might create a class extension to change an element's makeup.
Class extensions
To extend the business logic that is related to a table, you create an augmentation class. If you wanted to add another ID field to the table and have it filled, you would create a data event handler for the Inserting event and then implement the logic to fill the new field in that event handler. You can create a class that augments the table and enables access to the table's fields and methods in an easy-to-read manner. When creating a class extension, you must decorate it with the ExtensionOf
attribute, use the _Extension
suffix, and indicate the class as final
.
The following is an example of creating a class that extends
InventTable
. Methods can then be added to this
augmented class where the comment is used.
[ExtensionOf(tableStr(InventTable))]
final class InventTableNew_Extension
{
public void newDefaultInventLocationId()
{
//enter your code here
}
}
Event handlers
An event handler is a way for you to write or copy code to an element that runs when a certain event occurs, such as when a field is modified or a record is deleted. Some elements, like tables and forms, contain an Events node in the designer window that, when expanded, lists all the events that are associated with that element. If you need to add supplementary behavior that doesn't currently exist in an element, you should create an extension of that element, and then add an event handler to the extended element.
The following are methods for event handlers that are pulled from the CustTable
table. These methods can be copied and added to your extended element or class by right-clicking the event in the element designer window and selecting Copy event handler method.
OnDeleted
event - This is a post-event handler that triggers when a record is deleted in the table. You could use this, for example, to display an Infolog message after a record is deleted.
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
[DataEventHandler(tableStr(CustTable), DataEventType::Deleted)]
public static void CustTable_onDeleted(Common sender, DataEventArgs e)
{
}
OnInserting
event - This is triggered when data is being inserted. For example, this could trigger when you add a new customer to finance and operations apps.
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
[DataEventHandler(tableStr(CustTable), DataEventType::Inserting)]
public static void CustTable_onInserting(Common sender, DataEventArgs e)
{
}
OnValidatedWrite
event - This is a post-event handler that triggers after data is entered. This is used to validate data that is being written to a page, such as ensuring that a customer is at least 18 years old by verifying a birth date.
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
[DataEventHandler(tableStr(CustTable), DataEventType::ValidatedWrite)]
public static void CustTable_onValidatedWrite(Common sender, DataEventArgs e)
{
}
Chain of Command
You can wrap logic around methods that are defined in the base class that you're augmenting. You can also extend the logic of public and protected methods without having to use event handlers.
When wrapping a method, you can access public and protected methods as
well as variables of the base class. Using a wrapper around a method and
the next
keyword creates a Chain of Command (CoC).
CoC is a design pattern where a request is handled by a series of receivers. An extension class is used to wrap protected or public methods of classes, tables, data entities, and forms. You should be aware of some restrictions when wrapping methods:
- The wrapper method must have the same signature as the base method.
- When you augment form classes, only root-level methods can be wrapped, not methods that are defined in nested classes.
Wrapper methods in an extension class are required to always call
next
so that the next
method in the chain
and, finally, the original implementation is always called. This process ensures that every method in the chain factors into the result. The method must call next()
unconditionally.