openCRX Basic Customizing Guide
Version 2.13.0

www.opencrx.org
WORK
in PROGRESS
20-Aug-2014
@ 04:46:37 PM
Figure 1: Types
of openCRX GUIs 9
Figure 2:
Non-Java GUIs for openCRX 9
Figure 3: openCRX
Servlets enabling access with third-party clients 10
Figure 4:
Customizing Options – openCRX Standard HTML GUI 10
Figure 5: openCRX
Development and Customizing with Custom Project 13
Figure 6: UML
Model - CrxObject 15
Figure 7: Add the
string field Y!M nick to Contact objects 15
Figure 8: Wizard
User Settings – enable/disable Root Menu Entries 18
Figure 9: Set
Default Locale by Saving User Settings 20
Figure 10:
Placement of attributes in the attribute pane (Tab, Group,
Position) 25
Figure 11:
Placement of grid tabs (Pane, -, Position) 26
Figure 12:
Placement of attributes in grids (Level 0, Level 1, Level 2) 27
Figure 13: Sample
Extension of class Product with PropertyDataBindings 41
Figure 14: Sample
Extension of class Product with PropertyDataBindings 42
Figure 15:
Property Set Extension 43
Listing 1: UI
Customizing File zorder_contact.xml 16
Listing 2: List
of Packages in web.xml 17
Listing 3:
Enabling/Disabling Packages in web.xml 17
Listing 4:
Locales in web.xml 19
Listing 5:
Activating/Deactivating Locales in web.xml 19
Listing 6: Active
Locales in Login.jsp based on login-locales.jsp 20
Listing 7: UI
Customizing File zorder_product.xml 38
Listing 8:
Example AssignedActivityGroupsDataBinding 49
Listing 9:
Example FilteredActivityGroupsDataBinding 50
Listing 10:
Example FormattedFollowUpDataBinding 51
Listing 11:
Example FormattedNoteDataBinding 52
Listing 12:
Example JoiningListDataBinding 52
Listing 13:
Example Adding a new code to an existing code table 53
Listing 14:
Example Disabling of a code value 53
Listing 15:
uiRefreshRate in web.xml 59
Listing 16:
load-on-startup in web.xml 59
Listing 17:
session-timeout in web.xml 60
Listing 18:
transport-guarantee in web.xml 60
1 About
this Book
This book describes various ways of customizing
the openCRX AJAX HTML GUI to adapt the look and feel to your
personal tastes and preferences or to your company's CI (corporate
identity).
openCRX
is the leading enterprise-class open source CRM suite. openCRX is
based on openMDX,
an open source MDA framework based on the OMG's model driven
architecture (MDA)
standards. This guarantees total openness, standards compliance, a
state-of-the-art component-based architecture, and virtually
unlimited scalability.
1.1 Who
this book is for
The intended audience are openCRX administrators
and advanced users.
1.2 What
do you need to understand this book
It is helpful to have a good understanding of the
openCRX architecture. We assume that you are able to read/understand
the openCRX UML models and the openCRX Javadoc (Java API). It is
also assumed that you are familiar with XML files and you should
know how to program JSPs.
1.3 Tips,
Warnings, etc.
We make use the following
pictograms:

|
Information provided as a “Tip” might be
helpful for various reasons: time savings, risk reduction, etc. -
it goes without saying that we advise to follow our guides
meticulously
meticulous
\muh-TIK-yuh-luhs\, adjective: Extremely or excessively
careful about details.
|

|
You should carefully read information marked
with “Important”. Ignoring such information is typically not
a good idea.
|

|
Warnings should not be ignored (risk of data
loss, etc.)
|
2 Prerequisites
To work through some of the examples and in
particular to build your own customized openCRX, there are some
prerequisites:
You can either follow
the openCRX Server Installer documentation at
http://www.opencrx.org/server.htm
or you can do a manual installation of openCRX following the guide
openCRX
Manual Installation Tomcat 6.
Follow the openCRX
SDK Installer documentation at http://www.opencrx.org/sdk.htm.
Most of the openCRX customizing
files are UTF-8 encoded (see Wikipedia
for information on UTF-8 encoding) and if you intend to edit
such files you must use an UTF-8 enabled editor. Many simple
text editors work fine (e.g. Notepad on Windows, gedit or kate on
Linux), but make sure you test your editor of choice before you
waste a lot of time and end up with ruined files that are not
properly encoded anymore.
While you can manage all your changes
“manually”, we recommend the use of an openCRX custom project.
If you manage your changes and extensions to the standard
distribution of openCRX with a custom project, you will be able to
easily migrate your changes/extensions to new versions of openCRX.
Furthermore, you can easily build customized openCRX EARs.
Instructions on how to create an openCRX custom project are
available from the openCRX
Wiki (see “How to create custom projects”).
Throughout this guide we assume that the custom
project is called sample and the data directory is
org.opencrx.sample. Hence, most of the files you will be
changing/creating in this guide are contained in one of the
subdirectories of the
directory
...\opencrx-custom\sample\src\data\org.opencrx.sample
If you decide to
manipulate files directly in the apps folder, the same files are
contained in one of the subdirectories of the
directory
{TOMCAT_INSTALL_DIR}\apps\opencrx-core-CRX
3 Adapting
the openCRX HTML GUI to Your Needs
3.1 Overview openCRX GUI Types
openCRX is distributed with a generic but
extremely powerful and feature-rich HTML-GUI (built with the
Bootstrap
framework) that works on any device. This AJAX-enabled HTML-GUI
supports a wide range of modern browsers, including Chrome, Firefox,
Opera, Safari, IE, etc. and it supports any device including mobile
devices (iPhone, iPad, Android-based devices, etc.).
The openCRX HTML-GUI connects to the openCRX
backend through the API as shown on the right:
|

|
While this generic GUI has its strengths
(entirely model-driven, light-weight, open and extensible), it also
has its weaknesses (at times it can be hard to understand unless you
are familiar with the openCRX UML model). While we are continuously
enhancing the openCRX GUI, it is still a fact that it is nearly
impossible to write a “one size fits all” GUI.
It is of course also possible to develop
non-Java-based GUIs for openCRX. You could – for example –
write an XML-RRC Adapter (see Apache
XML-RPC).
|

Figure
2: Non-Java GUIs for openCRX
|
Another option you might consider is REST
(Representational State Transfer); see also
http://www.opencrx.org/opencrx/2.3/new.htm#REST
and the openCRX
Wiki (“How to use the REST servlet”).
openCRX includes a
set of servlets (caldav, ical, imap, vcard, rest, news, ...)
allowing you to connect to openCRX with a wide range of specialized
third-party clients like Mozilla Thunderbird, MS Outlook,
SmartPhones, and others:

Figure 3: openCRX Servlets
enabling access with third-party clients
3.2 Customizing Options openCRX HTML GUI
The openCRX
Standard HTML GUI can be customized in many ways to suit your needs:

Basic
customizing options are relatively straight-forward and require no
(or only moderate) programming know how. Advanced customizing
options, however, require a good understanding of the openCRX
architecture. This guide covers basic customizing options. If you're
interested in advanced customizing options, have a look at the
source code or consider attending an openCRX Developer Workshop (see
www.opencrx.org
for more information).
3.3 Things
to do before you start Customizing openCRX
Adapting openCRX to your needs typically involves
the following steps:
Collect the requirements of the (customized) application –
this step requires a solid understanding of the business domain:
your company's
CI information (e.g. color schemes, fonts, etc.)
business
objects and their attributes
mock screens
or screen shots of existing applications
typical use
cases, workflows, etc.
Map the business requirements to openCRX – this step
requires know how across both your business domain and the openCRX
domain:
-

|
Note that
openCRX objects are typically normalized, i.e. it is not
uncommon that a single business object gets spread out across
multiple openCRX objects. In other words, a single business
object and its attributes often times do not map to a single
openCRX object and its attributes.
Example:
mapping the data of a contact as it is available on a business
card typically involves multiple openCRX objects like
Contact
(first/name, ...) or LegalEntity (company name)
PostalAddress
(street, city, zip code, ...)
PhoneNumber (country code, number,
extension, ...)
Hence, study the openCRX UML models before
you start the mapping process. Take your time as the openCRX UML
models are very comprehensive; focus on those aspects of the
model that are most relevant to your project, e.g. account1,
activity1.
|
map business objects to (possibly a list of) openCRX objects;
depending on your business domain you might have to be a little
inventive and maybe adapt/change the meaning of some of the openCRX
objects
map each
attribute of your business objects to an attribute of an openCRX
object
-

|
If you come to
the conclusion that you need additional attributes in certain
openCRX objects, do not jump at extending the openCRX UML model
(such an undertaking requires a solid understanding of the
openCRX architecture and the build processes). Instead, learn
about and understand the following mechanisms for “adding”
additional fields to an object:
|
Customizing
the openCRX Standard HTML GUI
– that is what this guide is all about...
Obviously,
if you're only interested in changing some of the colors, there is
not much to do in step 2 above. However, if you plan to capture your
companies business objects, business processes, forms, etc. with
openCRX, it pays off to spend some time on collecting the
requirements and then properly map them to openCRX before you get
down to customizing...

|
It is a good idea to create an openCRX custom
project before you get started with customizing openCRX. Like
this you will be able to collect all your changes and
enhancements in one place and it will be easy to create custom
EARs which you can readily deploy.
Instructions for creating an openCRX custom
project are available from the openCRX
Wiki.
|
3.4 Limitations
of the generic HTML GUI
Even though the openCRX HTML GUI is extremely
flexible, we would like to point out a few limitations (not due to
bad design, but rather we are looking at advanced features that have
not been implemented yet).
3.4.1 Role-based
UI
openCRX features UI perspectives, a mechanism
that enables users to have different UI customizations based on the
current role (e.g. one GUI for sales and another GUI for the back
office). More information is available from
http://www.opencrx.org/opencrx/2.3/new.htm#UIPerspectives.
Obviously, the same goal can also be achieved
with multiple web applications. Simply create a custom project for
each role / customization and then deploy multiple web applications.
3.4.2 Model
Permissions
Model permissions are not implemented yet. Hence
you cannot control access to individual attributes of an object with
simple customization (the openCRX security plugin controls access to
complete objects, not to individual attributes of an object). You
can, however, deploy multiple web applications or work with Layout
JSPs to achieve the same goal. Alternatively, once the root admin
(admin-Root) has defined a security policy, segment administrators
can grant and/or revoke various GUI-level permissions . More
information is available in the openCRX Admin Guide at
http://www.opencrx.org/documents.htm.
4 Important
Hints
The following information is so important that it
deserves its own chapter!
4.1 Overloading
Overloading is a concept that allows you to
selectively enhance (or even replace) features of the standard
distribution of openCRX with your own changes and/or extensions.

|
The architecture of openCRX is such that you
should be able to add your own customizing and extensions without
actually changing any of the core files of the distribution.
The big advantage of leaving core files unchanged and keeping all
your changes/extensions separate is release capability,
i.e. instead of creating and then maintaining your own openCRX
branch (which you should really try to avoid) you keep your
changes and extensions in a custom project.
The reason is the following one: maintaining
your own openCRX branch requires advanced know how, i.e. it
is difficult and very time-consuming, whereas maintaining your
own custom project is easy because upgrading your custom
project to a new openCRX version typically requires minor changes
only (if any at all).
Do not go for quick fixes by changing files of
the core distribution as you are guaranteed to run into problems
down the road. Make use of openCRX custom projects and use
the power and the flexibility of the openCRX SDK and the various
overloading concepts.
|

Figure 5: openCRX
Development and Customizing with Custom Project
4.1.1 File
Overloading at the Project Level
Typically, files in your custom project will be
added to the custom EARs. However, if a file in your custom
project has the same name as a file of the standard distribution,
your file will actually replace the respective file of the
standard distribution when you build custom EARs.
Example:
|
Let's suppose
you want to add some fancy CSS to openCRX. If you call your file
myFancy.css and put it
into the directory
sample\src\data\org.opencrx.sample\_style
your css file will be added
to the various css files that already exist when you build your
custom EARs. If you call your file colors.css,
however, your file will replace the file with the same
name that is contained in the standard distribution of openCRX
(and unless you know what your doing it is quite likely that the
coloring of openCRX will look strange with your custom EARs...).
|
4.1.2 UI
Configuration Overloading
It is likely that
you want to change some of the default customizing. Quite possibly,
however, (a) you want to make a few changes only and (b) you want to
keep these changes if you upgrade to a new version of openCRX. This
is where UI configuration overloading can add value. Instead of
changing the original UI configuration files provided with the
standard distribution you create a new configuration file (or
multiple configuration files) containing all your changes. Make sure
that you name your file(s) containing changed UI Element Definitions
such that your changes are loaded AFTER the default configuration
files, thereby overloading the original configuration.
More information is available in chapter 8.2 UI Configuration Overloading.
4.1.3 Code
Table Overloading
Similar to UI
configuration overloading, you can also overload code tables.
Instead of changing original code tables you create new code table
files that contain your changes/extensions. It is also possible to
deactivate codes of the standard distribution. Make sure that you
name your file(s) containing changed code tables such that your
changes are loaded AFTER the default code tables, thereby
overloading the code tables.
More information is available in chapter 9.2 Code Table Overloading.

|
UI configuration files and code table files
are loaded in alphabetical order. Hence, if the same
element is defined multiple times, the definition contained in
the file that is (in alphabetical order) loaded last wins.
|
4.2 “Adding”
Fields / Extending Objects
Even though the openCRX
UML Model covers a wide range of business objects, you may still
want to “add” a field to a particular object. While the newbie's
approach would be to add a field to the appropriate database table
and then patch the code a bit here and there, take our advice and
make use of the advanced extension mechanisms provided by openCRX.
4.2.1 User-definable attributes of CrxObject

Figure
6: UML Model - CrxObject
|
The vast majority
of openCRX's objects are CrxObjects, and hence they feature
user-definable attributes as shown in the figure on the left.
There are four single-valued attributes and one multi-valued
attribute of each type:
boolean
decimal
string
dateTime
date
code
In the standard
distribution of openCRX these attributes are disabled (i.e. set
to <active>false</active>).
You can verify this by looking at the UI customizing file
.../config/ui/Root/en_US/common_userdefined.xml
(search for CrxObject:user).
Note that all of these user-definable
attributes are already available in the DB schemas, i.e. they are
ready to be used, you just have to enable them.
|
To make an example,
let's assume your Contacts absolutely need another String field to
store the Yahoo!
Messenger Nickname as shown below:

Figure 7: Add the string
field Y!M nick to Contact objects
All you have to do to
“add” the field Y!M nick to Contacts is to deploy the following
UI customizing file zorder_contact.xml
to the directory
{TOMCAT_INSTALL_DIR}/apps/opencrx-core-CRX/opencrx-core-CRX/WEB-INF/config/ui/Root/en_US
and then restart Tomcat.
Listing 1: UI Customizing File zorder_contact.xml
<?xml
version="1.0" encoding="UTF-8"?>
<org.openmdx.base.Authority
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
name="org:openmdx:ui1"
xsi:noNamespaceSchemaLocation="xri://+resource/org/openmdx/ui1/xmi1/ui1.xsd">
<_object/>
<_content>
<provider>
<org.openmdx.base.Provider qualifiedName="CRX"
_operation="null">
<_object/>
<_content>
<segment>
<org.openmdx.ui1.Segment qualifiedName="Root"
_operation="null">
<_object/>
<_content>
<elementDefinition>
<org.openmdx.ui1.ElementDefinition
name="org:opencrx:kernel:account1:Contact:userString0">
<_object>
<active>true</active>
<toolTip>
<_item>Y!M
nick</_item>
</toolTip>
<label>
<_item>Y!M
nick</_item>
</label>
<order>
<_item>0</_item> <!-- tab -->
<_item>0</_item> <!-- field group
-->
<_item>75</_item> <!--
position -->
</order>
</_object>
<_content/>
</org.openmdx.ui1.ElementDefinition>
</elementDefinition>
</_content>
</org.openmdx.ui1.Segment>
</segment>
</_content>
</org.openmdx.base.Provider>
</provider>
</_content>
</org.openmdx.base.Authority>
The above file is –
strictly speaking – not adding a field to the class Contact, it is
rather activating the attribute userString0 of the class Contact
(which it inherits from the class CrxObject). The field userString0
is already available in the standard distribution of openCRX, it's
just not visible by default.

|
Mapping your special requirements to
user-definable attributes is an extremely efficient way of
“extending” the standard distribution of openCRX, also in
terms of performance.
|
4.2.2 Property
Data Bindings
What can you do if you need even more
user-definable attributes, i.e. more than the ones provided by
CrxObject? This is where the PropertyDataBinding concept comes in
handy. With PropertyDataBindings you get access to a virtually
unlimited pool of user-definable attributes. See chapter 8.7.1 PropertyDataBinding
for a detailed introduction into this topic).
5 Managing
Packages
5.1 Enabling/Disabling Packages at the Application Level
With the openCRX standard distribution all
available packages are enabled. The openCRX administrator may wish
to disable certain packages at the application level if they are not
used. This chapter shows how you can achieve this.
In the custom
project sample, the package list is contained in the file:
opencrx—custom\sample\src\data\org.opencrx.sample\WEB-INF\web.xml
Once deployed on Tomcat, the package list is contained in the file
apps\opencrx-core-CRX\opencrx-core-CRX\WEB-INF\web.xml
Look for the section <!-- Admin
--> to find a list of available packages:
Listing 2: List of Packages in web.xml
<!-- Admin
-->
<init-param>
<param-name>rootObject[0]</param-name>
<param-value>xri:@openmdx:org.opencrx.kernel.admin1/provider/CRX/segment/${SEGMENT}</param-value>
</init-param>
<!--
Home -->
<init-param>
<param-name>rootObject[1]</param-name>
<param-value>xri:@openmdx:org.opencrx.kernel.home1/provider/CRX/segment/${SEGMENT}/userHome/${USER}</param-value>
</init-param>
...
You can disable
packages by commenting them out (<!--
to open a comment and -->
to close a comment). The following example shows how to deactivate
the package depot1:
Listing 3: Enabling/Disabling Packages in web.xml
...
</init-param>
<!-- Depots -->
<!--
<init-param>
<param-name>rootObject[6]</param-name>
<param-value>xri:@openmdx:org.opencrx.kernel.depot1/provider/CRX/segment/${SEGMENT}</param-value>
</init-param>
-->
<!--
Documents -->
<init-param>
<param-name>rootObject[6]</param-name>
<param-value>xri:@openmdx:org.opencrx.kernel.document1/provider/CRX/segment/${SEGMENT}</param-value>
</init-param>
<!--
Buildings -->
...

|
Please note that you must renumber all the
packages listed after the package you deactivated so that the
package numbering does not have any gaps (i.e. numbering of
active packets starts at 0 and it must be consecutive).
|

|
It is also possible to change the order of the
active packages by renumbering them. However, you must still
ensure both that the numbering starts at 0 and that the numbering
is consecutive.
|
5.2 Enabling/Disabling
Packages at the User Level
The most important
personalization settings – including enabling/disabling of
packages – are easily managed with the wizard User Settings.
Navigate to your home page (click Home
in the root menu) and then select Edit
> User Settings
from the main menu to start the User Settings Wizard.
1
|
set
your timezone – you can use either the upper drop down (lists
timezone names ordered by timezone) or the lower drop down
(lists them in alphabetical order)
|
         
Figure
8: Wizard User Settings – enable/disable Root Menu Entries
|
2
|
check
this box if you want openCRX to automatically save your current
settings whenever you logoff; if unchecked, changes made during a
session will be lost after logoff unless you save them manually
|
3
|
enter
the e-mail address at which you want to receive notification
e‑mails from openCRX
|
4
|
enter a
prefix that will be added to the subject of all notification
e‑mail messages sent to you by openCRX
|
5
|
the web
access URL is used in all notification e-mails – you may have
to adapt it if your openCRX server is moved to a new domain/etc.
|
6
|
every
user can enable/disable any of the packages activated by the
openCRX application manager – a particular package is only
listed in the package menu if the respective box is checked;
furthermore,
|
|
if
multiple perspectives are available (e.g. Root, Advanced,
Simple), every user can maintain a list of enabled packages for
each perspective
|
7
|
enter
the number of package menu entries to be accessible with a single
click – all other enabled packages are put into the package
menu overflow
|
8
|
check
to hide the workspace dashboard, uncheck to make it visible
|
9
|
every
user can enable/disable any of the subscriptions
configured by the openCRX application manager; detailed
information about the openCRX notification engine is available in
the
openCRX Admin Guide at http://www.opencrx.org/documents.htm)
|

|
Please note that entries corresponding to
packages disabled by the openCRX administrator cannot be enabled
with this wizard. Packages disabled in web.xml are not available
at all (and not shown in the wizard User Settings)!
|
6 Managing
Locales
The default installation of openCRX activates all
locales that are included in the Open Source distribution. The
openCRX administrator may wish to deactivate certain locales from
the locale list. This chapter shows how you how to do this.
6.1 Enabling/Disabling
Locales at the Application Level
The locale list is contained in the file
opencrx-core-CRX.ear\opencrx-core-CRX.war\WEB-INF\web.xml
Look for the section <!--
locales --> to find a list of available locales:
Listing 4: Locales in web.xml
<!-- locales
-->
<init-param>
<param-name>locale[0]</param-name>
<param-value>en_US</param-value>
</init-param>
<init-param>
<param-name>locale[1]</param-name>
<param-value>de_CH</param-value>
</init-param>
<init-param>
<param-name>locale[2]</param-name>
<param-value>es_MX</param-value>
</init-param>
...
You can deactivate locales by simply commenting
them out. The following example shows how to deactivate the locale
de_CH.
Listing 5: Activating/Deactivating Locales in web.xml
<!-- locales
-->
<init-param>
<param-name>locale[0]</param-name>
<param-value>en_US</param-value>
</init-param>
<!--
<init-param>
<param-name>locale[1]</param-name>
<param-value>de_CH</param-value>
</init-param>
-->
<init-param>
...

|
Please note that you must not
deactivate the base locale (that is the locale with the id 0,
typically en_US) as the base locale contains a lot of customizing
information not present in other locales.
|
As the Login page is displayed before the
authentication of the user has taken place, Login.jsp cannot access
the above information. That is why the list of available and active
locales are maintained in the file login-locales.jsp
as well. Changing the list of active locales is straightforward.
Comment out any of the lines in the following code segment of
localeSettings.jsp to disable the respective locale:
Listing 6: Active Locales in Login.jsp based on
login-locales.jsp
...
activeLocales.add("en_US");
activeLocales.add("cs_CZ");
activeLocales.add("de_CH");
activeLocales.add("es_CO");
activeLocales.add("es_MX");
//
activeLocales.add("fa_IR"); this locale is not
active
activeLocales.add("fr_FR");
activeLocales.add("it_IT");
activeLocales.add("ja_JP");
//
activeLocales.add("nl_NL"); this locale is not
active
activeLocales.add("pl_PL");
activeLocales.add("pt_BR");
activeLocales.add("ro_RO");
activeLocales.add("ru_RU");
activeLocales.add("sk_SK");
activeLocales.add("sv_SE");
activeLocales.add("tr_TR");
activeLocales.add("zh_CN");
...
The above example
shows how to disable the locales fa_IR and nl_NL in the Login page
of openCRX.

|
Note that you must use an UTF-8 enabled
editor to change the file login-locales.jsp.
If you break the UTF-8 encoding of this file your locale drop
will contain strange symbols...
|
6.2 Setting
the Default Locale at the User Level

A
user's default locale can be set by choosing/activating the desired
locale (step 1) and then clicking on [Save
Settings] (step 2) in the header of the application as shown
below:

If the
login page supports a user's preferred locale xx_YY, you can request
the login page in that locale xx_YY by appending the string
"?locale=xx_YY"
to the default login URL.
Example:
the following URL loads the German login page:
http://demo.opencrx.org/opencrx-core-CRX/Login.jsp?locale=de_CH
7 CSS,
Headers, Footers, etc.
7.1 Cascading Style Sheets
The directory ...\opencrx-core-CRX\_style
contains various CSS files:
Please note that various third-party modules
(e.g. WYMeditor, wiky) may also load CSS files. Those files are
typically located within the respective modules directory structure
(e.g. .../javascript/wymeditor, .../javascript/wiky).

|
Adding (internal
and/or external) style sheets to all pages is easy as all pages
are generated by the following 2 Layout JSPs:
...\opencrx-core-CRX\WEB-INF\config\layout\en_US\edit-Default.jsp
...\opencrx-core-CRX\WEB-INF\config\layout\en_US\show-Default.jsp
See also
chapter 13 Layout JSPs for additional information.
|
7.2 HTML Header and Footer Files
The Layout JSPs and the login page (Login.jsp) by
default include various HTML files. They are located in the
directory ...\opencrx-core-CRX
and you can adapt them to your liking:
login-header.html
login-footer.html
login-note.html
|
edit-header.html
edit-footer.html
|
|
See
also chapter 13 Layout JSPs for additional information.
8 UI
XML Files
8.1 Overview
8.2 UI
Configuration Overloading
8.3 Inspector
The inspector shows an object with its
attributes:

8.4 Attribute
Pane
8.4.1 Tabs
The ui file common.xml
contains tab definitions that apply to all objects :
[General]
|
Tab:0
|
this tab typically contains the most important
attributes of an object and is almost always visible
|
[Details]
|
Tab:10
|
this tab typically contains attributes that
are used less frequently; if no attributes are assigned to this
tab then it is not visible
|
[User]
|
Tab:90
|
by default all user defined attribute are
assigned to this tab; this tab, however, is not visible by
default
|
[System]
|
Tab:900100
|
this tab typically contains various system
attributes related to object creation and object changes,
security, etc.
|
You
can define your own tabs. The following example shows the definition
of the tab [Accounts] of the attribute pane of accounts (ui
file account.xml):
Example
|
<org.openmdx.ui1.ElementDefinition
name="org:opencrx:kernel:account1:Account:Pane:Attr:Tab:25">
<_object> <active>true</active>
<toolTip> <_item>Account</_item>
</toolTip> <label>
<_item>Account</_item> </label>
</_object>
<_content/> </org.openmdx.ui1.ElementDefinition>
|
8.4.2 Field
Groups
In the ui file common.xml
there are various default field groups defined that apply to all
objects, e.g. Field Groups 0, 10, 20, and 30 in the the tabs
[General] and [Details].
You can define your
own field groups like shown in the following example:
Example
|
<org.openmdx.ui1.ElementDefinition
name="org:opencrx:kernel:account1:Account:Pane:Attr:Tab:25:Group:10">
<_object> <active>true</active>
<toolTip> <_item></_item>
</toolTip> <label>
<_item>&nbsp;</_item> </label>
</_object>
<_content/> </org.openmdx.ui1.ElementDefinition>
|
8.4.3 Fields / Attributes
With order (or more specifically
orderFieldGroup) you can define the positioning of an
object's attribute in the attribute pane. You must provide three
values in the form of <_item>xxx</item>
where the first value corresponds to the id of the Tab, the second
value to the FieldGroup and the third value to the position within
the respective FieldGroup.
The following example explains the placement of a
contact's salutation:

Figure 10: Placement of
attributes in the attribute pane (Tab, Group, Position)
With the
tag <columnBreak>true</columnBreak>
you can place the current attribute in a new column within the given
Field Group.
8.5 Grid Panes
Shared and composite associations as well as
multi-valued references are mapped to grids. Such grids can be
positioned by providing three values in the form of
<_item>xxx</item>
where the first value corresponds to the id of the Grid Pane and the
third value to the position within the respective Pane (the second
value is not used).
The following example explains the placement of
an accounts composite association “member”:

Figure 11: Placement of
grid tabs (Pane, -, Position)
With order (or more specifically
orderObjectContainer) you can define the positioning of an
object's attribute within grids. You must provide three values in
the form of <_item>xxx</item>
where these values will used to define an (alphabetical) order.
The
following example explains the placement of a an address's usage:

Figure 12: Placement of
attributes in grids (Level 0, Level 1, Level 2)

|
Please
note that since openCRX v2.13.0 users can change the order of
grid columns interactively by opening a grid's View menu
and then selecting the entry of the grid column they want to move
to the right:

|
8.5.1 Expanding/Collapsing Tabs
Grid Tabs are
rendered collapsed if the label starts with a “»”
character:
Example
|
<org.openmdx.ui1.ElementDefinition
name="org:opencrx:kernel:account1:Account:partner">
<_object> <active>true</active>
<toolTip> <_item>Partners</_item>
</toolTip> <label>
<_item>»Partners</_item> </label>
<order> <_item>0</_item>
<_item>0</_item> <_item>97</_item>
</order> </_object>
<_content/> </org.openmdx.ui1.ElementDefinition>
|
8.5.2 AdditionalElementDefinition
With AdditionalElementDefinitions you can define
additional grid tabs (optionally with base filters). Have a look at
the UI XML file accounts.xml
which makes use of this feature to create various additional grid
tabs:
Example
|
<org.openmdx.ui1.ElementDefinition
name="org:opencrx:kernel:account1:Segment:account">
<_object> <active>true</active>
<toolTip> <_item>All Accounts</_item>
</toolTip> <label> <_item>»All
Accounts</_item> </label> <order>
<_item>0</_item> <_item>0</_item>
<_item>500</_item> </order>
<maxMember>23</maxMember>
<showMaxMember>7</showMaxMember> </_object>
<_content> <additionalElementDefinition>
<org.openmdx.ui1.AdditionalElementDefinition id="9998"
_operation="create"> <_object>
<toolTip> <_item>Accounts</_item>
</toolTip> <label>
<_item>Accounts</_item> </label>
<order> <_item>0</_item>
<_item>0</_item>
<_item>10</_item> </order>
<maxMember>23</maxMember>
<showMaxMember>7</showMaxMember>
</_object> <_content/>
</org.openmdx.ui1.AdditionalElementDefinition>
<org.openmdx.ui1.AdditionalElementDefinition id="9999"
_operation="create"> <_object>
<toolTip> <_item>Accounts
(disabled)</_item> </toolTip>
<label> <_item>»Accounts
(disabled)</_item> </label>
<order> <_item>0</_item>
<_item>0</_item>
<_item>510</_item> </order>
<maxMember>23</maxMember>
<showMaxMember>7</showMaxMember>
</_object> <_content/>
</org.openmdx.ui1.AdditionalElementDefinition>
<org.openmdx.ui1.AdditionalElementDefinition id="0"
_operation="create"> <_object>
<toolTip> <_item>Account
Groups only</_item> </toolTip>
<label> <_item>Account
Groups</_item> </label>
<order> <_item>0</_item>
<_item>0</_item>
<_item>15</_item> </order>
<maxMember>23</maxMember>
<showMemberRange>
<_item>0:0:0-0:0:7</_item>
<_item>0:0:9-0:0:9</_item>
</showMemberRange>
<showMaxMember>7</showMaxMember>
</_object> <_content/>
</org.openmdx.ui1.AdditionalElementDefinition>
</additionalElementDefinition>
</_content> </org.openmdx.ui1.ElementDefinition>
|
The respective base filters (see chapter 8.5.3 Base Filter for Grid Tabs
for additional information) are defined in the following file:
...\filters\org.opencrx.kernel.account1.Segment.account.xml
8.5.3 Base
Filter for Grid Tabs
You can (optionally) define base filters for grid
tabs. That is, for example, an elegant way of splitting up the tab
[All Accounts] into
[Accounts] (that are
active) and [Accounts (disabled)].
The following example assumes that you have
created an accounts tab with id 10000 (with an
AdditionalElementDefinition) and shows how to create a base filter
that selects only accounts that have a an address with a postal code
equal to 8000. Create a file named
org.opencrx.kernel.account1.Account.postal.xml
with the following content and then move the file to the directory
...\WEB-INF\config\filters:
Example
|
<?xml version="1.0"
encoding="UTF-8"?> <java version="1.4.2_06"
class="java.beans.XMLDecoder"> <object
class="org.openmdx.portal.servlet.Filters">
<void property="forReference"> <array
class="java.lang.String" length="1">
<void index="0">
<string>org:opencrx:kernel:account1:Segment:account</string>
</void> </array> </void>
<void property="filter"> <array
class="org.openmdx.portal.servlet.Filter" length="1">
<void index="0"> <object
class="org.openmdx.portal.servlet.Filter">
<void property="name">
<string>account:10000</string>
</void> <void property="iconKey">
<string>spacer.gif</string>
</void> <void property="condition">
<array class="org.openmdx.base.query.Condition"
length="2"> <void index="0">
<object
class="org.openmdx.base.query.PiggyBackCondition">
<void property="quantor">
<short>1</short>
<!-- for all --> </void>
<void property="feature">
<string>context:postalCode:object_class</string>
</void> <void
property="fulfil">
<boolean>true</boolean>
</void> <void property="value">
<array class="java.lang.String"
length="1"> <void
index="0">
<string>org:openmdx:compatibility:datastore1:QueryFilter</string>
</void>
</array> </void>
</object> </void>
<void index="1">
<object class="org.openmdx.base.query.PiggyBackCondition">
<void property="quantor">
<short>1</short>
<!-- for all --> </void>
<void property="feature">
<string>context:postalCode:clause</string>
</void> <void
property="fulfil">
<boolean>true</boolean>
</void> <void property="value">
<array class="java.lang.String"
length="1"> <void
index="0">
<string>EXISTS (SELECT 0 FROM OOCKE1_ADDRESS addr WHERE
addr.p$$parent = v.object_id AND addr.postal_code =
'8000')</string> </void>
</array>
</void> </object>
</void> </array>
</void> <void property="groupName">
<string>~</string>
</void> </object> </void>
</array> </void> </object> </java>
|
See also the discussion
at
https://sourceforge.net/projects/opencrx/forums/forum/329844/topic/3763898
8.5.4 Selection of Filterable Attributes (maxMember)
With maxMember you can define the number of
attributes that are available for filtering/sorting in the openCRX
GUI. Setting maxMember to a value “n” implies that (at most) n
attributes are available for filtering/searching even though more
attributes would be available given the model.
8.5.5 Selection of Visible Attributes (showMaxMember)
With showMaxMember you can define the number of
attributes (at most “maxNumber” attributes) that are visible in
a grid. If all the attributes that are filterable/searchable should
also be visible, there is no need to set showMaxMember.
8.5.6 Advanced Attribute Selection (showMemberRange)
There are quite a number of grids that contain
objects with quite different attribute sets (think of subclasses),
e.g. the address grid contains web addresses, phone numbers, e-mail
addresses, etc. As it does not make a lot of sense to display the
complete (sparse) matrix, you can selectively pick individual
attributes (or even ranges of attributes) to display in a grid.
The following example shows how showMemberRange
is used to define the grid “Groups” as it is available in the
standard openCRX distribution:
Example
|
... <org.openmdx.ui1.AdditionalElementDefinition
id="0" _operation="create">
<_object>
<toolTip>
<_item>Account Groups
only</_item>
</toolTip>
<label>
<_item>Account Groups</_item>
</label>
<order>
<_item>0</_item>
<_item>0</_item>
<_item>15</_item>
</order>
<maxMember>23</maxMember>
<showMemberRange>
<_item>0:0:0-0:0:7</_item>
<_item>0:0:9-0:0:9</_item>
</showMemberRange>
<showMaxMember>7</showMaxMember>
</_object>
<_content/>
</org.openmdx.ui1.AdditionalElementDefinition>
...
|
8.6 Various
XML Tags Explained
8.6.1 active
Purpose
|
Enable or disable a UI element. No default
value.
|
Examples
|
<active>true</active>
<active>false</active>
|
8.6.2 backColor
Purpose
|
Set the background color of an attribute. No
default value.
|
Examples
|
<backColor>#FF0000</backColor>
<backColor>inherit</backColor>
|
8.6.3 changeable
Purpose
|
Enable updates or limit access to read-only. Default value is
true.
|
Examples
|
<changeable>true</changeable>
<changeable>false</changeable>
|
8.6.4 color
Purpose
|
Set the (font) color of an attribute. No
default value.
|
Examples
|
<color>#FFFFFF</color>
<color>inherit</color>
|
8.6.5 columnBreak
Purpose
|
Add column break so that the current element
is the first element of a new column within given field group. No
default value.
|
Examples
|
<columnBreak>true</columnBreak>
<columnBreak>false</columnBreak>
|
8.6.6 cssClassFieldGroup
Purpose
|
Set a custom class for the inspector's field
group container
|
Examples
|
to right-align the amount field
“totalBaseAmount” in the inspector pane provide a class name,
e.g. alignRight, in the UI customizing file:
<org.openmdx.ui1.ElementDefinition
name="org:opencrx:kernel:contract1:SalesContract:totalBaseAmount">
<_object>
<columnBreak>true</columnBreak>
<active>true</active>
<changeable>false</changeable>
<cssClassFieldGroup>alignRight</cssClassFieldGroup>
<cssClassObjectContainer>alignRight</cssClassObjectContainer>
<toolTip> <_item>Total base
amount</_item>
</toolTip>
<label>
<_item>Total base amount</_item>
</label>
<order>
<_item>0</_item>
<_item>50</_item>
<_item>90</_item>
</order>
</_object>
<_content/>
</org.openmdx.ui1.ElementDefinition>
and then make sure that you define an
appropriate style for the class “alignRight”, e.g. as
follows:
.alignRight { text-align: right;
}
|
8.6.7 cssClassObjectContainer
Purpose
|
Set a custom class for the grid's group
container.
|
Examples
|
to right-align the amount field
“totalBaseAmount” in the grid provide a class name, e.g.
alignRight, in the UI customizing file:
<org.openmdx.ui1.ElementDefinition
name="org:opencrx:kernel:contract1:SalesContract:totalBaseAmount">
<_object>
<columnBreak>true</columnBreak>
<active>true</active>
<changeable>false</changeable>
<cssClassFieldGroup>alignRight</cssClassFieldGroup>
<cssClassObjectContainer>alignRight</cssClassObjectContainer>
<toolTip> <_item>Total base
amount</_item>
</toolTip>
<label>
<_item>Total base amount</_item>
</label>
<order>
<_item>0</_item>
<_item>50</_item>
<_item>90</_item>
</order>
</_object>
<_content/>
</org.openmdx.ui1.ElementDefinition>
and then define an appropriate style for the
class “alignRight”
|
8.6.8 defaultValue
Purpose
|
Default value of an attribute when a new
object is created. No default value.
|
Examples
|
<defaultValue>true</defaultValue>
<defaultValue>7</defaultValue>
|
8.6.9 filterable
Purpose
|
Enable or disable filtering for an attribute.
While you can disable filtering on any attribute, enabling
filtering makes only sense if the respective query is
implemented. By default, filtering is not supported for
references. Default value is true.
|
Examples
|
<filterable>true</filterable>
<filterable>false</filterable>
|
8.6.10 iconKey
Purpose
|
Allows you to set the name of the GIF file
that gets displayed for a particular object type. Default value
is class name.
|
Examples
|
<iconKey>AccountAssignment</iconKey>
<iconKey>Contact</iconKey>
|
8.6.11 isPassword
Purpose
|
Allows you to mark a particular attribute as
password. Default value is false.
|
Examples
|
<isPassword>true</isPassword>
<isPassword>false</isPassword>
|
8.6.12 label
Purpose
|
Allows you to set the label of an object. No
default value.
|
Examples
|
<label>
<_item>Related
Products</_item>
</label>
|
8.6.13 mandatory
Purpose
|
Make an attribute mandatory or optional.
Default value is false for optional attributes (according to UML
model) and true otherwise.
|
Examples
|
<mandatory>true</mandatory>
<mandatory>false</mandatory>
|
8.6.14 minValue
Purpose
|
Define the minimum acceptable value of a
numerical field. No default value.
|
Examples
|
<minValue>0</minValue>
<minValue>-100</minValue>
|
8.6.15 maxLength
Purpose
|
Limit the size of an input field (i.e. number
of characters a user can enter). No default value.
|
Examples
|
<maxLength>5</maxLength>
<maxLength>255</maxLength>
|
8.6.16 maxMember
Purpose
|
Set the maximum number of attributes that are
available in a grid (not necessarily visible, but at least
filterable). The default value is 6.
|
Examples
|
<maxMember>0</maxMember>
<maxMember>-100</maxMember>
|
8.6.17 maxValue
Purpose
|
Define the maximum acceptable value of a
numerical field. No default value.
|
Examples
|
<maxValue>0</maxValue>
<maxValue>-100</maxValue>
|
8.6.18 multiplicity
Purpose
|
multi-valued codes (e.g. userCode4) can
(optionally) be limited to support only a certain number of
values
|
Examples
|
<multiplicity>0..2</multiplicity>
|
8.6.19 order
see chapters 8.4.3 Fields / Attributes and 8.5 Grid Panes
8.6.20 orderFieldGroup
see chapter 8.4.3 Fields / Attributes
8.6.21 orderObjectContainer
see chapter 8.5 Grid Panes
8.6.22 showMaxMember
see chapter 8.5.5 Selection of Visible Attributes (showMaxMember)
8.6.23 showMemberRange
see chapter 8.5.6 Advanced Attribute Selection (showMemberRange)
8.6.24 eventHandler
any valid Javascript string (will be embedded in
edit pages)
8.6.25 skipRow
8.6.26 spanRow
8.6.27 sortable
8.6.28 toolTip
Title tag for labels are created automatically if
the contents of the toolTip differs from the contents of the name
tag. The following screen shot shows the toop tip of the attribute
salutationCode as displayed in a browser:

8.7 DataBindings
Data bindings are interceptors which allow to
perform any kind of transformation on data retrieved from the
backend. The default data binding
org.openmdx.portal.servlet.DefaultDataBinding is trivial (a simple
delegator).
8.7.1 PropertyDataBinding
PropertyDataBindings provide you with access to a
virtually unlimited pool of user-definable attributes to extend
CrxObjects. From a performance point of view, PropertyDataBindings
are not quite as efficient as the User-definable attributes of CrxObject
because the latter are always stored in the same table as the
extended object, whereas attributes based on PropertyDataBindings
are stored in a separate table (leading to additional SELECT
statements). Nevertheless, whenever you need additional attributes
that cannot be mapped to user-definable attributes, you should still
consider PropertyDataBindings before you jump at extending the
openCRX core model.

|
If you need
additional attributes, approach the issue as follows:
Map your
requirements to User-definable attributes of CrxObject (see
chapter 4.2.1).
If you run
out of attributes, use PropertyDataBindings.
Only as a last resort should you consider
extending the openCRX UML Model as such an extension requires
expert knowledge and is not suitable for the faint-hearted.
|

|
Extending the openCRX UML Model is for experts
only (and most of the time not really required)!
|
8.7.1.1 A comprehensive example with PropertyDataBindings
The following UI
customizing file demonstrates how to extend the Product class with a
set of attributes, one of each type. Deploy the file
zorder_product.xml
to the directory
{TOMCAT_INSTALL_DIR}/apps/opencrx-core-CRX/opencrx-core-CRX/WEB-INF/config/ui/Root/en_US
and then restart Tomcat.
Listing 7: UI Customizing File zorder_product.xml
<?xml
version="1.0"
encoding="UTF-8"?>
<org.openmdx.base.Authority
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
name="org:openmdx:ui1"
xsi:noNamespaceSchemaLocation="xri://+resource/org/openmdx/ui1/xmi1/ui1.xsd">
<_object/>
<_content>
<provider>
<org.openmdx.base.Provider qualifiedName="CRX"
_operation="null">
<_object/>
<_content>
<segment>
<org.openmdx.ui1.Segment qualifiedName="Root"
_operation="null">
<_object/>
<_content>
<featureDefinition>
<org.openmdx.ui1.StructuralFeatureDefinition
qualifiedName="org:opencrx:kernel:product1:Product:Extension!myBoolean">
<_object>
<type>org:w3c:boolean</type>
<multiplicity>0..1</multiplicity>
<changeable>true</changeable>
</_object>
<_content/>
</org.openmdx.ui1.StructuralFeatureDefinition>
<org.openmdx.ui1.StructuralFeatureDefinition
qualifiedName="org:opencrx:kernel:product1:Product:Extension!myInteger">
<_object>
<type>org:w3c:integer</type>
<multiplicity>0..1</multiplicity>
<changeable>true</changeable>
</_object>
<_content/>
</org.openmdx.ui1.StructuralFeatureDefinition>
<org.openmdx.ui1.StructuralFeatureDefinition
qualifiedName="org:opencrx:kernel:product1:Product:Extension!myDecimal">
<_object>
<type>org:w3c:decimal</type>
<multiplicity>0..1</multiplicity>
<changeable>true</changeable>
</_object>
<_content/>
</org.openmdx.ui1.StructuralFeatureDefinition>
<org.openmdx.ui1.StructuralFeatureDefinition
qualifiedName="org:opencrx:kernel:product1:Product:Extension!myString">
<_object>
<type>org:w3c:string</type>
<multiplicity>0..1</multiplicity>
<changeable>true</changeable>
</_object>
<_content/>
</org.openmdx.ui1.StructuralFeatureDefinition>
<org.openmdx.ui1.StructuralFeatureDefinition
qualifiedName="org:opencrx:kernel:product1:Product:Extension!myDate">
<_object>
<type>org:w3c:date</type>
<multiplicity>0..1</multiplicity>
<changeable>true</changeable>
</_object>
<_content/>
</org.openmdx.ui1.StructuralFeatureDefinition>
<org.openmdx.ui1.StructuralFeatureDefinition
qualifiedName="org:opencrx:kernel:product1:Product:Extension!myDateTime">
<_object>
<type>org:w3c:dateTime</type>
<multiplicity>0..1</multiplicity>
<changeable>true</changeable>
</_object>
<_content/>
</org.openmdx.ui1.StructuralFeatureDefinition>
<org.openmdx.ui1.StructuralFeatureDefinition
qualifiedName="org:opencrx:kernel:product1:Product:Extension!myReference">
<_object>
<type>org:opencrx:kernel:account1:Account</type>
<multiplicity>0..1</multiplicity>
<changeable>true</changeable>
</_object>
<_content/>
</org.openmdx.ui1.StructuralFeatureDefinition>
</featureDefinition>
<elementDefinition>
<org.openmdx.ui1.ElementDefinition
name="org:opencrx:kernel:product1:Product:Pane:Attr:Tab:0:Group:5">
<_object>
<active>true</active>
<toolTip>
<_item/>
</toolTip>
<label>
<_item>Extended Attributes
(PropertyDataBinding)</_item>
</label>
</_object>
<_content/>
</org.openmdx.ui1.ElementDefinition>
<org.openmdx.ui1.ElementDefinition
name="org:opencrx:kernel:product1:Product:Extension!myBoolean">
<_object>
<dataBindingName>org.opencrx.kernel.portal.BooleanPropertyDataBinding</dataBindingName>
<active>true</active>
<toolTip>
<_item>My boolean</_item>
</toolTip>
<label>
<_item>My boolean</_item>
</label>
<order>
<_item>0</_item>
<_item>5</_item>
<_item>10</_item>
</order>
</_object>
<_content/>
</org.openmdx.ui1.ElementDefinition>
<org.openmdx.ui1.ElementDefinition
name="org:opencrx:kernel:product1:Product:Extension!myInteger">
<_object>
<dataBindingName>org.opencrx.kernel.portal.IntegerPropertyDataBinding</dataBindingName>
<active>true</active>
<toolTip>
<_item>My integer</_item>
</toolTip>
<label>
<_item>My integer</_item>
</label>
<order>
<_item>0</_item>
<_item>5</_item>
<_item>20</_item>
</order>
</_object>
<_content/>
</org.openmdx.ui1.ElementDefinition>
<org.openmdx.ui1.ElementDefinition
name="org:opencrx:kernel:product1:Product:Extension!myDecimal">
<_object>
<dataBindingName>org.opencrx.kernel.portal.DecimalPropertyDataBinding</dataBindingName>
<active>true</active>
<decimalPlaces>4</decimalPlaces>
<hasThousandsSeparator>true</hasThousandsSeparator>
<toolTip>
<_item>My
decimal</_item>
</toolTip>
<label>
<_item>My
decimal</_item>
</label>
<order>
<_item>0</_item>
<_item>5</_item>
<_item>30</_item>
</order>
</_object>
<_content/>
</org.openmdx.ui1.ElementDefinition>
<org.openmdx.ui1.ElementDefinition
name="org:opencrx:kernel:product1:Product:Extension!myString">
<_object>
<dataBindingName>org.opencrx.kernel.portal.StringPropertyDataBinding</dataBindingName>
<active>true</active>
<toolTip>
<_item>My string</_item>
</toolTip>
<label>
<_item>My string</_item>
</label>
<order>
<_item>0</_item>
<_item>5</_item>
<_item>40</_item>
</order>
</_object>
<_content/>
</org.openmdx.ui1.ElementDefinition>
<org.openmdx.ui1.ElementDefinition
name="org:opencrx:kernel:product1:Product:Extension!myDate">
<_object>
<dataBindingName>org.opencrx.kernel.portal.DatePropertyDataBinding</dataBindingName>
<active>true</active>
<toolTip>
<_item>My date</_item>
</toolTip>
<label>
<_item>My date</_item>
</label>
<order>
<_item>0</_item>
<_item>5</_item>
<_item>50</_item>
</order>
</_object>
<_content/>
</org.openmdx.ui1.ElementDefinition>
<org.openmdx.ui1.ElementDefinition
name="org:opencrx:kernel:product1:Product:Extension!myDateTime">
<_object>
<dataBindingName>org.opencrx.kernel.portal.DateTimePropertyDataBinding</dataBindingName>
<active>true</active>
<toolTip>
<_item>My dateTime</_item>
</toolTip>
<label>
<_item>My dateTime</_item>
</label>
<order>
<_item>0</_item>
<_item>5</_item>
<_item>60</_item>
</order>
</_object>
<_content/>
</org.openmdx.ui1.ElementDefinition>
<org.openmdx.ui1.ElementDefinition
name="org:opencrx:kernel:product1:Product:Extension!myReference">
<_object>
<dataBindingName>org.opencrx.kernel.portal.ReferencePropertyDataBinding</dataBindingName>
<active>true</active>
<toolTip>
<_item>My reference (to
Account)</_item>
</toolTip>
<label>
<_item>My reference (to
Account)</_item>
</label>
<order>
<_item>0</_item>
<_item>5</_item>
<_item>70</_item>
</order>
</_object>
<_content/>
</org.openmdx.ui1.ElementDefinition>
</elementDefinition>
</_content>
</org.openmdx.ui1.Segment>
</segment>
</_content>
</org.openmdx.base.Provider>
</provider>
</_content>
</org.openmdx.base.Authority>
Once Tomcat is up and running, navigate to the tab [Products]
and create a new product as shown below:

The screen for entering new products should now
include a new field group labeled Extended Attributes
(PropertyDateBinding) containing additional fields as shown
below:

Enter some data as
follows:
Name: Sample
Product
Product number:
P-1234
My boolean:
check it
My integer: 123
My decimal:
987654321.0123
My string:
sample string
My date:
1/23/2009
My dateTime:
1/23/2009 12:34:56 AM
My reference (to Account): point to
guest
Save to new product and then navigate to it.
Expand the grid tabs in the first grid pane by
clicking on the tab [>>].
You will see additional tabs like [Notes],
[Folders], etc. Click on
the tab [Property Sets] to
see the entry Extension as shown below:

The PropertySet Extension was created
automatically when you saved the new product. It is called Extension
because that is what was customized in the file zorder_product.xml.
The PropertySet Extension contains all the attributes defined with
PropertyDataBindings, i.e. myBoolean, myInteger,
myDecimal, myString, myDate, myDateTime,
and myReference. Let's verify this by clicking on the icon of
the respective Property Set.
You should see the following:

While all of these properties could be edited
right within the Property Set, it is definitely more comfortable
(and natural) to edit them within the attribute pane of products.
Note that this extension of the class Product did
not require any modifications of the openCRX UML Model. We did not
even have to modify the database schema. The whole extension is done
with customizing features only!
8.7.1.2 BooleanPropertyDataBinding
Purpose
|
Display boolean value stored in a
BooleanProperty in the attribute pane.
|
Example
|
|
8.7.1.3 StringPropertyDataBinding
Purpose
|
Display string value stored in a
StringProperty in the attribute pane.
|
Example
|
|
8.7.1.4 IntegerPropertyDataBinding
Purpose
|
Display integer value stored in an
IntegerProperty in the attribute pane.
|
Example
|
...
<featureDefinition>
<org.openmdx.ui1.StructuralFeatureDefinition
qualifiedName="org:opencrx:kernel:product1:Product:Custom!lineNumber">
<_object>
<type>org:w3c:integer</type>
<multiplicity>0..1</multiplicity>
<changeable>true</changeable>
</_object>
<_content/>
</org.openmdx.ui1.StructuralFeatureDefinition>
</featureDefinition>
...
<elementDefinition>
<org.openmdx.ui1.ElementDefinition
name="org:opencrx:kernel:product1:Product:Custom!lineNumber">
<_object>
<dataBindingName>org.opencrx.kernel.portal.IntegerPropertyDataBinding</dataBindingName>
<active>true</active>
<filterable>false</filterable>
<sortable>false</sortable>
<toolTip>
<_item>Line Number</_item>
</toolTip>
<label>
<_item>Line Number</_item>
</label>
<orderFieldGroup>
<_item>0</_item>
<_item>0</_item>
<_item>50</_item>
</orderFieldGroup>
<orderObjectContainer>
<_item>0</_item>
<_item>0</_item>
<_item>32</_item>
</orderObjectContainer>
</_object>
<_content/>
</org.openmdx.ui1.ElementDefinition>
</elementDefinition>
...
|
8.7.1.5 DecimalPropertyDataBinding
Purpose
|
Display decimal value stored in a
DecimalProperty in the attribute pane.
|
Example
|
|
8.7.1.6 DatePropertyDataBinding
Purpose
|
Display date value stored in a DateProperty in
the attribute pane.
|
Example
|
|
8.7.1.7 DateTimePropertyDataBinding
Purpose
|
Display date/time value stored in a
DateTimeProperty in the attribute pane.
|
Example
|
|
8.7.1.8 ReferencePropertyDataBinding
Purpose
|
Display value of referenced object stored in a
ReferenceProperty in the attribute pane.
|
Example
|
...
<dataBindingName>org.opencrx.kernel.portal.ReferencePropertyDataBinding</dataBindingName>
...
|
8.7.2 DataBinding
ReferencedObjectDataBinding
Purpose
|
Display attribute of a referenced object in
the inspector of the current object.
|
Example
|
<featureDefinition>
<org.openmdx.ui1.StructuralFeatureDefinition
qualifiedName="org:opencrx:kernel:account1:AccountMembership:(accountFrom;void)*Membership!aliasName">
<_object> <type>org:w3c:string</type>
<multiplicity>0..1</multiplicity>
<changeable>false</changeable> </_object>
<_content/>
</org.openmdx.ui1.StructuralFeatureDefinition>
</featureDefinition>
<elementDefinition>
<org.openmdx.ui1.ElementDefinition
name="org:opencrx:kernel:account1:AccountMembership:(accountFrom;void)*Membership!aliasName">
<_object>
<dataBindingName>org.openmdx.portal.servlet.databinding.ReferencedObjectDataBinding</dataBindingName>
<columnBreak>false</columnBreak>
<active>true</active> <toolTip>
<_item>Alias name [from]</_item>
</toolTip> <label> <_item>Alias
name [from]</_item> </label>
<orderFieldGroup> <_item>0</_item>
<_item>10</_item>
<_item>90</_item> </orderFieldGroup>
<orderObjectContainer>
<_item>0</_item> <_item>0</_item>
<_item>5</_item>
</orderObjectContainer> </_object>
<_content/> </org.openmdx.ui1.ElementDefinition>
</elementDefinition>
|
8.7.3 DataBinding
CompositeObjectDataBinding
Purpose
|
Display attribute of a composite object in the
inspector of the current object.
|
Example
|
<featureDefinition>
<org.openmdx.ui1.StructuralFeatureDefinition
qualifiedName="org:opencrx:kernel:account1:Account:address*Business!postalCity">
<_object> <type>org:w3c:string</type>
<multiplicity>0..1</multiplicity>
<changeable>true</changeable> </_object>
<_content />
</org.openmdx.ui1.StructuralFeatureDefinition>
</featureDefinition>
<elementDefinition>
<org.openmdx.ui1.ElementDefinition
name="org:opencrx:kernel:account1:Account:address*Business!postalCity">
<_object>
<dataBindingName>org.openmdx.portal.servlet.databinding.CompositeObjectDataBinding?type=org:opencrx:kernel:account1:PostalAddress;disabled=(boolean)false;isMain=(boolean)true;usage=(short)500</dataBindingName>
<active>true</active> <toolTip>
<_item>City</_item> </toolTip>
<label> <_item>City</_item>
</label> <order>
<_item>0</_item> <_item>10</_item>
<_item>40</_item> </order>
</_object> <_content />
</org.openmdx.ui1.ElementDefinition> </elementDefinition>
|
It is even possible to work with attributes of
composite objects that are referenced, e.g. the web address (URL) of
a contact's assistant:
<org.openmdx.ui1.StructuralFeatureDefinition
qualifiedName="org:opencrx:kernel:account1:Contact:(assistant;address)!webUrl">
<_object>
<type>org:w3c:string</type>
<multiplicity>0..1</multiplicity>
<changeable>true</changeable>
</_object>
<_content/>
</org.openmdx.ui1.StructuralFeatureDefinition>
8.7.4 DataBinding
ProductConfigurationSet
8.7.5 DataBinding
ProductConfigurationTypeSet
8.7.6 DataBinding
LocalizedFieldDataBinding
Purpose
|
With
this databinding you can display and manage LocalizedField
objects attached as standard fields. The databinding selects the
localized field matching the current user's locale and displays
the localizedValue. The LocalizedFieldDataBinding allows to
localize field values in an easy way. E.g. the field 'Name:' of
an ActivityGroup can be localized with the following ui
configuration:
|
Example
|
<featureDefinition>
<org.openmdx.ui1.StructuralFeatureDefinition
qualifiedName="org:opencrx:kernel:activity1:ActivityGroup:localizedName!name">
<_object> <type>org:w3c:string</type>
<multiplicity>0..1</multiplicity>
<changeable>true</changeable> </_object>
<_content/>
</org.openmdx.ui1.StructuralFeatureDefinition>
</featureDefinition> ... <elementDefinition>
<org.openmdx.ui1.ElementDefinition
name="org:opencrx:kernel:activity1:ActivityGroup:localizedName!name">
<_object>
<dataBindingName>org.opencrx.kernel.portal.LocalizedFieldDataBinding[?usage=n]</dataBindingName>
<active>true</active> <toolTip>
<_item>Name (localized)</_item>
</toolTip> <label> <_item>Name
(localized)</_item> </label>
<order> <_item>0</_item>
<_item>0</_item> <_item>15</_item>
</order> </_object>
<_content/>
</org.openmdx.ui1.ElementDefinition> </elementDefinition>
|
8.7.7 DataBindings
for Addresses
8.7.7.1 EmailAddressDataBinding
Purpose
|
Display e-mail address (of a composite e-mail
address object) in the inspector of the current object.
|
Example
|
<org.openmdx.ui1.ElementDefinition
name="org:opencrx:kernel:account1:Account:address*Other!emailAddress">
<_object>
<dataBindingName>org.opencrx.kernel.portal.EmailAddressDataBinding?isMain=(boolean)true;usage=(short)1800;[emailType=(short)1]</dataBindingName>
<active>true</active> <toolTip>
<_item>E-mail other</_item>
</toolTip> <label> <_item>E-mail
other</_item> </label> <order>
<_item>0</_item> <_item>0</_item>
<_item>140</_item> </order>
</_object> <_content />
</org.openmdx.ui1.ElementDefinition>
|
8.7.7.2 PhoneNumberDataBinding
Purpose
|
Display phone number (of a composite e-mail
address object) in the inspector of the current object.
|
Example
|
<org.openmdx.ui1.ElementDefinition
name="org:opencrx:kernel:account1:Account:address*Other!emailAddress">
<_object>
<dataBindingName>org.opencrx.kernel.portal.PhoneNumberDataBinding?[isMain=(boolean)true];usage=(short)400;automaticParsing=(boolean)true</dataBindingName>
<active>true</active> <toolTip>
<_item>Phone home</_item>
</toolTip> <label> <_item>Phone
home</_item> </label> <order>
<_item>0</_item> <_item>0</_item>
<_item>100</_item> </order>
</_object> <_content />
</org.openmdx.ui1.ElementDefinition>
|
8.7.7.3 WebAddressDataBinding
8.7.8 DataBinding
AssignedActivityGroupsDataBinding
Listing 8: Example AssignedActivityGroupsDataBinding
<featureDefinition>
<org.openmdx.ui1.StructuralFeatureDefinition
qualifiedName="org:opencrx:kernel:activity1:Activity:assignedGroupName">
<_object>
<type>org:opencrx:kernel:activity1:ActivityGroup</type>
<multiplicity>list</multiplicity>
<changeable>false</changeable>
</_object>
<_content/>
</org.openmdx.ui1.StructuralFeatureDefinition>
</featureDefinition>
<org.openmdx.ui1.ElementDefinition
name="org:opencrx:kernel:activity1:Activity:assignedGroupName">
<_object>
<dataBindingName>org.opencrx.kernel.portal.AssignedActivityGroupsDataBinding?type=tracker</dataBindingName>
<active>true</active>
<spanRow>6</spanRow>
<toolTip>
<_item>Assigned Trackers</_item>
</toolTip>
<label>
<_item>Assigned
Trackers</_item>
</label>
<shortLabel>
<_item>Groups</_item>
</shortLabel>
<orderFieldGroup>
<_item>10</_item>
<_item>100</_item>
<_item>10</_item>
</orderFieldGroup>
<orderObjectContainer>
<_item>0</_item>
<_item>0</_item>
<_item>9</_item>
</orderObjectContainer>
</_object>
<_content/>
</org.openmdx.ui1.ElementDefinition>
Optional Parameter type:
Syntax: ?type={
[tracker|milestone|category] "," }
If you omit the optional parameter type
all assigned activity groups are shown. The above example selects
ActivityTrackers only. You can also provide a comma-separated list
of types, e.g. ?type=tracker,milestone.
8.7.9 DataBinding DocumentFolderAssignmentsDataBinding
Optional Parameter name:
Syntax: ?name={ name prefix ","
}
If you omit the optional parameter type
all document folder assignments are shown.
8.7.10 DataBinding
FilteredActivitiesDataBinding
The
org.opencrx.kernel.portal.FilteredActivitiesDataBinding allows to
specify a (possibly user-specific) activity tracker, milestone,
category or activity filter and returns the corresponding collection
of filtered activities. These activities can be shown as grid
wherever you like.
Listing 9: Example FilteredActivityGroupsDataBinding
<featureDefinition>
<org.openmdx.ui1.StructuralFeatureDefinition
qualifiedName="org:opencrx:kernel:home1:UserHome:tracker!${USER}~Private!filteredActivity">
<_object>
<type>org:opencrx:kernel:activity1:Activity</type>
<multiplicity>0..n</multiplicity>
<changeable>false</changeable>
<isReference>true</isReference>
</_object>
<_content/>
</org.openmdx.ui1.StructuralFeatureDefinition>
</featureDefinition>
<org.openmdx.ui1.ElementDefinition
name="org:opencrx:kernel:home1:UserHome:tracker!${USER}~Private!filteredActivity">
<_object>
<dataBindingName>org.opencrx.kernel.portal.FilteredActivitiesDataBinding</dataBindingName>
<active>true</active>
<changeable>false</changeable>
<toolTip>
<_item>Private Activities</_item>
</toolTip>
<label>
<_item>Private
Activities</_item>
</label>
<order>
<_item>0</_item>
<_item>0</_item>
<_item>3</_item>
</order>
<maxMember>5</maxMember>
</_object>
<_content/>
</org.openmdx.ui1.ElementDefinition>
8.7.11 DataBinding
FormattedFollowUpDataBinding
Listing 10: Example FormattedFollowUpDataBinding
<featureDefinition>
<org.openmdx.ui1.StructuralFeatureDefinition
qualifiedName="org:opencrx:kernel:activity1:ActivityFollowUp:formattedFollowUp">
<_object>
<type>org:w3c:string</type>
<multiplicity>0..1</multiplicity>
<changeable>false</changeable>
</_object>
<_content/>
</org.openmdx.ui1.StructuralFeatureDefinition>
</featureDefinition>
<org.openmdx.ui1.ElementDefinition
name="org:opencrx:kernel:activity1:ActivityFollowUp:formattedFollowUp">
<_object>
<active>true</active>
<toolTip>
<_item>Transition Info</_item>
</toolTip>
<label>
<_item>Transition
Info</_item>
</label>
<order>
<_item>90</_item>
<_item>70</_item>
<_item>5</_item>
</order>
<orderObjectContainer>
<_item>0</_item>
<_item>5</_item>
<_item>0</_item>
</orderObjectContainer>
<dataBindingName>org.opencrx.kernel.portal.FormattedFollowUpDataBinding</dataBindingName>
</_object>
<_content/>
</org.openmdx.ui1.ElementDefinition>
8.7.12 DataBinding
FormattedNoteDataBinding
Listing 11: Example FormattedNoteDataBinding
<featureDefinition>
<org.openmdx.ui1.StructuralFeatureDefinition
qualifiedName="org:opencrx:kernel:activity1:ActivityFollowUp:formattedNote">
<_object>
<type>org:w3c:string</type>
<multiplicity>0..1</multiplicity>
<changeable>false</changeable>
</_object>
<_content/>
</org.openmdx.ui1.StructuralFeatureDefinition>
</featureDefinition>
<org.openmdx.ui1.ElementDefinition
name="org:opencrx:kernel:activity1:ActivityFollowUp:formattedNote">
<_object>
<active>true</active>
<toolTip>
<_item>Title / Text</_item>
</toolTip>
<label>
<_item>Title
/ Text</_item>
</label>
<order>
<_item>90</_item>
<_item>70</_item>
<_item>10</_item>
</order>
<orderObjectContainer>
<_item>0</_item>
<_item>10</_item>
<_item>0</_item>
</orderObjectContainer>
<dataBindingName>org.opencrx.kernel.portal.FormattedNoteDataBinding</dataBindingName>
</_object>
<_content/>
</org.openmdx.ui1.ElementDefinition>
8.7.13 DataBinding
JoiningListDataBinding
The JoiningListDataBinding allows to collect
objects from a specified set of reference features and display them
in a unified grid.
Listing 12: Example JoiningListDataBinding
<org.openmdx.ui1.ElementDefinition
name="org:opencrx:kernel:activity1:Activity:summary">
<_object>
<active>true</active>
<toolTip>
<_item>Additional
Information</_item>
</toolTip>
<label>
<_item>Additional Information</_item>
</label>
<order>
<_item>13</_item>
<_item>0</_item>
<_item>10</_item>
</order>
<maxMember>5</maxMember>
<showMaxMember>1</showMaxMember>
<dataBindingName>org.openmdx.portal.servlet.databinding.JoiningListDataBinding?features=[meetingParty,incidentParty,taskParty,sender,mailingRecipient,phoneCallRecipient,assignedGroup,activityLinkTo,activityLinkFrom];orderBy=[createdAt.ASCENDING]</dataBindingName>
</_object>
<_content />
</org.openmdx.ui1.ElementDefinition>
9 Code
Table XML Files
9.1 Overview
9.2 Code
Table Overloading
9.2.1 Adding Codes to Existing Code Tables
This is best done by using codes >= 10'0000 as
openCRX/core typically uses codes < 10'000:
Listing 13: Example Adding a new code to an existing code table
<org.opencrx.kernel.code1.CodeValueEntry
code="10000" _operation="set">
<_object>
<shortText>
<_item>LHG</_item>
</shortText>
<longText>
<_item>Land of Hope and
Glory</_item>
</longText>
</_object>
<_content/>
</org.opencrx.kernel.code1.CodeValueEntry>
9.2.2 Disabling Existing Codes
This is best done by defining a very short
validity period far in the past:
Listing 14: Example Disabling of a code value
<org.opencrx.kernel.code1.CodeValueEntry
code="249" _operation="set">
<_object>
<validFrom>1970-01-01T00:00:00.000Z</validFrom>
<validTo>1970-01-01T00:00:00.001Z</validTo>
<shortText>
<_item>FX</_item>
</shortText>
<longText>
<_item>France,
Metropolitan</_item>
</longText>
</_object>
<_content/>
</org.opencrx.kernel.code1.CodeValueEntry>
9.2.3 Replacing Existing Code Tables
If you assign a code table of your custom project
the name of a code table that already exists in the core project,
the code table of the custom project will be included during the
build process (and the core code table will be ignored).
9.3 Segment-Specific
Code Tables
10 Groovy
Controls
10.1 MenuOps
– openCRX Operations Menu
10.2 Navigation
– openCRX Breadcrum
10.3 North
– openCRX Header
10.4 RootMenu
– openCRX Top Level Tabbed Menu
10.5 RootPanel
– openCRX Top Level PopUp Menu
10.6 Search
– openCRX Index-based Search
11 JSP
Wizards
See the various examples in the directory
...\opencrx-core-CRX\wizards\en_US
12 Forms
Forms were introduced with openCRX v2.4. Have a
look at the following examples included in the distribution:
Form
|
Wizards making use of the Form
|
CreateActivityForm.xml
|
CreateActivityWizard.jsp
|
CreateActivityTrackerForm.xml
|
CreateAgendaWizard.jsp CreateBugTrackerWizard.jsp CreateCampaignWizard.jsp CreateProjectWizard.jsp
|
CreateContactForm.xml
|
CreateContactWizard.jsp
|
CreateCrontactForm.xml
|
CreateContractWizard.jsp
|
CreateLeadForm.xml
|
CreateLeadWizard.jsp
|
CreateProductForm.xml
|
CreateProductWizard.jsp
|
ScheduleEventForm.xml
|
ScheduleEventWizards.jsp
|
13 Layout
JSPs
openCRX is distributed with 2 default layout JSPs
located in the directory
...\opencrx-core-CRX\WEB-INF\config\layout\en_US.
13.1 show-Default.jsp
This layout JSP renders all pages that show
information (typically an Inspector containing information about the
current object and all the grids containing associated information).
This layout JSP is generic and can handle any object. It is provided
by openMDX/portal.
13.2 edit-Default.jsp
Similarly, this layout JSP renders all pages that
are used to edit objects and create new objects. This layout JSP is
generic and can handle any object. It is provided by openMDX/portal.
13.3 Custom
Layout JSPs
If you have a need for specialized screens for a
particular object in edit and/or show mode, you can write your own
layout JSP and deploy it to the above-mentioned directory. The file
name of your custom layout JSP determines which objects (or rather:
objects of which class) will be handled by your custom layout JSP.
Example:
Let's assume you
want to replace the default edit screen for openCRX Contacts (i.e.
class org.opencrx.kernel.account1.Contact) with a custom
layout JSP. Name your file
edit-org.opencrx.kernel.account1.Contact.jsp
and deploy it to the directory
...\WEB-INF\config\layout\en_US.
After restarting Tomcat or your application server your new layout
JSP will be active.

|
If you develop localized JSPs you can create
new directories for the respective locales and then deploy your
localized JSPs there. The fallback algorithms are comparable to
those in ui customization.
|

|
You must provide a layout JSP for the base
locale, by default the locale en_US.
|
14 Advanced
Customizing Options
14.1 Workflows
14.2 Java
Controls
14.3 Portal
Extensions
14.4 UML
Model Extensions
14.5 Application
Logic Extensions
15 Other
Customizing Options
A collection of useful configuration and
customizing options.
15.1 web.xml
All of the following settings can be made in the
file
...\opencrx-core-CRX\WEB-INF\web.xml
15.1.1 uiRefreshRate
By default, the UI configuration is loaded at
startup only. If you are changing customizing files during a
customization session you might want to reload the UI periodically
to verify your changes without restarting the servlet container. You
can do so by setting the respective value to something else than 0.
The refresh period is measured in milliseconds, i.e. the following
example would cause the UI configuration to reload once per minute:
Listing 15: uiRefreshRate in web.xml
...
<!-- ui refresh rate
-->
<init-param>
<param-name>uiRefreshRate</param-name>
<param-value>60000</param-value>
</init-param>
...
15.1.2 load-on-startup
By default, the ObjectInspectorServlet is
initialized with the first login (and hence the first login can take
some time). If you prefer to initialize the ObjectInspectorServlet
right after the deployment of the respective EAR, uncomment the
following section in web.xml:
Listing 16: load-on-startup in web.xml
...
<!-- activate if
ObjectInspectorServlet should be initialized at startup
-->
<load-on-startup>1</load-on-startup>
...
15.1.3 session-timeout
By default, the session timeout is set to 30
minutes. If you want to shorten or lengthen the session timeout you
can do so by changing the value of session-timeout (measured in
minutes) in web.xml. The following example shows how to change the
timeout to 2 hours:
Listing 17: session-timeout in web.xml
...
<session-config>
<session-timeout>120</session-timeout>
</session-config>
...
15.1.4 transport-guarantee
If you want to force your users to connect with
SSL you can require a transport guarantee and replace the default
value NONE with CONFIDENTIAL. The following example shows how to
require the application admin (admin-Root) to connect with SSL:
Listing 18: transport-guarantee in web.xml
...
<security-constraint
id="security_constraint-Root">
<web-resource-collection id="c-Root">
<web-resource-name>c-Root</web-resource-name>
<url-pattern>/LogConsoleServlet/*</url-pattern>
<url-pattern>/WorkflowController/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint
id="auth_constraint-Root">
<role-name>OpenCrxRoot</role-name>
</auth-constraint>
<user-data-constraint
id="user_data_constraint-Root">
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
...
16 Next
Steps
You might want to have a look at some of the
additional documentation published at
http://www.opencrx.org/documents.htm.
The openCRX Admin Guide might be of particular interest to you.