How to create a callout
Overview
The objective of this article is to show you how to create a new callout . A callout is a piece of Javascript code associated with a particular field on a tab. This code is executed whenever the field changes. It is a type of Ajax substitute, changing parts of a tab/window without the need of refreshing it.
It works by calling the FIC when a field with an associated callout is changed. The FIC (Form Initialization Component) refreshes the needed fields based on the callout logic.
This section implements the following new functionality: When entering a new product, one has the option of entering the Search Key for the product, the Name and the Category it belongs to. But what if our client wants the search key to be constructed automatically by taking the product's name, removing all spaces, appending the underscore (_) and the category name it belongs to?
For example, the Search Key of a product that has the Name Bon Fountain and belongs to the Water Product Category would become BonFountain_Water. Let's see how this could be done using a callout.
The steps involved in creating a new callout are:
- Create the source file(s) of the callout (usually a java file).
- Define the new callout within the application dictionary (
Menu
>Application Dictionary
>Setup
>Callout
). - Associate this callout with a table column (
Application Dictionary
>Table and Column: Callout field within Column tab
). - Compile the window/tab(s) where this Column is used.
Important
Developments related to points (1) and (2) must belong to a module that is not the core module. Please follow the How to create and package a module section to create a new module. For the development related to point (3) about modifying a core located column, a new template is needed. You can read the How to change an existing Window article to obtain more information.
Note
This article assumes you have created both module and template according to the articles just mentioned.
Creating the Callout
Existing callouts are located in src/org/openbravo/erpCommon/ad_callouts.
The right way to create a callout is by extending the SimpleCallout class. This class simplifies the callout code, hides some of the internals of the callout and keeps you focused on the operations required. To access database data, DAL is used.
Theory
To develop a new callout based on this class, you only have to create a new java class that extends SimpleCallout and overwrite the following method:
In this method you can develop the logic of the callout and use the info object of class CalloutInfo to access window fields, database and other methods. The most important are:- public String
getStringParameter(String param, RequestFilter filter)
: Returns the value of a field named param as an String using the filter to accept values. - public BigDecimal
getBigDecimalParameter(String param) throws ServletException
: This method returns the value of of a field named param as a BigDecimal. - public void
addResult(String param, String value)
: This method sets the value of a field named param with the String value indicated. - public void
addResult(String param, Object value)
: This method sets the value of a field named param with the value indicated. This method is useful to set numbers like BigDecimal objects. - public void
addSelect(String param)
: Starts the inclusion of values of a field named param of type select. - public void
addSelectResult(String name, String value)
: Adds an entry to the select field and marks it as unselected. - public void
addSelectResult(String name, String value, boolean selected)
: Adds an entry to the select field. - public void
endSelect()
: Finish the inclusion of values to the select field. - protected void
showMessage(String value)
: Shows a message in the browser with the value indicated. - protected void
showError(String value)
: Shows an error message in the browser with the value indicated. - protected void
showWarning(String value)
: Shows a warning message in the browser with the value indicated. - protected void
showInformation(String value)
: Shows an information message in the browser with the value indicated. - protected void
showSuccess(String value)
: Shows a success message in the browser with the value indicated. - protected void
executeCodeInBrowser(String value)
: Executes the javascript code indicated in the value in the browser. - public String
getLastFieldChanged()
: Returns the name of field that triggered the callout. - public String
getTabId()
: Returns the Tab Id that triggered the callout. - public String
getWindowId()
: Returns the Window Id that triggered the callout. - public
VariablesSecureApp vars
: This instance field contains the VariablesSecureApp associated to the callout servlet.
It is important to keep coherence with each expected data type (String, BigDecimal, ...)
See the following class as an example of a class that currently uses SimpleCallout: SL_Project_Service. This callout simply takes the numeric value of two fields, calculates the sum and writes it into another field. This is the interesting part of the code that performs the logic:
@Override
protected void execute(CalloutInfo info) throws ServletException {
BigDecimal serviceSerCost = info.getBigDecimalParameter("inpservsercost");
BigDecimal serviceOutCost = info.getBigDecimalParameter("inpservoutcost");
BigDecimal serviceTotalCost = serviceSerCost.add(serviceOutCost);
info.addResult("inpservcost", serviceTotalCost);
}
Extend a Callout
It is possible to implement a callout that extends from another callout. For more information visit this How to create a callout that extends from another callout tutorial.
Product Search Key Calculation using SimpleCallout
Let's define the tasks that need to be performed by the callout:
- Retrieve the name of the product as entered by the user
- Retrieve the ID of the category selected from a dropdown by the user
- Get the name of the product category inside the database using the product category ID retrieved
- Strip spaces out of the product and category names
- Construct the Search Key
// the package name corresponds to the module's manual code folder // created above package com.etendoerp.customer.example.ad_callouts; import javax.servlet.ServletException; import org.openbravo.utils.FormatUtilities; import org.openbravo.erpCommon.ad_callouts.SimpleCallout; import org.openbravo.base.secureApp.VariablesSecureApp; // classes required to retrieve product category data from the // database using the DAL import org.openbravo.dal.service.OBDal; import org.openbravo.model.common.plm.ProductCategory; // the name of the class corresponds to the filename that holds it // hence, modules/modules/org.openbravo.howtos/src/org/openbravo/howtos/ad_callouts/ProductConstructSearchKey.java. // The class must extend SimpleCallout public class ProductConstructSearchKey extends SimpleCallout { private static final long serialVersionUID = 1L; @Override protected void execute(CalloutInfo info) throws ServletException { // parse input parameters here; the names derive from the column // names of the table prepended by inp and stripped of all // underscore characters; letters following the underscore character // are capitalized; this way a database column named // M_PRODUCT_CATEGORY_ID that is shown on a tab will become // inpmProductCategoryId html field String strProductName = info.getStringParameter("inpname", null); String strProductCategoryId = info .getStringParameter("inpmProductCategoryId", null); // inject the result into the response info.addResult("inpvalue", getConstructedKey(info.vars, strProductName, strProductCategoryId)); } protected String getConstructedKey(VariablesSecureApp vars, String strProductName, String strProductCategoryId) { // Retrieve the product category name final ProductCategory productCategory = OBDal.getInstance().get(ProductCategory.class, strProductCategoryId); String strProductCategoryName = productCategory.getName(); // construct full key String generatedSearchKey = FormatUtilities.replaceJS(strProductName .replaceAll(" ", "")) + "_" + strProductCategoryName.replaceAll(" ", ""); // return generated key return generatedSearchKey; } }
Defining the Callout within the Application Dictionary
Note
You need to have only your module as "In Development" at this stage.
Using the role System Administrator, navigate to Application Dictionary
> Setup
> Callout
. Create a new record as indicated by the screenshot below:
Warning
The name of the callout should not have spaces or illegal javascript characters.
Save and navigate to the Callout Class tab of the same window. You will notice that the Java Class Name was automatically generated for you, however, not correctly since the name could not match the Callout name you have provided. Correct it in line with your callout package/class name. See screenshot below:
Now Etendo Classic knows that a callout exists and is implemented by the class you have just specified.
Warning
Remember to perform
./gradlew export.database
in order to persist your changes in your module.
Associating the Callout with a Column
Note
You need to have ONLY your template as "In Development" at this stage.
Using the role System Administrator navigate to Application Dictionary
> Tables and Columns
> and find the M_Product DB Table. This is the underlying table of the main tab of the Product window.
Go to Column tab, find the Name record and edit it. Find the Callout dropdown that should at this point be empty. Select our Product_Construct_SearchKey callout and save the record:
Do the same for the Product Category record since a change in any of them should also regenerate the Search Key.
Warning
Remember to perform
./gradlew export.database
and
./gradlew export.config.script
in order to persist your changes in your template.
Compiling the Window
Finally, for the callout to take effect, the window that uses it needs to be recompiled and deployed to Tomcat. Do:
Info
Once the compilation has finished, restart Apache Tomcat server.
The Result
Using the role Group Admin (or your defined 'administrator' role),
navigate to the Master Data Management
> Product
window. Enter a new
product with Name = Bon Fountain and leave the Name field. Notice
how the Search Key changes. Then, change the Product Category to something
else and see how the change is reflected inside the Search Key field.
Last, save changes.
This work is a derivative of How to Create a Callout by Openbravo Wiki, used under CC BY-SA 2.5 ES. This work is licensed under CC BY-SA 2.5 by Etendo.