1. Introduction
This document describes the form builder module. This module is used by software developers in specialized projects that need to generate edoras forms dynamically in Java. It provides Java builder APIs for individual form widgets and the form itself. These builders are used to generate an object representation of the form, which can then be converted directly to the corresponding JSON description. This JSON is then used by the edoras forms engine running in the browser.
1.1. Prerequisites
This document assumes a familiarity with edoras form concepts such as the form layout mechanism and the functionality supported by the available form widgets. This information can be found in the {modelerGuide}.
2. Obtaining the form builder
To include the form builder into your project you just need to add a dependency on the form builder
JAR file, for example as a dependency in your Maven pom.xml
:
<dependency>
<groupId>com.edorasware.one</groupId>
<artifactId>edoras-forms-builder</artifactId>
<version>1.5.0.S83</version>
</dependency>
3. Using the form builder
3.1. Overview
The following tutorial introduces the fundamental form builder concepts, and describes how a form description can be assembled and used to generate the corresponding JSON. Detailed documentation for the form builder API is provided in the form builder javadoc which can be obtained from edorasware support. Details of the functionality supported by specific form widget types and usage examples can be found in the edoras one Modeler Guide.
3.2. Widget builders
Before we can create a form we need to be able to create individual form widgets.
The form builder classes are located in the package com.edorasware.forms.builder
, and
builders for individual form widgets are located in the com.edorasware.forms.builder.component
sub-package.
3.3. Creating a simple form widget
All widgets in the form builder are created using a widget-specific builder API. Each builder supports only the settings that are actually supported by the widget, so it should be impossible to create an invalid widget definition.
A new widget builder is created by calling the type-specific static builder()
method. This method
may require a number of parameters corresponding to the mandatory widget attributes and returns a
builder object, providing additional methods to set the optional attributes. When the required settings have been
made the build()
method can be called to create the widget instance.
As an example, a text widget can be created as follows:
// Create the component builder
Text.Builder builder = Text.builder("id123", "{{textValue}}");
// Adjust the optional settings
builder.isRequired(true);
builder.size(3);
// Instantiate the component from the builder
Text component = builder.build();
The additional configuration methods also return the builder instance, resulting in a fluent builder API. The configuration method calls can therefore be chained together and combined into a single statement:
Text component =
Text.builder("id123", "{{textValue}}")
.isRequired(true)
.size(3)
.build();
This pattern is followed by all widget builders, with the appropriate variations in the supported configuration parameters.
3.4. Creating an empty form
The first step when creating a form is to create the form builder itself.
A form builders is instantiated using the static factory method EdorasForm.builder()
.
When the builder has been created, the required form widgets can be added as required and the
assembled form is then created by calling the build()
method on the form builder.
The following example shows how to create an empty form:
EdorasForm.Builder builder = EdorasForm.builder();
EdorasForm form = builder.build();
3.5. Adding form widgets
As described in the edoras one Modeler Guide, edoras one form widgets are laid out in rows where each row is made up of 12 slots and a widget can span multiple slots within the row. Vertical spans across rows are not supported.
The form builder creates rows as required, with the first widget being added to the first free slot in the current row (building from left to right). The following example shows the construction of a form with a single row containing three widgets:
EdorasForm.Builder builder = EdorasForm.builder();
builder.add(Text.builder(
"t1", "{{value1}}").label("Test 1", Alignment.TOP).size(2).build());
builder.add(Text.builder(
"t2", "{{value2}}").label("Test 2", Alignment.TOP).size(3).build());
builder.add(Text.builder(
"t3", "{{value3}}").label("Test 3", Alignment.TOP).size(4).build());
EdorasForm form = builder.build();
If there are not enough free slots to add the new widget in the current row then a new row will be created automatically. In the following example the final widget is too big to fit in the remaining 3 slots, so a new row is created:
EdorasForm.Builder builder = EdorasForm.builder();
builder.add(Text.builder(
"t1", "{{value1}}").label("Test 1", Alignment.TOP).size(3).build());
builder.add(Text.builder(
"t2", "{{value2}}").label("Test 2", Alignment.TOP).size(6).build());
builder.add(Text.builder(
"t3", "{{value3}}").label("Test 3", Alignment.TOP).size(9).build());
EdorasForm form = builder.build();
It is also possible to explicitly force the creation of a new row, which will then receive any further widgets that are added:
EdorasForm.Builder builder = EdorasForm.builder();
builder.add(Text.builder(
"t1", "{{value1}}").label("Test 1", Alignment.TOP).size(3).build());
builder.nextRow();
builder.add(Text.builder(
"t2", "{{value2}}").label("Test 2", Alignment.TOP).size(6).build());
builder.add(Text.builder(
"t3", "{{value3}}").label("Test 3", Alignment.TOP).size(9).build());
EdorasForm form = builder.build();
To alter the horizontal placement of a widget within a row, a spacer widget of the appropriate size can simply be inserted beforehand (either at the start of a row or within it):
EdorasForm.Builder builder = EdorasForm.builder();
builder.add(Spacer.builder(3).build());
builder.add(Text.builder(
"t1", "{{value1}}").label("Test 1", Alignment.TOP).size(3).build());
builder.nextRow();
builder.add(Text.builder(
"t2", "{{value2}}").label("Test 2", Alignment.TOP).size(3).build());
builder.add(Spacer.builder(3).build());
builder.add(Text.builder(
"t3", "{{value3}}").label("Test 3", Alignment.TOP).size(3).build());
EdorasForm form = builder.build();
String json = FormBuilderUtil.toJson(form);
with(json).assertThat("$.rows", hasSize(2))
.assertThat("$.rows[0].cols", hasSize(2))
.assertThat("$.rows[1].cols", hasSize(3))
.assertEquals("$.rows[0].cols[1].label", "Test 1")
.assertEquals("$.rows[1].cols[0].label", "Test 2")
.assertEquals("$.rows[1].cols[2].label", "Test 3");
}
@Test
public void addCollection() throws JsonProcessingException {
List<EdorasFormComponent> components = newLinkedList();
components.add(Text.builder("t1", "{{value1}}").size(2).build());
components.add(Text.builder("t2", "{{value2}}").size(3).build());
components.add(Text.builder("t3", "{{value3}}").size(4).build());
EdorasForm.Builder builder = EdorasForm.builder();
builder.addAll(components);
EdorasForm form = builder.build();
String json = FormBuilderUtil.toJson(form);
with(json).assertThat("$.rows", hasSize(1)).assertThat("$.rows[0].cols", hasSize(3));
}
@Test
public void addVarargs() throws JsonProcessingException {
Text t1 = Text.builder("t1", "{{value1}}").size(2).build();
Text t2 = Text.builder("t2", "{{value2}}").size(3).build();
Text t3 = Text.builder("t3", "{{value3}}").size(4).build();
EdorasForm.Builder builder = EdorasForm.builder();
builder.addAll(t1, t2, t3);
EdorasForm form = builder.build();
String json = FormBuilderUtil.toJson(form);
with(json).assertThat("$.rows", hasSize(1)).assertThat("$.rows[0].cols", hasSize(3));
}
}
As well as adding individual widgets to the form, it is also possible to add multiple widgets with a single call, either as a collection:
List<EdorasFormComponent> components = newLinkedList();
components.add(Text.builder("t1", "{{value1}}").size(2).build());
components.add(Text.builder("t2", "{{value2}}").size(3).build());
components.add(Text.builder("t3", "{{value3}}").size(4).build());
EdorasForm.Builder builder = EdorasForm.builder();
builder.addAll(components);
EdorasForm form = builder.build();
or using a varargs list:
Text t1 = Text.builder("t1", "{{value1}}").size(2).build();
Text t2 = Text.builder("t2", "{{value2}}").size(3).build();
Text t3 = Text.builder("t3", "{{value3}}").size(4).build();
EdorasForm.Builder builder = EdorasForm.builder();
builder.addAll(t1, t2, t3);
EdorasForm form = builder.build();
3.6. Creating the form JSON
When an EdorasForm
definition has been created using the form builder, it can be converted
into the corresponding JSON representation using the static FormBuilderUtil.toJson()
method:
String json = FormBuilderUtil.toJson(form);