NXJ Language/Runtime
From Support Wiki
Do I need to declare form fields on my layout as variables?
No - any fields you have placed on your form layout are automatically declared as variables of class Nullable<type>Field (where <type> is the field type declared in the layout). For example, a String field is declared as NullableStringField.
How do I access columns from my target table that are not on my form layout?
To do this, you need to declare the fields in the FORM section of your NXJ code. The fields need to be declared as "multi_valued Nullable<type>Variable <x>" where <type> is the datatype to use for the column, and <X> is the name of the column in the database. For example, if the target table for form "employee" has an AMOUNT column "salary" which is not on the form layout, you can access it with code like the following:
FORM employee
{
multi_valued NullableAmountField salary;
ON FIND
{
vacation_cost = salary / 30 * vacation_days;
}
}
Why do my field code sections not execute when I leave the field?
The moment at which field code sections are executed depends on whether the field's "Immediate" attribute is set or not. If the "Immediate" attribute is not set, the field code sections will not execute until a command occurs that requires communication to the back-end server. Instead, the code sections will be queued and executed in a batch before the command is executed. If the "Immediate" attribute is set, code sections will be executed immediately as events are triggered on the field.
How do I check a variable or field for a NULL value?
Use the isNull() method on the variable:
if (!myVar.isNull()) notes = notes + myVar;
How can I get a reference to the entry point form to call methods defined on the entry form?
Declare a variable of the class of your entry form and initialize it as follows:
<entryformclass> MAF = (<entryformclass>)session.entryForm;
For example, if your entry point form is named "Login":
Login MAF = (Login)session.entryForm;
How can I use the above reference to call a method on the entry form?
Just use the reference to call the method:
result = MAF.myMethod(param1,param2);
How can I make a button on the form execute code?
First, create a developer designed command in your NXJ code:
COMMAND buttonPressed
{
session.displayToMessageBox("Button was pressed");
}
Then, in the designer, create a button on the form. In the dropdown list for the "Command" attribute you should see your newly developed command. Select it to assign the command to the button.
How can I queue commands to be executed?
Use the session.queueCommand() method. For example:
- session.queueCommand("CLEAR_TO_FIND");
- session.queueCommand("FIND");
You can also specify that a command be queued to execute on a specific dataview:
- session.queueCommand("ADD_UPDATE", "Detail");
Where 'Detail' is the name of the dataview.
How can I set up conditional next forms?
You can set up conditional next forms by setting the "Conditional" attribute in your Next Form list (see What does the "Conditional" check box mean in the form properties?) and writing a evaluateNextFormCondition() method to determine which form(s) will be available as next forms at any given time.
The evaluateNextFormCondition() method takes as parameters the name of the form as well as the transaction characteristics. It returns "true" if the form should be made available as a Next Form, or "false" if the form should not be available. For example, the following code allows you to use buttons on the form to determine which form to bring up:
FORM test
{
NullableStringVariable nextFormName = "";
COMMAND button1Command
{
nextFormName = "NextForm1";
}
COMMAND button2Command
{
nextFormName = "NextForm2";
}
boolean evaluateNextFormCondition(
String formName,
int transactionMode,
int consistencyMode)
{
if (formName == nextFormName)
return (true);
else
return (false);
}
}
How can I create an output file on disk from NXJ code?
Here is an example of how to do this:
import java.io.FileWriter;
import java.io.BufferedWriter;
import java.io.PrintWriter;
import java.io.IOException;
FORM EntryForm
{
void writeerrtofile(NullableString errmsg)
{
try {
fileName = "C:/temp/err.txt";
log = new PrintWriter(new BufferedWriter(new FileWriter(fileName)));
} catch (IOException ioe) {
System.out.println("Error opening file .. " + fileName);
ioe.printStackTrace();
}
log.println(errmsg.trim());
}
AFTER APPLICATION
{
log.println("Application Exit.. !");
try {
log.flush();
log.close();
} catch (Exception ioe) {
System.out.println("Error closing file .. " + fileName);
ioe.printStackTrace();
}
}
}
How do I get the current date and time in NXJ?
You can use the session.getCurrentDate() and session.getCurrentTime() methods to get the current date and time. Then you can use these values anywhere you need them. For example, if you want to place the date and time on your form, you can use the following code:
FORM test
{
NullableDateVariable currentDate = session.getCurrentDate();
NullableTimeVariable currentTime = session.getCurrentTime();
...
}
Then you can use "=currentDate" and "=currentTime" as expressions for dynamic text fields on the form to display the values automatically. See How can I change the value of a label at runtime? for details on dynamic text fields.
How can I use a different connection for my embedded SQL statement?
How does NXJ match rows in the selected set to rows in the database table?
How NXJ will identify which database rows match selected set rows depends on the underlying database used. In DataServer and Oracle, we use the ROWID of the row. In DataServer ELS, we use the primary key for the table - thus in DataServer ELS you must have a primary key on any table that you are going to use as a target table.
How does NXJ retrieve the information for a newly added row?
This depends on the underlying database. For Oracle, we use the ROWID that Oracle returns when an INSERT operation occurs. For DataServer and DataServer ELS, we use all the columns in the table to uniquely identify the new row. This has repercussions if there are any columns which change in value during the insert, for example columns that are modified by an INSERT trigger.
How can I commit or roll back my transaction in NXJ?
Use either of the following statements:
- EXEC SQL COMMIT WORK;
- EXEC SQL ROLLBACK WORK;
How can I determine what form I was called from?
The prevForm attribute of a form will allow you access to the attributes of the previous form. You can use the formName attribute of the previous form to identify it:
if (prevForm.formName.equals("formname"))
session.displayToMessageBox("You came from 'formname'");
How do I set default search criteria for a form?
Use the clearFindExp attributes of the form fields:
BEFORE FORM field1.clearFindExp = "A%"; field2.clearFindExp = Login#var;
How do I access variables on another form?
Use the syntax <formname>#<varname> - for example, to access the variable "var1" on form "form1" use form1#var1.
What does 'multi-valued' mean as a property for a layout object or a Nullable*Variable?
Multi-valued indicates that for each record in the record set of the dataview, the object or variable in question will have a unique value. That is, if the column of one record is updated, that same column of other records are not affected. All objects that are connected to a column in the table of the form or dataview must be multi-valued. Objects not tied to a column should be multi-valued if they are displaying data based on values in the presented record (such as presenting an employee name based on an EMP_ID field.) Multi-Valued is also used to refer to Nullable*Variable's (such as a NullableNumericVariable) to expose table columns that do not have corresponding objects on the form or dataview:
multi_valued NullableNumericVariable EMP_ID;
(See also How do I access columns from my target table that are not on my form layout?)
How can I make a field hidden or make a hidden field visible at runtime?
To make a field invisible, simply set the "visible" attribute of the field to false in the NXJ code. To make it visible once again, set "visible" to true.
Is there any way to get NXJ connection information from a Java class?
Yes, you will need to pass in a reference to the NXJ session object and use the getConnection() method on this object to get a reference to the NXJ JDBC connection. For example:
// Java class
import com.unify.nxj.mgr.NXJSession;
import com.unify.nxj.mgr.dataConnection.NXJDataConnection;
class JavaClass
{
public String example1( NXJSession session )
{
try {
NXJDataConnection nxjconn = session.getConnection("drgTutorial");
java.sql.Connection jdbcConn = nxjconn.getJdbcConnection();
// the application does what it wants with the JDBC connection
return jdbcConn.getMetaData().getDatabaseProductName();
}
catch ( Exception theEx )
{
return "exception occurred: " + theEx.toString();
}
}
}
Unify NXJ Support for JSP and Servlet Code
An interface is available that can be used by JSP and Servlet code to access some NXJ-created objects, such as the data source associated with an NXJ connection.To use the interface, the JSP/Servlet code will need to import com.unify.nxj.awebServlet.Runtime and call the interface methods as Runtime.getLocalizedString(xxx), for example. The interface currently has the following methods available.
getLocalizedString
Returns the localized String, or the tag itself if the string is not found. These tags are looked up in the “application.properties” files based on the current locale. For more information about the “application.properties” files, see “Localizing Your NXJ Application” at http://www.unify.com/products/nxj/documentation/supplemental/index.htm.
public static String getLocalizedString(
ServletRequest request, // the servlet request
String tag /* the tag to use to lookup the localized string
in the application.properties file. */
)
getLocalizedURL
Returns the localized URL of the resource.
public static String getLocalizedURL( ServletRequest request, // the servlet request String filename /* the filename of the resource; assumed to be relative to the Static_Content directory */ )
getDataSource
Returns the data source for an NXJ connection. The data source can be used to create JDBC Connections for use in the Servlet. Note that these connections are independent of the transactions being used by the NXJ forms. Be sure to follow the J2EE requirements for using such connections (such as transactions cannot span calls to the Servlet and javax.sql.UserTransaction must be used rather than java.sql.Connection to commit or roll back transactions).
public static javax.naming.DataSource getDataSource(
String connectionName // The name of a connection in the NXJ project
)
throws NullPointerException, // if connectionName is null
javax.naming.NameNotFoundException, /* if the connection
* name is not a valid name of a
* connection in this project or if there
* is an internal JNDI problem looking up
* contexts in the J2EE component. */
javax.naming.NamingException, /* if there is a resource
* problem in the application server's
* JNDI namespace. */
ClassCastException, /* if the connection has not been correctly
* mapped to a javax.sql.DataSource in the J2EE
* component context. */
How do I bring up my NXJ application in a browser window with no toolbar/menubar?
Sometimes, you may want to bring up the application with no toolbar/menubar - you can do this easily by changing the URL you use to start the application. Instead of linking directly to the "http://..." URL of the application, you can directly embed the Javascript "window.open()" method into your link URL. For example, to bring up your application http://localhost:8088/ControlCenter/packages/MyApp/entry in it's own window, use the following URL:
javascript:window.open("http://localhost:8088/ControlCenter/packages/MyApp/entry","_blank","toolbar=no,menubar=no,resizable=yes")
See the documentation for the Javascript window.open() method for more examples on how to control your windows.
Why does my application against an Informix database fail with a “Transactions not Supported” JDBC exception?
Within the Informix environment you are allowed to create a database in three different manners:
create database xyz with buffered log; create database xyz with log; create database xyz;
Option 1: creates the database with a logging (i.e. transactions) turned on. The buffered log portion of the statement means that it buffers or writes multiple transactions at a time to the log. It’s not ANSI standard but better from a performance perspective. Option 2: will create the same database with ANSI style logging meaning that every transaction committed will be written to the log at the time it is committed. This is a slower way to do logging but it ensures that there is zero loss of committed data if a system should crash. Option 3: will create a database with logging turned off. This means that transaction support is not available for this database. If you create a database using the syntax from option 3, NXJ will allow you to connect from the Design Center but when you try and deploy the application you will receive a JDBC exception error stating “Transactions not Supported”, since NXJ requires that the underlying database support transactions.
How do I change the default timeout for my NXJ applications on JBoss
Edit the $UNIFY_HOME/jboss/server/default/deploy/jbossweb-tomcat41.sar/web.xml file and modify the <session-timeout> entry:
<session-config>
<session-timeout>30</session-timeout>
</session-config>