3. Creating the Address Details Pane
The JSP is again our focal point for this component. Like the SelectTable component, adding powerful
features is simply a matter of adding component tags and setting the appropriate attributes. The
Address Details pane is shown below.

Figure 4. Address Details Pane.
The Address Details pane is made up of plain HTML plus ECruiser? tags for the user input fields. The
work of arranging the fields with labels is accomplished by the Field layout component. It includes a
convenient shortcut that builds the labels from the IDs. Of course, you can explicitly define field
labels, but if you want, you can use the shortcut by setting the idsForLabels property to "true" and
ECruiser? will automatically create labels from the id property.
| FYI: Other ECruiser® components feature similar shortcuts
to make your programming life easier.
|
Have a look at the JSP for this input component and you will see many of the same characteristics
that we have examined so far:
 |
Add AJAX power with a simple property setting |
| |
|
ajax="true" |
 |
Set operational characteristics by binding to the backing bean |
| |
|
value="#{addressBean.selectedAddress.firstName}" |
 |
Define how to handle standard JavaScript events |
| |
|
onchange="#{addressBean.updateData}"/> |
 |
Define styles using style class name assignments and CSS |
| |
|
suggestColumnStyles="suggestColumn" |
Examine the JSP to see for yourself how easy component setup can be.
<e:fieldLayout fieldStyle="fieldLayoutInput" idsForLabels="true">
<e:input
id="firstName"
ajax="true"
disabled="#{addressBean.disabled}"
value="#{addressBean.selectedAddress.firstName}"
onchange="#{addressBean.updateData}"/>
<e:input
id="lastName"
ajax="true"
disabled="#{addressBean.disabled}"
value="#{addressBean.selectedAddress.lastName}"
onchange="#{addressBean.updateData}"/>
<e:lookupinput
id="country"
ajax="true"
suggestColumnStyles="suggestColumn"
lookupColumnHeaders="Country"
dataModel="#{addressBean.countryModel}"
suggestColumnIds="country"
keyField="country"
disabled="#{addressBean.disabled}"
value="#{addressBean.selectedAddress.country}"
onchange="#{addressBean.updateData}"
lookupWidth="200"/>
<e:textarea
id="address"
ajax="true"
rows="5"
cols="30"
disabled="#{addressBean.disabled}"
value="#{addressBean.selectedAddress.address}"
onchange="#{addressBean.updateData}"/>
</e:fieldLayout>
One other thing you might have noticed in your examination is how we used the disabled property for
our fields to keep them inactive until an event occurred to allow users to enter new information. Once
again, the operational responsibility is given to the backing bean. We use a similar technique with
the Delete button (discussed in the next section) as well.
4. Creating the Control Buttons
The final piece of the UI is the two control buttons.

Figure 5. Insert and Delete Buttons.
Check out the code snippet below. One thing you might notice is that the only style applied is width.
Just as with straight HTML, you have the option of using inline styles instead of linking to a style
class.
The buttons' functions are assigned using a standard JavaScript onclick event to call a method in the
backing bean-not much to it.
<e:button
ajax="true"
style="width:75px"
value="Insert"
immediate="true"
onclick="#{addressBean.insertAddress}"/>
<e:button
ajax="true"
style="width:75px"
value="Delete"
onclick="if(confirm('Delete
selected
address?'))#{addressBean.deleteAddress}"
disabled="#{addressBean.disabled}"/>
For the Delete button's onclick action, we show how easily you can combine a typical
piece of JavaScript with the binding expression. In this case, we are conditionally calling the method
in the bean - that is, after users confirm that they want to delete the record.
5. Creating the AJAX Example Backing Bean
A Simple POJO Does it All
Where the JSP provides the place to define the UI, the Backing Bean provides the place for
application logic.
So that obviously means that this is where all the programming difficulties really come in, right? To
get all the functionality like we see in the graphic below requires some special training and
knowledge, right? Not really!

Figure 6. The Backing Bean Provides the Place for Application Logic.
The backing bean is a few getters and setters, and some basic event handling logic; that's all, not
nearly as difficult as you might think.
As we saw in the previous sections, the key to connecting the UI with the backing bean lies with the
binding expressions that are assigned as attributes.
The backing bean appears below in its entirety; complete with comments to help explain each part of
the code for your convenience.
import ecruiser.model.WrappedDataModel;
import javax.faces.event.ActionEvent;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* The main backing bean for the address book demo. Addresses are modeled using
a list
* of simple HashMap instances and this bean keeps track of which of them is
currently
* selected.
*/
public class AddressBookBean {
/**
* WrappedDataModel is an implementation of ECDataModel that allows inserting
and
* deleting of rows and support for AJAX.
*/
private WrappedDataModel addressModel;
/**
* Keeps the state of the selected address.
*/
private Map selectedAddress;
/**
* Default constructor initialzes the address model.
*/
public AddressBookBean() {
addressModel = new WrappedDataModel(new
ListDataModel(Data.getInitialAddresses()));
}
/**
* Returns the data model with the list of addresses used by the main
SelectTable.
*/
public WrappedDataModel getAddressModel() {
return addressModel;
}
/**
* Returns the data model with the list of countries used by the
LookupInput.
*/
public DataModel getCountryModel() {
return Data.COUNTRY_MODEL;
}
/**
* Returns the flag used by the button and input components to show
* their state as disabled.
*/
public boolean isDisabled() {
return selectedAddress == null;
}
/**
* Sets the selected address.
*/
public void setSelectedAddress(Map selectedAddress) {
this.selectedAddress = selectedAddress;
}
/**
* Gets the selected address.
*/
public Map getSelectedAddress() {
return selectedAddress;
}
/**
* Handles the onchange event for the input components. It makes the
addressModel
* dirty so the main SelectTable's data will be refreshed when any of the
individual
* fields change.
*/
public void updateData(ActionEvent event) {
addressModel.setDirty(true);
}
/**
* Handles inserting a new address. This method is called by the Insert button.
* New addresses are always added to the end of the list.
*/
public void insertAddress(ActionEvent event) {
Map item = new HashMap();
item.put("id", Long.toString(System.currentTimeMillis()));
item.put("firstName", "[First Name]");
item.put("lastName", "[Last Name]");
item.put("address", "[Address]");
addressModel.insertRow(-1, item);
selectedAddress = item;
}
/**
* Handles deleting an address. This method is alled by the Delete button.
The
* new selected address will be the address after the deleted address
except
* when it is the last address.
*/
public void deleteAddress(ActionEvent event) {
List data = (List)addressModel.getWrappedData();
int oldIndex = data.indexOf(selectedAddress);
int newIndex = oldIndex;
if(data.size() == 0) {
newIndex = -1;
}
else if(oldIndex + 1 == data.size()) {
newIndex = oldIndex - 1;
}
addressModel.deleteRow(selectedAddress);
if(newIndex != -1) {
selectedAddress = (Map)data.get(newIndex);
}
else {
selectedAddress = null;
}
}
}
You might have noticed references to a data model, which provides a list of items for a component. We
moved some of the code that simply enumerates static values into a separate object called "Data" and
we reference it as needed here. For this example, the list items are provided as in-memory objects,
but because the JSF DataModel is quite flexible, these items could have come from a database or other
persistent data source.
Summary
So let's recap our AJAX example.
Our demo illustrates how ECruiser® takes the heavy work out of creating web applications. You can
simply create applications by using just a few files; in our example a JSP, a CSS, a backing bean, and
a data file.
The JSP is a key element. Just use plain HTML in the JSP to define the layout and static content of
your page, then insert ECruiser® tags for the parts you want to be AJAX-enabled.
Property assignments in the JSP assign style classes to specific components, or you can use inline
styles. Beyond that, you simply define the style attributes within the CSS much like you would in any
application using CSS.
Where the JSP provides the place to define the UI, the Backing Bean provides the place for
application logic. The backing bean is a few getters and setters, and some basic event handling logic.
The key to connecting the UI with the backing bean lies with the binding expressions that are assigned
as attributes.
Take some time and play with the demo to get a feel for its features and behavior. Then if you like,
look a little closer at the JSP, CSS, and Backing Bean to see just how this AJAX example application
was put together.
Download Now!
Ready to try yourself? This Address Book example application, this example guide as a PDF and
everything else you need to get started with ECruiser® are available from our Download Page.
Download ECruiser® and get started today!
< Previous Page 1 of 2
|