Reference guide: Model | View | Tabular data | Object/relational mapping | Controllers | Application | Customizing

Customizing

User Interface generated by OpenXava is good for most cases, but sometimes you may need customizing some part of the user interface (creating your own editors) or create your own handmade user interface (using custom JSP views) completly.
On the other hand, if you simply want to define the Look & Feel of your application look at the Custom visual style guide.

Editors

Editors configuration

You see that the level of abstraction used to define views is high, you specify the properties to be shown and how to layout them, but not how to render them. To render properties OpenXava uses editors.
An editor indicates how to render a property. It consists of an XML definition put together with a JSP fragment.
To refine the behavior of the OpenXava editors or to add your custom editors you must create in the folder xava of you project a file called editors.xml. This file looks like this:
<?xml version = "1.0" encoding = "ISO-8859-1"?>
 
<!DOCTYPE editors SYSTEM "dtds/editors.dtd">
 
<editors>
 <editor .../> ...
</editors>
Simply it contains the definition of a group of editors, and an editor is defined like this:
<editor
    name="name"                         <!--  1  New in v2.1.3 -->
    url="url"                           <!--  2 -->
    format="true|false"                 <!--  3 -->
    depends-stereotypes="stereotypes"   <!--  4 -->
    depends-properties="properties"     <!--  5 -->
    frame="true|false"                  <!--  6 -->
    always-reload="true|false"          <!--  7  New in v3.1.2 -->
    composite="true|false"              <!--  8  New in v3.1.3 -->
    icon="icon"                         <!--  9  New in v5.7 -->
    init-action="Controller.action"     <!-- 10  New in v5.7 -->
    release-action="Controller.action"  <!-- 11  New in v5.7 -->
    selectable-items="true|false"       <!-- 12  New in v5.7 -->
>
   <property ... /> ...                 <!-- 13 -->
   <formatter ... />                    <!-- 14 -->
   <list-formatter ... />               <!-- 15  New in v3.1.4 -->
   <for-stereotype ... /> ...           <!-- 16 -->
   <for-type ... /> ...                 <!-- 17 -->
   <for-model-property ... /> ...       <!-- 18 -->
   <for-reference ... /> ...            <!-- 19  New in v3.1.3 -->
   <for-collection ... /> ...           <!-- 20  New in v3.1.3 -->
   <for-tab ... /> ...                  <!-- 21  New in v4.6 -->
   <for-valid-values />                 <!-- 22  New in v2.1.2 -->
   <for-references />                   <!-- 23  New in v3.1.3 -->
   <for-collections />                  <!-- 24  New in v3.1.3 -->
   <for-element-collections />          <!-- 25  New in v5.0 -->
   <for-tabs />                         <!-- 26  New in v4.6 -->
</editor>
  1. name (optional): (New in v2.1.3) Name for referencing to this editor from other places, like @Editor from a JPA entity or <reference-view ... editor=/> from a XML component.
  2. url (required): URL of JSP fragment that implements editor. Starts from xava/editors (inside the web folder of your project).
  3. format (optional): If true, then OpenXava has the responsibility of formatting the data from HTML to Java and vice versa; if false, then the responsibility of this is for the editor itself (generally getting the data from request and assigning it to org.openxava.view.View and vice versa). The default is true.
  4. depends-stereotypes (optional): List of stereotypes (comma separated) which this editor depends on. If in the same view there are some editors for these stereotypes they throw a change value event if its values change.
  5. depends-properties (optional): List of properties (comma separated) on which this editor depends. If in the same view there are some editors for these properties they throw a change value event if its values change.
  6. frame (optional): If true, then the editor will be displayed inside a frame. The default is false. Useful for big editors (more than one line) that can be prettier this way.
  7. always-reload (optional): (New in v3.1.2) If true, this editor is reloaded always (each time a user executes an action or he does any other request to the application). When false the editor is reloaded only when the data it represents has been changed. The default is false.
  8. composite (optional): (New in v3.1.3) A composite editor is made up by several other editors; it receives a View object that represents a subview. The default is false.
  9. icon (optional): (New in v5.7) Icon id from Material Design Icons. For example, if you write icon="bell" a bell will be used as icon to allow the user choose that editor. Currently choosing an editor is only available for list mode.
  10. init-action (optional) (New in v5.7): Qualified name of the action (from controllers.xml) to init the editor. Currently applies only to list mode editors.
  11. release-action (optional) (New in v5.7): Qualified name of the action (from controllers.xml) to relase the resources used by the editor. Currently applies only to list mode editors.
  12. selectable-items (optional) (New in v5.7): if true, the editor allows the user to select several elements (with a checkbox or similar). In this way OpenXava can know when to hide the actions that process several elements. Currently applies only to list mode editors. The default is true.
  13. property (several, optional): Set values in the editor; this way you can configure your editor and use it several times in different cases.
  14. formatter (one, optional): Java class to define the conversion from Java to HTML and from HTML to Java.
  15. list-formatter (one, optional): (New in v3.1.4) Java class to define the conversion from Java to HTML in list mode.
  16. for-stereotype (several, optional): Associates this editor with a stereotype. The preference order is: first model property, then stereotype and finally type.
  17. for-type (several, optional): Associates this editor with a type. The preference order is: first model property, then stereotype and finally type.
  18. for-model-property (several, optional): Associates this editor with a concrete property of a model. The preference order is: first model property, then stereotype and finally type.
  19. for-reference (several, optional): (New in v3.1.3) This editor will be used for the references to the specified model.
  20. for-collection (several, optional): (New in v3.1.3) This editor will be used for the collections of objects of the specified model.
  21. for-tab (several, optional): (New in v4.6) This editor will be used for the tabs (list mode) of objects of the specified model.
  22. for-valid-values (one, optional): (New in v2.1.2) This will be the default editor for enum and <valid-values/>.
  23. for-references (one, optional): (New in v3.1.3) This will be the default editor for references.
  24. for-collections (one, optional): (New in v3.1.3) This will be the default editor for collections.
  25. for-element-collections (one, optional): (New in v5.0) This will be the default editor for element collections.
  26. for-tabs (one, optional): (New in v4.6) This will be the default editor for tabs, that is for list mode.
Let's see an example of an editor definition. This example is an editor that comes with OpenXava, but it is a good example to learn how to make your custom editors:
<editor url="textEditor.jsp">
 <for-type type="java.lang.String"/>
 <for-type type="java.math.BigDecimal"/>
 <for-type type="int"/>
 <for-type type="java.lang.Integer"/>
 <for-type type="long"/>
 <for-type type="java.lang.Long"/>
</editor>
Here a group of basic types is assigned to the editor textEditor.jsp (you can find it in web/xava/editors folder of your project). The JSP code of this editor is:
<%@ page import="org.openxava.model.meta.MetaProperty" %>
 
<%
String propertyKey = request.getParameter("propertyKey"); // 1
MetaProperty p = (MetaProperty) request.getAttribute(propertyKey); // 2
String fvalue = (String) request.getAttribute(propertyKey + ".fvalue"); // 3
String align = p.isNumber()?"right":"left"; // 4
boolean editable="true".equals(request.getParameter("editable")); // 5
String disabled=editable?"":"disabled"; // 5
String script = request.getParameter("script"); // 6
boolean label = org.openxava.util.XavaPreferences.getInstance().isReadOnlyAsLabel();
if (editable || !label) { // 5
%>
<input id="<%=propertyKey%>" name="<%=propertyKey%>" class=editor <!-- 1 -->
 type="text"
 tabindex="1" <!-- 7 -->
 title="<%=p.getDescription(request)%>"
 align='<%=align%>' <!-- 4 -->
 maxlength="<%=p.getSize()%>"
 size="<%=p.getSize()%>"
 value="<%=fvalue%>" <!-- 3 -->
 <%=disabled%> <!-- 5 -->
 <%=script%> <!-- 6 -->
 />
<%
} else {
%>
<%=fvalue%>&nbsp;
<%
}
%>
<% if (!editable) { %>
 <input type="hidden" name="<%=propertyKey%>" value="<%=fvalue%>">
<% } %>
A JSP editor receives a set of parameters and has access to attributes that allows to configure it in order to work suitably with OpenXava. First you can see how it gets propertyKey (1) that is used as HTML id. From this id you can access to MetaProperty (2) (that contains meta information of the property to edit). The fvalue (3) attribute contains the value already formated and ready to be displayed. Align (4) and editable (5) are obtained too. Also you need to obtain a JavaScript (6) fragment to put in the HTML editor. You have to specify tabindex="1" (7) in order that the editors would be in the correct tab order (new in v4.5.1).
Although creating an editor directly with JSP is easy it is not usual to do it. It's more common to configure existing JSPs. For example, in your xava/editors.xml you can write:
<editor url="textEditor.jsp">
 <formatter class="org.openxava.formatters.UpperCaseFormatter"/>
 <for-type type="java.lang.String"/>
</editor>
In this way you are overwriting the OpenXava behavior for properties of String type, now all Strings are displayed and accepted in upper-cases. Let's see the code of the formatter:
package org.openxava.formatters;
 
import javax.servlet.http.*;
 
/**
 * @author Javier Paniza
 */
 
public class UpperCaseFormatter implements IFormatter { // 1
 
 public String format(HttpServletRequest request, Object string) { // 2
 return string==null?"":string.toString().toUpperCase();
 }
 
 public Object parse(HttpServletRequest request, String string) { // 3
 return string==null?"":string.toString().toUpperCase();
 }
 
}
A formatter must implement IFormatter (1), this forces you to write a format() (2) method to convert the property value (that can be a Java object) to a string to be rendered in HTML; and a parse() (3) method to convert the string received from the submitted HTML form into an object suitable to be assigned to the property.
Also we can set a specific formatter to display information in list mode (New in v3.1.4) through list-formatter. The formatter assigned to this attribute designates the form in which the information is displayed at list mode without affected detail mode. This formatter must implement IFormatter but unlike the previous one only needs to implement format(). If list-formatter is not specified then formatter is used for list mode too.

Multiple values editors

Defining an editor for editing multiple values is alike to define a single value editor. Let's see it.
For example if you want to define a stereotype REGIONS that allows the user to select more than one region for a single property. You may use the stereotype in this way:
@Stereotype("REGIONS")
private String [] regions;
Then you need to add the next entry to your stereotype-type-default.xml file:
<for stereotype="REGIONS" type="String []"/>
And to define in your editor in your editors.xml file:
<editor url="regionsEditor.jsp"> <!-- 1 -->
 <property name="regionsCount" value="3"/> <!-- 2 -->
 <formatter class="org.openxava.formatters.MultipleValuesByPassFormatter"/> <!-- 3 -->
 <for-stereotype stereotype="REGIONS"/>
</editor>
regionsEditor.jsp (1) is the JSP file to render the editor. You can define properties that will be sent to the JSP as request parameters (2). And the formatter must implement IMultipleValuesFormatter, that is similar to IFormatter but it uses String [] instead of String. In this case we are using a generic formatter that simply do a bypass.
The last is to write your JSP editor:
<%@ page import="java.util.Collection" %>
<%@ page import="java.util.Collections" %>
<%@ page import="java.util.Arrays" %>
<%@ page import="org.openxava.util.Labels" %>
 
<jsp:useBean id="style" class="org.openxava.web.style.Style" scope="request"/>
 
<%
String propertyKey = request.getParameter("propertyKey");
String [] fvalues = (String []) request.getAttribute(propertyKey + ".fvalue"); // 1
boolean editable="true".equals(request.getParameter("editable"));
String disabled=editable?"":"disabled";
String script = request.getParameter("script");
boolean label = org.openxava.util.XavaPreferences.getInstance().isReadOnlyAsLabel();
if (editable || !label) {
 String sregionsCount = request.getParameter("regionsCount");
 int regionsCount = sregionsCount == null?5:Integer.parseInt(sregionsCount);
 Collection regions = fvalues==null?Collections.EMPTY_LIST:Arrays.asList(fvalues);
%>
<select id="<%=propertyKey%>" name="<%=propertyKey%>" multiple="multiple"
 class=<%=style.getEditor()%>
 <%=disabled%>
 <%=script%>>
 <%
 for (int i=1; i<regionsCount+1; i++) {
 String selected = regions.contains(Integer.toString(i))?"selected":"";
 %>
 <option
 value="<%=i%>" <%=selected%>>
 <%=Labels.get("regions." + i, request.getLocale())%>
 </option>
 <%
 }
 %>
</select>
<%
}
else {
 for (int i=0; i<fvalues.length; i++) {
%>
<%=Labels.get("regions." + fvalues[i], request.getLocale())%>
<%
 }
}
%>
 
<%
if (!editable) {
 for (int i=0; i<fvalues.length; i++) {
%>
 <input type="hidden" name="<%=propertyKey%>" value="<%=fvalues[i]%>">
<%
 }
}
%>
As you see it is like defining a single value editor, the main difference is that the formatted value (1) is an array of strings (String []) instead of a simple string (String).
As alternative, you can define the above editor using checkboxes (new in v4.9), as following:
<%@ page import="java.util.Collection" %>
<%@ page import="java.util.Collections" %>
<%@ page import="java.util.Arrays" %>
<%@ page import="org.openxava.util.Labels" %>
 
<jsp:useBean id="style" class="org.openxava.web.style.Style" scope="request"/>
 
<%
String propertyKey = request.getParameter("propertyKey");
String [] fvalues = (String []) request.getAttribute(propertyKey + ".fvalue");
boolean editable="true".equals(request.getParameter("editable"));
String disabled=editable?"":"disabled";
String script = request.getParameter("script");
boolean label = org.openxava.util.XavaPreferences.getInstance().isReadOnlyAsLabel();
if (editable || !label) {
    String sregionsCount = request.getParameter("regionsCount");
    int regionsCount = sregionsCount == null?5:Integer.parseInt(sregionsCount);
    Collection regions = fvalues==null?Collections.EMPTY_LIST:Arrays.asList(fvalues);
    for (int i=1; i<regionsCount+1; i++) {
        String checked = regions.contains(Integer.toString(i))?"checked":"";
    %>
        <input name="<%=propertyKey%>" type="checkbox" class="<%=style.getEditor()%>"
                tabindex="1"
                value="<%=i%>"
                <%=checked%>
                <%=disabled%>
                <%=script%>
        />
        <%=Labels.get("regions." + i, request.getLocale())%>
    <%
    }
}
else {
    for (int i=0; i<fvalues.length; i++) {
%>
<%=Labels.get("regions." + fvalues[i], request.getLocale())%>
<%
    }
}
%>
 
<%
if (!editable) {
    for (int i=0; i<fvalues.length; i++) {
%>
        <input type="hidden" name="<%=propertyKey%>" value="<%=fvalues[i]%>">
<%
    }
}
%>

Editors for references (new in v3.1.3)

By default references are displayed with a detail view, but you can create your own editor for references. For example, you can write this in the editors.xml file of your application:
<editor url="colorEditor.jsp">
 <for-reference model="Color"/>
</editor>
With the above code you say that any reference to Color entity must be displayed and edited using colorEditor.jsp (for using an editor only for a concrete reference in a concrete entity look at Choosing an editor section in chapter 4).
Here the code for colorEditor.jsp:
<%@page import="java.util.Iterator"%>
<%@page import="org.openxava.test.model.Color"%><%
 
String propertyKey = request.getParameter("propertyKey"); // Id of the key property of the reference (1)
Object value = request.getAttribute(propertyKey + ".value"); // You can use propertyKey + ".value" (2)
if (value == null) value = 0;
 
for (Iterator it = Color.findAll().iterator(); it.hasNext(); ) {
 Color color = (Color) it.next();
 String checked = value.equals(color.getNumber())?"checked='checked'":"";
%>
<span style="font-weight: bold; color: #<%=color.getHexValue()%>; vertical-align: bottom">
 <input name="<%=propertyKey%>" value="<%=color.getNumber()%>" type="radio" <%=checked%>/> <!-- (3) -->
 <%=color.getName()%>
</span>
<%
}
%>
The parameter "propertyKey" (1) give you the id for the key property of the reference. You can use it to name the HTML input element (3) or to get the its current value (2). The list of parameters to be used in a reference editor is:
  1. referenceKey: Unique identifier OX gives to this reference.
  2. propertyKey: Unique identifier of the property that is the key of the reference.
  3. editable: If the reference must be editable by the user.
  4. viewObject: The session object name of the subview that represents this reference. Only applies to composite editors.
  5. propertyPrefix: Prefix used for giving name to editors for properties. Only applies to composite editors.
Moreover, you can define the way all references are displayed by default for your entire application, using <for-references/>. Edit your editors.xml and add:
<editor name="MyReference" url="myReferenceEditor.jsp" frame="true" composite="true">
 <for-references/>
</editor>
Since you have marked the editor with <for-references/> now all the references in your application will be displayed using your myReferenceEditor.jsp. This is a simple way to customize the behaviour of the OpenXava UI generator.

Editors for collections (new in v3.1.3)

By default collections are displayed with a tabular data list, but you can create your own editor for collections. For example, you can write this in the editors.xml file of your application:
<editor url="blogCommentsEditor.jsp">
 <for-collection model="BlogComment"/>
</editor>
With the above code you say that any collection of BlogComment entities must be displayed and edited using blogCommentsEditor.jsp (for using an editor only for a concrete collection in a concrete entity look at Choosing an editor section in chapter 4). <for-collection /> works for @OneToMany/@ManyToMany and @ElementCollection collections.
Here the code for blogCommentsEditor.jsp:
<jsp:include page="collectionEditor.jsp">
 <jsp:param name="listEditor" value="blogCommentsListEditor.jsp"/>
</jsp:include>
This is a typical way to create a collection editor, you call to collectionEditor.jsp (the default OpenXava editor for collections) sending as listEditor argument a JSP that contains the editor for the list part. In this way you have all the actions and default behaviour for collections for free, so you only have to do the rendering of the list.
The blogCommentsListEditor.jsp is:
<%@ include file="../imports.jsp"%>
 
<%@page import="org.openxava.view.View"%>
<%@page import="org.openxava.model.MapFacade"%>
<%@page import="org.openxava.test.model.Blog"%>
<%@page import="org.openxava.test.model.BlogComment"%>
<%@page import="java.util.Iterator"%>
<%@page import="java.util.Map"%>
<%@page import="java.text.DateFormat"%>
<%@page import="org.openxava.util.Locales"%>
<%@page import="org.openxava.util.Is"%>
 
<jsp:useBean id="context" class="org.openxava.controller.ModuleContext" scope="session"/>
 
<%
String viewObject = request.getParameter("viewObject"); // Id to access to the view object of the collection
View collectionView = (View) context.get(request, viewObject); // We get the collection view by means of context
View rootView = collectionView.getRoot(); // In this case we use the root view, the view of Blog
Map key = rootView.getKeyValues();
if (Is.empty(key)) {
%>
There are no comments
<%
} else { // If the key has value, then we render the collection of comments
 
Blog blog = (Blog) MapFacade.findEntity("Blog", key);
String action = request.getParameter("rowAction"); // rowAction is the action to edit or view each element
String actionArgv = ",viewObject=" + viewObject;
%>
 
These are the comments:<br/>
<%
DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, Locales.getCurrent());
int f=0;
for (Iterator it = blog.getComments().iterator(); it.hasNext(); f++) {
 BlogComment comment = (BlogComment) it.next();
%>
<i><b><big>Comment at <%=df.format(comment.getDate())%></big></b></i>
<xava:action action='<%=action%>' argv='<%="row=" + f + actionArgv%>'/>
<p>
<i><%=comment.getBody()%></i>
</p>
<hr/>
<%
}
 
}
%>
This editor draw the blog comments as simple texts with a date as header.
The list of parameters to be used in a list editor for collections is:
  1. collectionName: The name of collection as you write it in your entity.
  2. viewObject: The session object name of the subview that represents this collection.
  3. rowAction: The qualified action name (Controller.action as in controllers.xml) to execute in each element in order to view or edit it.
Of course, you can create your collection editor from scratch, without using collectionEditor.jsp. In this case you have to write the whole user interface for the collection. Look an example in carriersNamesEditor.jsp:
<%@page import="org.openxava.view.View"%>
<%@page import="org.openxava.model.MapFacade"%>
<%@page import="org.openxava.test.model.Carrier"%>
<%@page import="java.util.Iterator"%>
 
<jsp:useBean id="context" class="org.openxava.controller.ModuleContext" scope="session"/>
 
<%
String viewObject = request.getParameter("viewObject"); // viewObject is the id of the view of the parent object
View view = (View) context.get(request, viewObject); // view is the view of Carrier, the parent of the collection
Carrier carrier = (Carrier) MapFacade.findEntity("Carrier", view.getKeyValues());
%>
The fellows of <%=carrier.getName()%> are:<br>
<ul>
<%
for (Iterator it = carrier.getFellowCarriers().iterator(); it.hasNext(); ) {
 Carrier fellow = (Carrier) it.next();
%>
<li><%=fellow.getName()%></li>
<%
}
%>
</ul>
In this case you write the code for render the complete collection, if you wish to have some actions for working with the collection you must put it yourself. Beware, because viewObject here is the view of the object that contains the collection, not the view of the collection itself.
The list of parameters to be used in an editor for collections is:
  1. collectionName: The name of collection as you write it in your entity.
  2. viewObject: The session object name of the view or subview that represents the parent object of this collection.

Moreover, you can define the way all collections are displayed by default for your entire application, using <for-collections/> for @OneToMany/@ManyToMany collections and <for-element-collections/> (new in v5.0) for @ElementCollection. Edit your editors.xml and add:
<editor name="MyCollection" url="myCollectionEditor.jsp">
 <for-collections/>
</editor>
 
<editor name="MyElementCollection" url="myElementCollectionEditor.jsp">
 <for-element-collections/> <!-- New in v5.0 -->
</editor>
Now all @OneToMany/@ManyToMany collections in your application will be displayed using your myCollectionEditor.jsp and all @ElementCollection collections using your myElementCollectionEditor.jsp.

Editors for tabs (list mode) (new in v4.6)

By default tabular data (the data shown in list mode) is displayed with a list, but you can create your own editor for list mode. For example, you can write this in the editors.xml file of your application:
<editor url="corporationEmployeeListEditor.jsp">
  <for-tab model="CorporationEmployee"/>
</editor>
With the above code you say that all tabs (all the lists) for CorporationEmployee entity must be displayed and edited using corporationEmployeeListEditor.jsp (for using an editor only for a concrete tab of an entity look at Choosing an editor section in chapter 5).
Here is the code for corporationEmployeeListEditor.jsp:
<%@ include file="../imports.jsp"%>
 
<jsp:useBean id="context" class="org.openxava.controller.ModuleContext" scope="session"/>
 
<%
String tabObject = request.getParameter("tabObject");
tabObject = (tabObject == null || tabObject.equals(""))?"xava_tab":tabObject;
org.openxava.tab.Tab tab = (org.openxava.tab.Tab) context.get(request, tabObject);
String condition = tab.getBaseCondition()==null?"":tab.getBaseCondition();
String all = condition.equals("")?"selected":"";
String low = condition.contains("<=")?"selected":"";
String high = condition.contains(">")?"selected":"";
String action="openxava.executeAction('OpenXavaTest', 'CorporationEmployee'," +
    "false, false, 'CorporationEmployee.filter', 'segment='+this.value)";
%>
 
<select name="<xava:id name='chooseSegment'/>" style='margin-bottom: 6px' onchange=
    "<%=action%>">
    <option value="all" <%=all%>>All employees</option>
    <option value="low" <%=low%>>Low salary employees</option>
    <option value="high" <%=high%>>High salary employees</option>
</select>
 
<jsp:include page="listEditor.jsp"/>
Note that this editor includes listEditor.jsp at the end. listEditor.jsp is the default editor for list mode, so in this case we only refine the standard list adding a combo to choose a custom filter. However, you can create your own list editor from scratch, for example, the following editor, customerCardListEditor.jsp, shows a list customer as a row of cards:
<%@ include file="../imports.jsp"%>
 
<jsp:useBean id="context" class="org.openxava.controller.ModuleContext" scope="session"/>
 
<%
String collection = request.getParameter("collection");
String id = "list";
String collectionArgv = "";
String prefix = "";
String tabObject = request.getParameter("tabObject");
tabObject = (tabObject == null || tabObject.equals(""))?"xava_tab":tabObject;
if (collection != null && !collection.equals("")) {
    id = collection;
    collectionArgv=",collection="+collection;
    prefix = tabObject + "_";
}
org.openxava.tab.Tab tab = (org.openxava.tab.Tab) context.get(request, tabObject);
org.openxava.tab.impl.IXTableModel model = tab.getTableModel();
for (int r=tab.getInitialIndex(); r<model.getRowCount() && r < tab.getFinalIndex(); r++) {
%>
    <xava:link action="List.viewDetail"><div
      style="border: 2px solid rgb(130, 143, 149); display: inline-block; padding: 10px; margin-bottom: 10px;">
    <h4><%=model.getValueAt(r, 1)%>(<%=model.getValueAt(r, 0)%>)</h4>
    <%=model.getValueAt(r, 2)%><br/>
    <%=model.getValueAt(r, 3)%> (<%=model.getValueAt(r, 4)%>)
    </div></xava:link>
<%
}
%>
Moreover, you can define the way all the lists are displayed by default for your entire application, using <for-tabs/>. Edit your editors.xml and add:
<editor name="MyList" url="myListEditor.jsp">
  <for-tabs/>
</editor>
Since you have marked the editor with <for-tabs/> now all the tabs in your application will be displayed using your myListEditor.jsp. This is a simple way to customize the behaviour of the OpenXava UI generator.

Editors for list formats (new in v5.7)

All the editors marked with <for-tabs/> in default-editors.xml and editors.xml are used as different list formats that the user can choose. For example, if you have this in OpenXava/xava/default-editors.xml:
<editor name="List" url="listEditor.jsp" icon="table-large">
    <for-tabs/>
</editor>
 
<editor name="Charts" url="chartsEditor.jsp"
    selectable-items="false"
    icon="chart-line"
    init-action="Chart.init"
    release-action="Chart.release">
    <for-tabs/>
</editor>
And the next declaration in the editors.xml of your project:
<editor name="MyCards" url="myCardsEditor.jsp" icon="view-module">
    <for-tabs/>
</editor>
Your user will have three formats to choose in the list:
tab050.png
That is, since v5.7 <for-tabs/> does not replace but accumulates. Note the icon attribute in <editor/>, used as the icon for the format button.
If you want to restrict the formats available in your application without touching OpenXava/xava/default-editors.xml use tabs-default-values.xml of your project.
The above is about changing the list formats at global level, if you want to change the formats for a specific list use the editors attribute of @Tab in your entity.

JavaScript in editors

Since v4m3

If you need custom or third-party JavaScript functions to be used from your editor, you cannot include them in the JSP directly, because the editor markup is loaded via AJAX. Instead you have to put your functions in an JS file and put it in the web/xava/editors/js folder of your project. All the JavaScript there is loaded automatically.
That is, if you need to use a JavaScript function f() from your editor, just as following:
<input ... onclick="f()"/>
You have to define the f() function in a JS file. Create a file called myEditor.js (or whatever name you want), and put it in web/xava/editors/js folder. The content of that file can be:
function f() {
alert("Hello. It's f()");
}
On the other hand. If you need JavaScript initialization logic for your editor, you cannot use onload event or equivalent, because the editor markup is loaded via AJAX, so no page loading is produced. You have to register your initialization code in OpenXava. You can do it in your myEditor.js file (or another file in web/xava/editors/js), as following:
openxava.addEditorInitFunction(function() {
/*
Here your initialization code for your editor.
That is the things your usually put in onload JavaScript event
or $(function() { ... }) of jQuery
*/
...
});
You see how using openxava.addEditorInitFunction() to register an initialization function. The onload JavaScript event or ready() event of jQuery does not work, because no page is loaded, instead the editor is generated in the server, loaded via AJAX and inserted in the already displayed page.
Since v4.8.1 you can also define a destroy function for your editor in your myEditor.js file:
openxava.addEditorDestroyFunction(function() { // New in v4.8.1
/*
Here the destroy code for your editor.
This is to free resources obtained by the editor.
*/
...
});

Until v4m2

You have to put all the JavaScript code for all your editors in custom-editors.js in the folder web/xava/js. This technique is still supported though deprecated.

Until 3.0.x

No AJAX is used, so the JavaScript code can be included directly in the JSP for the editor.

CSS in editors (new in v5.4)

All the CSS files in the web/xava/editors/style folder of your application are loaded automatically. Put here the CSS files needed by the JavaScript components and toolkits you use in your editors. Also, you can put here your own CSS for the style specific for your editors. Don't put in web/xava/editors/style the CSS for the overall application style.

Custom editors and stereotypes for displaying combos

You can have simple properties displayed as combos and fill the combos with data from the database.
Let's see this.
You define the properties like this in your entity:
@Stereotype("FAMILY")
private int familyNumber;
 
@Stereotype("SUBFAMILY")
private int subfamilyNumber;
 
And in your editors.xml put:
<editor url="descriptionsEditor.jsp"> <!-- 10 -->
<property name="model" value="Family"/> <!-- 1 -->
<property name="keyProperty" value="number"/> <!-- 2 -->
<property name="descriptionProperty" value="description"/> <!-- 3 -->
<property name="orderByKey" value="true"/> <!-- 4 -->
<property name="readOnlyAsLabel" value="true"/> <!-- 5 -->
<for-stereotype stereotype="FAMILY"/> <!-- 11 -->
</editor>
 
<!-- It is possible to specify dependencies from stereotypes or properties -->
<editor url="descriptionsEditor.jsp" <!-- 10 -->
depends-stereotypes="FAMILY"> <!-- 12 -->
<!--
<editor url="descriptionsEditor.jsp" depends-properties="familyNumber"> <!-- 13 -->
-->
<property name="model" value="Subfamily"/> <!-- 1 -->
<property name="keyProperty" value="number"/> <!-- 2 -->
<property name="descriptionProperties" value="number, description"/> <!-- 3 -->
<property name="condition" value="${familyNumber} = ?"/> <!-- 6 -->
<property name="parameterValuesStereotypes" value="FAMILY"/> <!-- 7 -->
<!--
<property name="parameterValuesProperties" value="familyNumber"/> <!-- 8 -->
-->
<property name="descriptionsFormatter" <!-- 9 -->
value="org.openxava.test.formatters.FamilyDescriptionsFormatter"/>
<for-stereotype stereotype="SUBFAMILY"/> <!-- 11 -->
</editor>
When you show a view with this two properties (familyNumber and subfamilyNumber) OpenXava displays a combo for each property, the family combo is filled with all families and the subfamily combo is empty; and when the user chooses a family, then the subfamily combo is filled with all the subfamilies of the chosen family.
In order to do that you need to assign to stereotypes (FAMILY and SUBFAMILY in this case(11)) the descriptionsEditor.jsp (10) editor and you configure it by assigning values to its properties. Some properties that you can set in this editor are:

  1. model: Model to obtain data from. It can be the name of an entity (e.g. Invoice) or the name of the model used in an embedded collection (Invoice.InvoiceDetail).
  2. keyProperty or keyProperties: Key property or list of key properties; this is used to obtain the value to assign to the current property. It is not required that they are the key properties of the model, although this is the typical case.
  3. descriptionProperty or descriptionProperties: Property or list of properties to show in combo.
  4. orderByKey: If it has to be ordered by the key, by default it is ordered by description. You can also use order with an order clause in SQL style if you need it.
  5. readOnlyAsLabel: When it is read only, then it is rendered as label. The default is false.
  6. condition: Condition to limit the data to be displayed. Has SQL format, but you can use the property names with ${}, even qualified properties are supported. You can put arguments with ?. This last case is when this property depends on other ones and only obtain data when these other properties change.
  7. parameterValuesStereotypes: List of stereotypes from which properties depend. It's used to fill the condition arguments and has to match with depends-stereotypes attribute (12).
  8. parameterValuesProperties: List of properties from which properties depends. It's used to fill the condition arguments and has to match with depends-properties attribute (13).
  9. descriptionsFormatter: Formatter for the descriptions displayed in a combo. It must implement IFormatter.
Following this example you can learn how to create your own stereotypes that display a simple property in combo format and with dynamic data. Nevertheless, in most cases it is more convenient to use references displayed as @DescriptionsList; but you always can choose.

Custom JSP view and OpenXava taglibs

Obviously the better way to create user interfaces is using the view annotations explained in chapter 4. But, in extreme cases perhaps you have to define your view using JSP. OpenXava allows you to do it. And in order to help you to do it, you can use some JSP taglibs provided by OpenXava. Let's see an example.

Example

First you have to define in your module that you want to use your own JSP, in application.xml:
<module name="SellersJSP" folder="invoicing.variations">
<model name="Seller"/>
<view name="ForCustomJSP"/> <!-- 1 -->
<web-view url="custom-jsp/seller.jsp"/> <!-- 2 -->
<controller name="Typical"/>
</module>
If you use web-view (2) on defining your module, OpenXava uses your JSP to render the detail, instead of generating the view automatically. Optionally you can define an OpenXava view using view (1), this view is used to know the events to throw and the properties to populate, if not it is specified the default view of the entity is used; although it's advisable to create an explicit OpenXava view for your JSP custom view, in this way you can control the events, the properties to populate, the focus order, etc explicitly. You can put your JSP inside web/custom-jsp (or other of your choice) folder of your project, and it can be as this one:
<%@ include file="../xava/imports.jsp"%>
 
<table>
<tr>
<td>Number: </td>
<td>
<xava:editor property="number"/>
</td>
</tr>
<tr>
<td>Name: </td>
<td>
<xava:editor property="name"/>
</td>
</tr>
 
<tr>
<td>Level: </td>
<td>
<xava:editor property="level.id"/>
<xava:editor property="level.description"/>
</td>
</tr>
</table>
You are free to create your JSP file as you like, but it can be useful to use OpenXava taglibs, in this case, for example the <xava:editor/> taglib is used, this renders an editor suitable for the indicated property, furthermore add the needed javascript to throw the events. If you use <xava:editor/>, you can manage the displayed data using xava_view (of org.openxava.view.View type) object, therefore all standard OpenXava controllers (including CRUD) work.
You can notice that qualified properties are allowed (as level.id or level.description) (new in v2.0.1), furthermore when you fill level.id, level.description is populated with the corresponding value. Yes, all the behaviour of an OpenXava view is available inside your JSP if you use the OpenXava taglibs.
Let's see the OpenXava taglibs.

xava:editor

The <xava:editor/> tag allows you to render an editor (a HTML control) for your property, in the same way that OpenXava does it when it generates the user interface automatically.
<xava:editor
property="propertyName" <!-- 1 -->
editable="true|false" <!-- 2 New in v2.0.1 -->
throwPropertyChanged="true|false" <!-- 3 New in v2.0.1 -->
/>
  1. property (required): It's the property of the model associated with the current module
  2. editable (optional): New in v2.0.1. Forces to this editor to be editable, otherwise the appropriate default value is assumed.
  3. throwPropertyChanged (optional): New in v2.0.1. Forces to this editor to throws property changed event, otherwise the appropriate default value is assumed.
This tag generates the needed JavaScript in order to allow your view to work in the same way as an automatic one. The qualified properties (properties of references) are supported (new in v2.0.1).

xava:action, xava:link, xava:image, xava:button

The <xava:action/> tag allows you to render an action (a button or a image that the user can click).
<xava:action action="controller.action" argv="argv"/>
The action attribute indicates the action to execute, and the argv attribute (optional) allows you to put values to some properties of the action before execute it. One example:
<xava:action action="CRUD.save" argv="resetAfter=true"/>
When the user clicks on it, then it executes the action CRUD.save, before it puts true to the resetAfter property of the action.
The action is rendered as an image, if it has an image associated. Otherwise it is rendered as a button. If you want to determine the render style, then you can use directly the next taglibs: <xava:button/>, <xava:image/> or <xava:link/> similars to <xava:action/>.
You can specify an empty string as action (new in v2.2.1), as following:
<xava:action action=""/>
In this case the tag has no effect and no error is produced. This feature may be useful if you fill the name of the action dynamically (that is action=”<%=mycode()%>”), and the value can be empty in some cases.

xava:message (new in v2.0.3)

The <xava:message/> tag allows to show in HTML a message from the i18n resource files of OpenXava.
<xava:message key="message_key" param="messageParam" intParam="messageParam"/>
The message is searched first in the message resource files of your project (YourProject/i18n/YourProject-messages.properties) and if it is not found there then it's searched in the default OpenXava messages (OpenXava/i18n/Messages.properties).
The attributes param and intParam are optional. The attribute intParam is used when the value to send as parameter is of int type. If you use Java 5 you can use always param because int is automatically converted by autoboxing.
This tag only generates the message text, without any formatting HTML tags.
An example:
<xava:message key="list_count" intParam="<%=totalSize%>"/>

xava:label (new in v5.5)

The <xava:label/> tag allows to show in HTML a label from the i18n resource labels files of OpenXava.
<xava:label key="memberName"/>
The message is searched first in the label resource files of your project (YourProject/i18n/YourProject-labels.properties) and if it is not found there then it's searched in the default OpenXava labels (OpenXava/i18n/Labels.properties).
This tag only generates the label text, without any formatting HTML tags.
With <xava:label/> instead of writing this:
<tr>
<td>Number: </td><td>
<xava:editor property="number"/>
</td>
</tr>
You can write this:
<tr>
<td><xava:label key="number"/>: </td><td>
<xava:editor property="number"/>
</td>
</tr>
And get the label translated.

xava:descriptionsList (new in v2.0.3)

The <xava:descriptionsList/> tag allows you to render a description list (a HTML combo) for your reference, in the same way that OpenXava does it when it generates the user interface automatically.
<xava:descriptionsList
reference="referenceName" <!-- 1 -->
/>
  1. reference (required): It's a reference of the model associated with the current module
This tag generates the needed JavaScript in order to allow your view to work in the same way as an automatic one.
An example:
<tr>
<td>Level: </td>
<td>
<xava:descriptionsList reference="level"/>
</td>
</tr>
In this case level is a reference of the current model (for example Seller). A combo is shown with all available levels.

Xava Properties Settings

The xava.properties file allows you to change the behavior of OpenXava for the whole application.

Property
Description
Default
E-Mailing
emailAsUserNameInPortal

false
smtpHost
Host for mail send through SMTP provider

smtpHostTrusted (new in v4.7)
if true a mail server with an expired certificate can be used
false
smtpPort
Port for mail send through SMTP provider

smtpUserId
User id for connecting to mail SMTP provider

smtpUserPassword
User password for connecting to the SMTP server

smtpStartTLSEnable (new in v5.6)
If true, enables the use of the STARTTLS command (if supported by the server) to switch the connection to a TLS-protected connection before issuing any login commands. Note that an appropriate trust store must configured so that the client will trust the server's certificate.
false

Persistence
defaultPersistenceUnit
Persistence unit to be used as default
default
jpaCodeInPOJOs (removed since v5.6)

Depends on persistence provider
mapFacadeAsEJB

false
mapFacadeAutoCommit

false
persistenceProviderClass (removed since v5.6)
Defines which class provides the persistence handling
org.openxava.model.impl.JPAPersistenceProvider

Labels, Messages and Locales
i18nWarnings

false
portletLocales
Locales for portlet generation and deployment
bg, ca, de, en, es, fr, in, it, ja, ko, nl, pl, pt, ru, sv, zh

Application and Controllers
defaultLabelFormat
Possibles values for defaultLabelFormat are: NORMAL, SMALL and NO_LABEL
NORMAL
defaultLabelStyle
It has defined: bold-label, italic-label. And you can define your own style.

defaultModeController (new in v4m5)
Possibles values for defaultModeController are Mode, DetailList, DetailOnly, ListOnly and SplitOnly; moreover your own custom controllers. If not specified, the default mode controller associated to the style is used
Mode
duplicateComponentWarnings
On encountering duplicate components like controllers or modules, warning messages are written to the log
true
failOnAnnotationMisuse
Throws error if properties, references or collections have non-applicable annotations
true
generateDefaultModules
If true it is not required to define modules in application.xml, OX generates the modules' information automatically
true

Styling
liferay6StyleClass (new in v4m6)
Style class compatible with liferay 6
org.openxava.web.style.Liferay6Style
liferay51StyleClass
Style class compatible with liferay 5.1
org.openxava.web.style.Liferay51Style
liferay41StyleClass
Style class compatible with liferay 4.1
org.openxava.web.style.Liferay41Style
liferay43StyleClass
Style class compatible with liferay 4.3
org.openxava.web.style.Liferay43Style
styleClass
Class that handles the default UI element class assignment. Provides a simple way of making OX compatible with portal's css classes
org.openxava.web.style.Liferay51Style
styleCSS
URL of CSS file that provides a visual UI style for out of portal OX applications
liferay51/css/everything_unpacked.css
webSpherePortal61StyleClass
Style class compatible with WebSphere Portal 6.1
org.openxava.web.style.WebSpherePortal61Style

Views and Layouts
alignedByColumns (new in v4.7.1)
If true all properties within views are displayed aligned by column same as using # on all views. Active only for default implementations of layoutParser & layoutPainter.
false
buttonsForNoImageActions
If true when an action has no image it uses a button for display it, else it uses a link.
false
layoutParser (new in v4.5)
Name of a layout parser class. Must implement
org.openxava.web.layout.ILayoutParser
Until v5.4.1: org.openxava.web.layout.impl.DefaultLayoutParser
Since v5.5: null (so a JSP parser is used)
layoutPainter (new in v4.5)
Name of a layout painter class.
org.openxava.web.layout.ILayoutPainter
Until v5.4.1: org.openxava.web.layout.impl.DefaultLayoutPainter
Since v5.5: null (so a JSP painter is used)
maxSizeForTextEditor
On large text (String) properties limits the display size to this value
100
messagesOnTop (new in v4.5, until v5.7.1)
If true errors, warnings and messages are displayed at the top, if false they are displayed at the bottom. Since v5.8 you can use CSS to put the messages on bottom.
true
readOnlyAsLabel

false
showIconForViewReadOnly (new in v4.6)


showLabelsForToolBarActions (new in v4m6)
If false the toolbar shows only the action images, no text is displayed
true
useIconsInsteadOfImages (new in v5.4)
When both icon and image are defined for an action, the icon will be used
true
flowLayout (new in v5.7)
If true adjusts the fields layout to the size of the page, ignoring the , ; # used in @View
false
showDefaultActionInBottom (new in v5.8)
If true the default action is shown as the first action in bottom, even if it is already in top buttom bar
true

Lists and Collections
addColumnsPageRowCount (until v5.1.1)
Limits the number of selectable properties that can be added to the columns of lists and collections
100
customizeList (new in v4m5)
If false, list customization is disallowed
true
detailOnBottomInCollections

false
ignoreAccentsForStringArgumentsInConditions
(new in v4m6)
If true it ignores accents to string arguments for conditions in list and collections
false
pageRowCount
Default number of objects to show in lists and collections
10
resizeColumns (new in v4m5)
If false, columns resizing is disabled
true
saveAndStayForCollections (new in v4m6)
If false, the save and stay button is hidden when adding elements to collections
true
showCountInList

true
showIconForViewReadOnly

true
showFilterByDefaultInList
If true filter is show by default for list on init. The user always have the option to show or hide the filter
true
showFilterByDefaultInCollections
If true filter is show by default for collections on init. The user always have the option to show or hide the filter
true
summationInList (new in v4.3)
If true, summary rows are shown at bottom of lists, under numerical columns. Users can manually turn on or off the totals at each column
true
tabAsEJB

false
toUpperForStringArgumentsInConditions
If true upper case conversions are applied to string arguments for conditions in list and collections. If true, also the searching using list or collections are more flexible (the user can use indistinctly upper or lower case) but can be slower in some databases (because they cannot use index)
true
filterOnChange (new in v4.8)
Filtering is done automatically when an option of a combo is chosen, without clicking on filter button
true

Help
helpAvailable (new in v5.6)
If true an icon to go to help is shown in the module
true
helpInNewWindow (new in v4m5)
If true the help page is opened in a new window, if false, the help page is opened in the current window
true
helpPrefix (new in v4m5)
Help prefix for the help URL generation

helpSuffix (new in v4m5)
Help suffix for the help URL generation


FILE/ARCHIVO Stereotype
filePersistorClass
Defines which class provides the storing of attachments.
org.openxava.web.editors.FileSystemPersistor
filesPath
File storage directory, if no database is used.


Reporting
reportParametersProviderClass
class that provides the report parameters
org.openxava.util.DefaultReportParametersProvider

Miscelaneous
csvEncoding (new in v4.2.1)
Because it's impossible to obtain the client encoding, that used by Excel to open the file. UTF-8, ISO-8859-1

csvSeparator

;
hibernateJavaLoggingLevel
Logging level for hibernate. Valid values are: SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST, ALL, OFF
INFO
javaLoggingLevel
Logging level for java. Valid values are: SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST, ALL, OFF
INFO
componentParsersClasses (new in v5.6)
List of comma separated classes used for parsing the components, they must implement
org.openxava.component.parse.IComponentParser
org.openxava.component.parse.XMLComponentParser, org.openxava.component.parse.AnnotatedClassParser
connectionRefinerClass (new in v5.6)
Class to create an org.openxava.util.IConnectionRefiner to refine the JDBC connections just after get them from the data source and before use them.