This topic describes how to organize logic by using the
Model, View, and Controller (MVC) method and how Rich UI uses the
concept of MVC to support validation and formatting.
MVC
Modern data-processing systems separate
the view from the model:
- The view is either the user interface, the logic
that supports the user interface, or the business data in the user
interface
- The model is either a database (or other data storage),
the logic that accesses a database, or the data that is sent to or
retrieved from a database
The controller is the logic that oversees
the transfer of data between the user interface and the database-access
logic.
In many cases, the acronym MVC refers to processing across
multiple platforms. For example, a Rich UI application on a Windows® platform might be considered
to be the view (and to include the controller), while a service that
accesses a database might be considered to be the model.
You
can also consider a division of view from model in the Rich UI application
itself. In this case, the terms have the following meaning:
- The view is a widget in the user interface. Data
that is placed into that widget must be validated before it can be
used in other processing. Application data that is intended for display
by the widget must be formatted before display.
- The model is a data field that is internal to the
application.
You can use a new EGL definition, the Controller, to
tie a specific view—a specific widget—to a specific model. The Controller
also oversees validations and format rules, which are described in
this topic.
You can also define a validation form that identifies
a set of display fields and the related Controllers. If you define
a validation form or a form that you code for yourself, you can display
the error messages that result from validations and formatting. The
form developer uses the getErrorMessage controller-specific
function to access the message.
The next sections describe the
Controller and how to work with it. For details about creating validation
forms, see "Form processing with Rich UI," which uses the mechanisms
described here.
The Controller in Rich UI
Consider the following
declarations:
nameField TextField;
name String {inputRequired=yes,
validationPropertiesLibrary=myLibrary,
inputRequiredMsgKey="requiredMessage"};
The
declaration of
name has the following properties:
- inputRequired ensures that the user
will provide input to any widget (a view) that is associated with
that the data field (a model)
- validationPropertiesLibrary identifies
the library (RUIPropertiesLibrary stereotype) that
includes declarations for use in messages and other text. If you do
not include this property, the EGL Runtime accesses default messages.
For details about customizing validation messages in Rich UI, see
"Use of properties files for displayable text."
- inputRequiredMsgKey identifies a customized
validation message
Here is an example declaration of a Rich UI controller:
nameController Controller
{ @MVC
{ model=name, view=nameField }
validators = [myValidationFunction01, myValidationFunction02]
};
The declaration ties a specific model—the
name field—to
a specific view—the
nameField widget. You control
the transfer of data between the model and the view:
- To transfer data from the view to the model, you validate the
data and then commit the validated data. In most cases, the commit
step removes formatting characters, such as currency symbols.
- To transfer data from the model to the view, you publish the data.
In most cases, the publish step formats the data for display.
In the example, the controller declaration also lists
a set of
validators, which are functions that you write
and that validate input. Each validator is based on the following
Delegate part:
Delegate
MVCValidatorFunction(input String in) returns(String?)
end
Input to a validator is valid if the function
returns an empty string or null, but not if the validator returns
a string with content. Such a string is considered an error message.
In
most cases, you commit data only after you validate it. Here is the
syntax for committing the user input from the
nameField widget
into the
name field:
if (nameController.isValid())
nameController.commit();
end
Validating the user input
A specific controller
function—
isValid—is invoked either because
of user action (when the user moves focus away from the widget) or
because of developer request (when the code invokes that function).
That function controls the controller-specific validation steps:
- Runs the function that is referenced by the retrieveViewHelper property
(not shown in the example), which identifies the function that retrieves
the widget content. The function has no parameters and returns a string.
You might use this function to convert the input. In most cases, you
do not need to set the retrieveViewHelper property.
If you do not use that property, the widget content is available as
a string for subsequent processing.
- Runs the functions that is referenced by the unformatters property
(not shown in the example), which identifies an array of functions.
You might use these functions to remove formatting characters from
the input. The first function that is listed accepts the string that
is returned from the retrieveViewHelper function.
Each of the later-listed functions accepts the string that is returned
from the previous function. You might not need to set the unformatters property.
- Removes the formatting characters from the user input in accordance
with the formatting properties, if any, that you specified in the
source code. An example of a formatting character is the currency
symbol, which is associated with the currency property.
A second example is the separators that are specified by the dateFormat property.
- Returns control to the user if a validation error occurs related
to data type; for example, the user might have typed a character when
the model is a numeric field.
- Runs the elementary validations, as specified by EGL properties
that are set on the model, not on the view.
The available properties,
which include inputRequired, are listed
in this topic. The inputRequired property
ensures that the user will provide input to any widget that is associated
with that the data field.
The elementary validations might
cause these outcomes:
- Runs the validators in the order specified in the controller validators array.
Each validator accepts the input string without formatting characters
such as the currency symbol; each validator returns a string. If the
validator returns a null or blank, the EGL Runtime considers the validation
to have succeeded. However, the following statements apply if the
validator returns a different value—for example, a value retrieved
from a properties file, as described in "Use of properties files for
displayable text":
- The EGL Runtime considers the validation to have failed
- Control immediately returns to the user; in that case, the subsequent
validators do not run
- The returned string is available for use in a form
Changing the display of the invalid input
By
default, a widget with invalid content is displayed with a style that
is specified in a Cascading Stylesheet (CSS) class; specifically,
the initial class, such as EglRuiTextField, along with the following,
secondary class: FormErrorEditor. For the best effect, a Web designer
in your company might set up the style sheet.
You can assign
a different set of CSS classes (or a different CSS ID) in response
to validation failure or you can change another aspect of the displayed
output. For example, you can assign CSS classes to a label, as occurs
(by default) if you use a validating form. For details, see "Form
processing with Rich UI."
To change the displayed output after
validation:
- Set the validStateSetter controller
property, which identifies a function for the EGL runtime to invoke
at the end of validation.
- Create the function, which has two parameters. The first is of
a Widget type and the second is a Boolean type. The first parameter
receives the widget that is being validated and the second indicates
whether the validation succeeded.
- In that function, assign a different or additional class (or a
different CSS ID) to the widget that has invalid content or, more
likely, to the label of that widget.
Committing the validated input
When you
run the controller-specific
commit function,
data is transferred from the view to the model. During that process,
several functions are invoked, as is determined by a set of controller
properties. Those properties are as follows:
- The retrieveViewHelper property identifies
the function that retrieves the widget content. The function has no
parameters and returns a string. You might use this function to convert
the input. In most cases, you do not need to set the retrieveViewHelper property.
Without that property, the widget content is available as a string
for subsequent processing.
- The unformatters property identifies
an array of functions. You might use these functions to remove formatting
characters from the input. The function that is listed first accepts
the string that is returned from the retrieveViewHelper function.
Each of the later-listed functions accepts the string that is returned
from the previous function. You might not need to set the unformatters property.
- Formatting characters are removed from the user input in accordance
with the formatting properties, if any, that you specified in the
source code. An example of a formatting character is the currency
symbol, which is associated with the currency property.
A second example is the separators that are specified by the dateFormat property.
- The commitHelper property identifies
the function that assigns a value to the model. The function has a
single parameter of the STRING type and has no return value. You might
not need to set this property. Without this property, the model receives
the string that was provided by an earlier function, if any, and that
no longer includes formatting characters.
Publishing the model data
When you run the
controller-specific
publish function, data
is transferred from the model to the view. During that process, several
functions are invoked, as is determined by a set of controller properties.
Those properties are as follows:
- The retrieveModelHelper property identifies
the function that retrieves the data content. The function has no
parameters and returns a string. You might use this function to convert
the output. In most cases, you do not need to set the retrieveModelHelper property.
Without that property, the model content is available as a string
for subsequent processing.
- Formatting characters are added to the user input in accordance
with the formatting properties, if any, that you specified in the
source code. An example of a formatting character is the currency
symbol, which is associated with the currency property.
A second example is the separators that are specified by the dateFormat property.
- The formatters property identifies an
array of functions. You might use these functions to format the output.
The function that is listed first accepts the string that is returned
from the retrieveModelHelper function, with
any formatting characters added in step 2. Each of the later-listed
functions accepts the string that is returned from the previous function.
You might not need to set the formatters property.
- The publishHelper property identifies
the function that assigns a value to the model. The function has a
single parameter of the STRING type and has no return value. You might
not need to set this property. Without this property, the view receives
the string that was provided by an earlier function, if any, and that
includes formatting characters.
Validation and formatting properties
Each
of the field-level properties used in Rich UI is described in "Form
field properties." This section lists the properties, each of which
is categorized with a single letter:
- F is for formatting. A property in this category removes formatting
characters during the commit process and adds formatting characters
during the publish process. Any of these properties can result in
the display of an error message; for example, if an input date is
significantly different from the required date format, or if an integer
value is a number other than 0 or 1 but is associated with is Boolean.
- V is for input validation.
Here are all of the properties:
- currency (F)
- currencySymbol (F)
- dateFormat (F)
- fillCharacter (F)
- inputRequired (V)
- inputRequiredMsgKey (V)
- isBoolean (F)
- isDecimalDigit (V)
- isHexDigit (V)
- lowercase (F)
- minimumInput (V)
- minimumInputMsgKey (V)
- numericSeparator (F)
- sign (F)
- timeFormat (F)
- timestampFormat (F)
- typeChkMsgKey (V)
- uppercase (F)
- validValues (V)
- validValuesMsgKey (V)
- zeroFormat (F)
The following properties are further described in "Use
of properties files for displayable text":
- inputRequiredMsgKey (V)
- minimumInputMsgKey (V)
- typeChkMsgKey (V)
- validValuesMsgKey (V)
You can specify the validation and formatting properties
on DataItem definitions, variables, and Record fields; they are in
effect for a given Rich UI Controller only if you specify the @MVC property
when you declare the Controller.