Developer notes written down before they get lost.
GWT Elemento
GWT Elemento is a library which tries to make working with GWT Elemental as easy as possible. In a nutshell Elemento brings the following features to the table:
Builder like API to easily create arbitrary large element hierarchies
HTML templates, declarative event handling and support for handlebar-like expressions
Helper methods to mix and match GWT Elemental and GWT Widgets
In this blog post I will give a short introduction to some of Element’s features.
Builder API
When working with GWT Elemental it is often awkward and cumbersome to create an hierarchy of elements. Even simple structures like
1234567891011121314
<sectionclass="main"><inputclass="toggle-all"type="checkbox"><labelfor="toggle-all">Mark all as complete</label><ulclass="todo-list"><li><divclass="view"><inputclass="toggle"type="checkbox"checked><label>Taste Elemento</label><buttonclass="destroy"></button></div><inputclass="edit"></li></ul></section>
lead to a vast amount of Document.createXXXElement() and chained Element.appendChild() calls. However using Elemento’s builder API, creating the above structure is as easy as
1234567891011121314151617181920
importstaticorg.jboss.gwt.elemento.core.InputType.checkbox;importstaticorg.jboss.gwt.elemento.core.InputType.text;// @formatter:offElementelement=newElements.Builder().section().css("main").input(checkbox).css("toggle-all").label().attr("for","toggle-all").innerText("Mark all as complete").end().ul().css("todo-list").li().div().css("view").input(checkbox).css("toggle").label().innerText("Taste Elemento").end().button().css("destroy").end().end().input(text).css("edit").end().end().end().build();// @formatter:on
Templates
Elemento provides an easy way to take existing HTML content and use it in your GWT application. Templates can be either HTML snippets or full HTML documents where you select an element and its children. This allows you to preview your templates more easily during design without running the application.
Elemento leverages annotation processors to generate code which picks the HTML content from your template. Let’s say you’ve got the following HTML document called Todo.html:
<!doctype html><htmllang="en"><head><linkrel="stylesheet"href="<path-to>/node_modules/todomvc-common/base.css"><linkrel="stylesheet"href="<path-to>/node_modules/todomvc-app-css/index.css"></head><body><sectiondata-element="todos"class="todoapp"><headerclass="header"><h1>todos</h1><inputdata-element="newTodo"class="new-todo"placeholder="What needs to be done?"autofocus></header><sectiondata-element="main"class="main"><inputdata-element="toggleAll"class="toggle-all"id="toggle-all"type="checkbox"><labelfor="toggle-all">Mark all as complete</label><uldata-element="list"class="todo-list"><!-- Todo items are mapped to an extra template class --></ul></section><footerdata-element="footer"class="footer"><spandata-element="count"class="todo-count"><strong>0</strong> item left</span><ulclass="filters"><li><adata-element="all"href="#/">All</a></li><li><adata-element="active"href="#/active">Active</a></li><li><adata-element="completed"href="#/completed">Completed</a></li></ul><buttondata-element="clearCompleted"class="clear-completed">Clear completed</button></footer></section>[...]
</body></html>
The HTML is enriched with data-element attributes. Elemento needs these attributes to select the root element and to map specific HTML elements to fields in the template class. To create a template class which maps to the <section/> element, create an abstract class and annotate it with @Templated:
To map specific elements from the HTML to your template class use the @DataElement annotation. If no value is provided for the @DataElement annotation, the name of the field / method is taken as default.
It’s also possible to register event handlers for elements marked with data-element=<name>. It does not matter whether the HTML element is mapped with @DataElement. Attaching the event handler will work in any case.
If you want to learn more about HTML templates take a look at the official documentation.
Goodies
Elemento contains a small set of static helper methods to make working with elements easier. One set of methods can be used to convert between Element and Widget:
123456789101112131415161718192021222324
/** * Converts from {@link IsElement} → {@link Widget}. */publicstaticWidgetasWidget(IsElementelement){...}/** * Converts from {@link Element} → {@link Widget}. */publicstaticWidgetasWidget(Elementelement){...}/** * Converts from {@link IsWidget} → {@link Element}. */publicstaticElementasElement(IsWidgetwidget){...}/** * Converts from {@link Widget} → {@link Element}. */publicstaticElementasElement(Widgetwidget){...}/** * Converts from {@link com.google.gwt.dom.client.Element} → {@link Element}. */publicstaticElementasElement(com.google.gwt.dom.client.Elementelement){...}
Finally there are methods to iterate over the children of an element using the Java collection classes:
12345678910
/** * Returns an iterator over the children of the given parent element. The iterator supports the {@link * Iterator#remove()} operation which removes the current element from its parent. */publicstaticIterator<Element>iterator(Elementparent){...}/** * Returns an iterable collection for the children of the given parent element. */publicstaticIterable<Element>children(Elementparent){...}
All three samples are using the same key to persist the todo items in the local storage. So you can switch between the samples and continue working on your tasks seamlessly ;-)