JBoss.orgCommunity Documentation

Chapter 9. Errai UI

9.1. Get started
9.1.1. App.gwt.xml
9.2. Use Errai UI Composite components
9.2.1. Inject a single instance
9.2.2. Inject multiple instances (for iteration)
9.3. Create a @Templated Composite component
9.3.1. Basic component
9.3.2. Custom template names
9.4. Create an HTML template
9.4.1. Select a template from a larger HTML file
9.5. Use other Widgets in a composite component
9.5.1. Annotate Widgets in the template with @DataField
9.5.2. Add corresponding data-field attributes
9.6. How HTML templates are merged with Components
9.6.1. Example
9.6.2. Element attributes (template wins)
9.6.3. DOM Elements (component field wins)
9.6.4. Inner text and inner HTML (preserved when component implements HasText or HasHTML)
9.7. Event handlers
9.7.1. Concepts
9.7.2. GWT events on Widgets
9.7.3. GWT events on DOM Elements
9.7.4. Native DOM events on Elements
9.8. Data Binding
9.9. Nest Composite components
9.10. Extend Composite components
9.10.1. Template
9.10.2. Parent component
9.10.3. Child component

One of the primary complaints of GWT to date has been that it is difficult to use "pure HTML" when building and skinning widgets. Inevitably one must turn to Java-based configuration in order to finish the job. Errai, however, strives to remove the need for Java styling. HTML template files are placed in the project source tree, and referenced from custom "Composite components" (Errai UI Widgets) in Java. Since Errai UI depends on Errai IOC and Errai CDI, dependency injection is supported in all custom components. Errai UI provides rapid prototyping and HTML5 templating for GWT.

The Errai UI module is directly integrated with Chapter 8, Data Binding and Errai JPA but can also be used as a standalone project in any GWT client application by simply inheriting the Errai UI GWT module, and ensuring that you have properly using Errai CDI's @Inject to instantiate your widgets:

Before explaining how to create Errai UI components, it should be noted that these components behave no differently from any other GWT Widget once built. The primary difference is in A) their construction, and B) their instantiation. As with most other features of Errai, dependency injection with CDI is the programming model of choice, so when interacting with components defined using Errai UI, you should always @Inject references to your Composite components.

Custom components in Errai UI are single classes extending from com.google.gwt.user.client.ui.Composite , and must be annotated with @Templated.

Templates in Errai UI may be designed either as an HTML snippit, or as a full HTML document. You may even take an existing HTML page and use it as a template. With either approach, the "data-field" annotation is used to identify fragments (by name) in the template, which are used in the Composite component to add behavior, and use additional components to add functionality to the template. There is no limit to how many component classes may share a given HTML template.

We will begin by creating a simple HTML login form to accompany our @Templated LoginForm composite component.

Or as a full HTML document which may be more easily previewed during design without running the application; however, in this case we must also specify the location of our root component DOM Element using a "data-field" matching the value of the @Templated annotation. There is no limit to how many component classes may share a given HTML template.

Notice the corresponding HTML data-field attribute in the form Element below, and also note that multiple components may use the same template provided that they specify a corresponding data-field attribute. Also note that two or more components may share the same template data-field DOM elements; there is no conflict since components each receive a unique copy of the template DOM from the designated data-field at runtime (or from the root element if a fragment is not specified.)

For example's sake, the component below could also use the same template. All it needs to do is reference the template name, and specify a fragment.

Now that we have created the @Templated Composite component and an HTML template, we can start wiring in functionality and behavior; this is done by annotating fields and methods to replace specific sub-elements of the template DOM with other Widgets. We can even replace portions of the template with other Errai UI Widgets!

Three things are merged or modified when Errai UI creates a new Composite component instance:

Dealing with User and DOM Events is a reality in rich web development, and Errai UI provides several approaches for dealing with all types of browser events using its "quick handler" functionality. It is possible to handle:

A recurring implementation task in rich web development is writing event handler code for updating model objects to reflect input field changes in the user interface. The requirement to update user interface fields in response to changed model values is just as common. These tasks cause a significant amount of boilerplate code which can be alleviated by Errai. Errai's data binding module provides the ability to bind model objects to user interface fields, so they will automatically be kept in sync. While the module can be used on its own, it can cut even more boilerplate when integrated with Errai UI.

In the following example, all @DataFields annotated with @Bound will automatically be bound to properties of the data model (a User object). The model object is provided by an injected DataBinder instance which has to be annotated with @AutoBound for the automatic bindings to be carried out. Both field and constructor injection can be used.



@Templated
public class LoginForm extends Composite {
   @Inject
   @Bound
   @DataField ��
   private TextBox username;

   @Inject ��
   @Bound
   @DataField
   private PasswordTextBox password;
��
   @DataField  ��
   private Button submit = new Button();
   private User user;
   @Inject
   public LoginForm(@AutoBound DataBinder<User> userBinder) {
     this.user = userBinder.getModel();
   }
}

Now the user object and the username and password fields are automatically kept in sync. No event handling code needs to be written for updating the user object in response to input field changes and no code needs to be written for updating the user interface fields when the model object changes (when setUsername or setPassword is called).

By default, the bindings are carried out based on the @DataField names. So, in the example above, the @DataField username is automatically bound to the JavaBean property username of the model object. The @Bound annotation also allows for specifying the property to bind to. In the following example, the password field is bound the JavaBean property named pass, assuming such a property exists in the User class.



@Inject ��
@Bound(property="pass")
@DataField
private PasswordTextBox password;

The @Bound annotation further allows to specify a converter to use for the binding (see Specifying Converters for details). This is how a binding specific converter can be specified on a data field:



@Inject ��
@Bound(converter=MyDateConverter.class)
@DataField
private TextBox date;

Using Composite components to build up a hierarchy of widgets functions exactly the same as when building hierarchies of GWT widgets. The only distinction might be that with Errai UI, @Inject is preferred to manual instantiation.

Templating would not be complete without the ability to inherit from parent templates, and Errai UI also makes this possible using simple Java inheritance. The only additional requirement is that Composite components extending from a parent Composite component must also be annotated with @Templated, and the path to the template file must also be specified in the child component's annotation. Child components may specify @DataField references that were omitted in the parent class, and they may also override @DataField references (by using the same data-field name) that were already specified in the parent component.