It’s all about the form…
Based on the feedback we receive from our customers and our own experiences at customer sites, we learned that almost every application contains multiple forms. In business applications, forms are the basic building blocks that make up the essence of the application. Until now, UltraLightClient provided no special support for this central element. With UltraLightClient ‘08 this will change!
UltraLightClient ‘08 will provide an out-of-the-box form component that makes it ultra easy to implement your forms:
What before was obfuscated by a lot of boilerplate code will now be reduced to some lines of clean code. What before offered lots of degrees of freedom (and lots of ways of getting lost as well) is now guided by best practices. As a result, form code is easier to write, easier to find, easier to read, easier to understand, and easier to maintain. Writing a form will become a very cost-effective task with UltraLightClient ‘08!
Implementing a form basically means defining the following aspects of the form:
- layout of the input components
- value binding to a business object
- input validation
- status feedback: missing or invalid input, dirty state (i.e. not yet stored input)
- calculation of dependent values (e.g. find corresponding city to entered ZIP)
Let’s consider an example that shows how to express these aspects with help of the form component and how the form component simplifies your life (the programming one, not the real one ;-)). In this example I’ll show you how to implement the following form using the new features in UltraLightClient ‘08.

The first step is to define the layout of the form. In the old days, this would mean creating tabs for the separate parts of the form, adding labels to the tabs, adding input fields to the tabs, connecting the labels to the input fields, adding layout constraints for each added component (e.g. that the last name input field is on the same line as the first name input field), … With UltraLightClient ‘08 this is just one line of code for each tab and each input field! The resulting code is easy to write, easy to understand, and easy to maintain:
@Override
protected void initForm() {
startTab("General");
addTextField("firstName", "Firstname, Lastname:");
addTextField("lastName", new LayoutInfo(append())); // append = add on same line
addTextField("company", "Company:");
startTab("Address");
addTextField("street", "Street:");
addTextField("zip", "ZIP, City:");
addTextField("city", new LayoutInfo(append())); // append = add on same line
addTextField("country", "Country:");
}
And as an added bonus, you get the value binding for free! There’s no need to copy the property values from the business object (a person in this example) into the form when creating the form, and no need to write back the input component values into business object when storing the form. UltraLightClient ‘08 takes care of this for you for free.
How about input validation? In UltraLightClient ‘08 this is ultra easy as well:
@Override
public String validateValue(String value) {
char firstChar = value.charAt(0);
if (Character.isDigit(firstChar)) {
return "Field must not start with digit";
}
return null;
}
The previous code snippet adds error feedback to the form whenever the user input starts with a digit. UltraLightClient ‘08 takes care of invoking your validation code when necessary and displays the validation feedback to the user. So no need for you to add listeners to the input components and to update the form to display the validation feedback. See the red exclamation mark and the tooltip in the screenshot above, displaying the validation feedback.
We talked about layout, value binding, input validation, and status feedback. In the last section of this post, we will tackle the calculation of dependent values. With UltraLightClient ‘08 this is ultra easy as well:
@Override
protected void calculate() {
Person person = getBean();
if (hasChanged("zip")) {
String city = toCity(person.getZip());
setProperty("city", city);
}
}
As with input validation UltraLightClient ‘08 takes care of invoking your code when necessary. So there is no need for you to add listeners to the input components and to update the form here as well.
Summary: With the new form component in UltraLightClient ‘08 implementing forms is an ultra easy task. No need to write stupid boilerplate code again and again. You can concentrate on the essential parts. Plus UltraLightClient ‘08 enforces best practices, which results in more uniform code. Form code will become ultra easy to write, ultra easy to read, and ultra easy to maintain in the upcoming release.
We plan to publish an UltraLightClient ‘08 milestone release in early April. Stay tuned!


Thomas Ernst said,
February 27, 2008 @ 12:29 am
Hi Daniel,
nice post! I agree that forms make up a very important part of real-life business applications. I am glad to see that there will be support in the next ULC release. Which brings me to my first question: is UltraLightClient ‘08 a code name / working title for the next ULC release or will the whole release naming change (which I do not expect)? If the naming doesn\’t change, which release is UltraLightClient ‘08 related to? 6.2.2, 6.3, 7.0? Just curious…
Question 2: I can see that the new features help in designing label/field combinations of the type … (as illustrated in the post). However, this is not the design I see most often but merely something like several rows of …, arranged in a grid. How does the new forms support simplify the design of such layouts?
Question 3: The real text fields seem to be hidden, so how can I control the tabbing order of these fields?
Question 4: Will it be possible to have other error indicators apart from the exclamation mark, for instance, icons?
Regards, Thomas
sandra wendland said,
February 27, 2008 @ 10:46 am
Hi Thomas,
thank you for your comments. I’ll answer your first question cos it’s kind of my idea
We’ll be using the UltraLightClient 08 image to mark blog posts and new web pages related to the next major release of the Canoo RIA library. Regarding the final version naming, we’ll decide on this closer to the date (as was the case in the past).
I’ll communicate how the new naming corresponds to the current versioning closer to the release date.
I guess Daniel will answer your remaining questions.
Sandra
Stuart Booth said,
February 27, 2008 @ 1:34 pm
Regarding the addTextField method: will it be possible to use subclasses, and can extra params be passed to the constructor?
Tamas KIS said,
February 27, 2008 @ 5:34 pm
Hello,
first of all i think the mouseover error message is great. In addition I think it would be nice to show the validation message as pop up bubbles as well…
Q1: ULC already has got a concept for validation (see IDataType interface; e.g. ULCDateDataType), will it be extended, or neglected?
Best regards,
Tamas
Daniel said,
February 27, 2008 @ 5:45 pm
Hi Thomas,
First thanx for your feedback!
Question 2: For grids we will provide improved support as well. However this is not part of the form component. There will be another high-level component that takes care of grids. More on this in a next blog post!
Question 3: The addTextField() method returns the added text field, i.e. it is possible to change the tab order with already existing UltraLightClient API.
Question 4: Currently the exclamation mark is hard coded. But we are thinking of giving customization options to the application developer, not only for the error feedback but for other aspects as well (e.g. layout, component types). This is still work in progress so I can’t say much how this will look like.
Regards Dany
Daniel said,
February 27, 2008 @ 5:47 pm
Hi Stuart,
As said to Thomas we are thinking of giving customization options to the application developer. One aspect is the concrete classes to create for the various addXXX methods. This is work in progress so I can’t say much how this will look like.
Regards Dany
Daniel said,
February 27, 2008 @ 5:50 pm
Hi Tamas,
The form component internally uses data types to filter and validate input on the client side. The validateValue() method is meant for server-side validation only.
Regards Dany