The Forms application contains many highly configurable field types out-of-the-box. Most use cases will be met with one of the existing field types.
If you’re reading this, however, your use case probably wasn’t met with the
default field types. For example, perhaps you need a color picker field. You
could create a select field that lists the color options, but some users don’t
know that gamboge is the color of spicy mustard (maybe a little darker), and
anyway, seeing colors is much more interesting than listing them. Another
example is a dedicated time field. You can use a text field and add a tip to
tell users something like enter the time in the format hour:minute
, but some
users will still enter something indecipherable, like 8:88. Instead, add a
time field to Liferay DXP’s Forms application. You can think of other uses where
it’s best to break free of the mold of existing field types and create your own
that serve your needs best. Keep reading to find out how.
In these tutorials, learn to
- create a module that adds a Time form field type with a timepicker
- add custom configuration options to your field types
Before getting started, learn what Liferay DXP’s field types consist of.
Anatomy of a Field Type Module
The dynamic-data-mapping-type-*
modules in Liferay DXP’s source code (inside
the Forms and Workflow application suite) are good templates to follow when
developing your own field types. For example, look at the directory structure
of the dynamic-data-mapping-type-paragraph
module (version 2.0.7) in the
Forms and Workflow application suite:
bnd.bnd
build.gradle
src
└── main
├── java
│ └── com
│ └── liferay
│ └── dynamic
│ └── data
│ └── mapping
│ └── type
│ └── paragraph
│ └── internal
│ ├── ParagraphDDMFormFieldRenderer.java
│ ├── ParagraphDDMFormFieldType.java
│ └── ParagraphDDMFormFieldTypeSettings.java
└── resources
├── content
│ ├── Language.properties
│ └── Language_xx_XX.properties
│ └── ...
└── META-INF
└── resources
├── config.js
├── paragraph_field.js
├── paragraph.soy
└── paragraph.soy.js
Custom field type modules are nearly identical in structure to those included in
Liferay DXP, as presented above. You won’t need a *TypeSettings
class in your
initial module (see the tutorial on adding settings to your form field types to
learn more about *TypeSettings
), and the *.soy.js
is generated from the
*.soy
file at compile time. These are the Java classes and resources you’ll
need to create:
*DDMFormFieldRenderer.java
: Controls the rendering of the template. Sets the language, declares the namespace, and loads the template resources on activation of the Component. Extending the abstract class that implements theDDMFormFieldRenderer
makes your work here easier.*DDMFormFieldType.java
: Define the form field type in the backend. If you extend the abstract class that implements the interface, you automatically include the default form configuration options for your form field type. In that case, override the interface’sgetName
method and you’re done. To see the default configuration options your form field type will inherit, look at theDefaultDDMFormFieldTypeSettings
class in thedynamic-data-mapping-form-field-type
module.config.js
: Autogenerated if you use Blade CLI,config.js
defines the dependencies of all declared JavaScript components.[name-of-field-type]_field.js
: The JavaScript file that models your field.[name-of-field-type].soy
: The template that defines the appearance of the field.Language_xx.properties
: Define any terms that need to be translated into different languages.
In addition to the Java classes, Soy templates, and JavaScript files, Liferay DXP
applications contain a bnd.bnd
file to manage the module’s metadata, and a
build.gradle
file to manage its dependencies and build properties. This
example follows those patterns.