Using BindowsFaces™

Introduction

The purpose of BindowsFaces is to add AJAX and Bindows capabilities into JSF applications without resorting to JavaScript. Almost every existing Bindows component has a corresponding, highly customizable, component in BindowsFaces.

Getting Started

Place the ./lib/bindowsfaces.jar file from the bindowsfaces.zip and in the WebContent/WEB-INF/lib directory of your JSF project. A WAR file containing a set of BindowsFaces sample can downloaded separately.

Web.xml

You should enter into the web.xml file; the position of where your Bindows distro can be located. Replace the param-value with the position of your Bindows package, relative to your WebContent folder.

<context-param>
	<param-name>net.bindows.rootPath</param-name>
	<param-value>bindows/html</param-value>
</context-param>

The Tag Library

The BindowsFaces tag library has a corresponding tag for most of the classes in the Bindows framework. The best source of documentation is the Bindows API documentation found here:

http://www.bindows.net/documentation/api/.

Set up the bindows tag library in your jsp file

The following line is the head of your jsp file makes it possible to use the Bindows Faces tag library.

<%@ taglib uri="http://www.bindows.net/taglib" prefix="bi"%>

Complex Attributes

In an ordinary Bindows ADF complex attributes are used to allow setting of properties that take an instance of a class as their argument. For details, please refer to the Bindows documentation. A sample is shown below:

<Label left="10" top="100" text="hello world">
	<Label.border>
		<Border style="solid" color="red"/>
	</Label.border>
</Label>

The corresponding BindowsFaces jsp expression would be:

<bi:Label left="10" top="100" text="hello world">
	<bi:Complex name="border">
		<bi:Border style="solid" color="red"/>
	</bi:Complex>
</bi:Label>

Attached Properties

Another Bindows ADF construct is attached properties, which refer to a static method of a class. For details, please refer to the Bindows documentation. A sample of an attached property is shown below:

<HBox>
	<Label Box.flex="1"/>
</HBox>

The corresponding jsp snipplet would then be:

<bi:HBox>
	<bi:Label boxFlex="1"/>
</bi:HBox>

The BindowsFaces library support Box.flex (boxFlex), DockPanel.dock (dockPanelDock) and Propery.name (propertyName).

Actions

The new Bindows version 4.0 introduces Actions which is a straightforward, flow based way of describing an action sequence.

These Actions are supported is BindowsFaces as well.

Read more at http://www.bindows.net/documentation/40/#actions.

Communication

The ServerAction and the ServerActionEventListener tag

The ServerAction and ServerActionEventListener tags that can be used for implementing AJAX requests to the server and they both follows the new Action paradigm of Bindows. That means that they can be used in consistency with other tags like Reference, EventListener etc... to create complex execution flows containing JSF expression based AJAX server requests.

SIMPLE QUERIES

A small snippet showing how to tie a ServerActionEveneListener to the mouseover event of a Label.

<bi:Label top="10" left="10" width="60" text="Hover Me" backColor="red">	
	<bi:ServerActionEventListener listener="#{bean.count}" type="mouseover" />
</bi:Label>

The next step would be to show how a ServerAction could be used in a more complex construction inconsistency with Reference and EventListener. In this sample a value is fetched from the server whenever a mouseover event is dispatched of a certain Label, this value is set on the text property of another Label:

<bi:Label id="hover2" top="40" left="80" text="0" />
<bi:Label top="40" left="10" width="60" text="Hover Me2"
	backColor="blue">
	<bi:EventListener type="mouseover">
		<bi:Reference src="#hover2" name="text" type="set">
			<bi:Complex name="arguments">
				<bi:ServerAction property="#{bean.number}" />
			</bi:Complex>
		</bi:Reference>
	</bi:EventListener>
</bi:Label>

COMPOSITE QUERIES

The make the server request more efficient composite request can be constructed. When a ServerAction has ServerAction:s as children these children will become parts of a request instead of performing a request by themselves. This sample is showing that when an action event of the Button is dispatched two ServerAction are executed, but they will only use one request to the server. First a listener is executed, countUp, that is increasing the count value and then the actual count property is fetched in set to a property by the Reference:

<bi:Button text="++" top="60">
	<bi:EventListener type="action">
		<bi:Reference type="set" src="countLabel" name="text">
			<bi:Complex name="arguments">
				<bi:ServerAction async="true">
					<bi:ServerAction listener="#{newBean.countUp}" />
					<bi:ServerAction property="#{newBean.count}" />
				</bi:ServerAction>
			</bi:Complex>
		</bi:Reference>
	</bi:EventListener>
</bi:Button>

Sometimes the ServerAction tags that could be executed in a single request can't be placed in a parent/child structure, for those cases the ServerActions can be grouped. In the source below three properties are fetched in a single request whenever a tick event is dispatched. The source also shows how to implement a "poll" mechanism:

<bi:Timer id="pollTimer" interval="1000">
	<bi:EventListener type="tick">
		<bi:Reference src="#needleHours" name="value" type="set">
			<bi:Complex name="arguments">
				<bi:ServerAction async="true" group="time"
						property="#{serverTime.hour}" />
			</bi:Complex>
		</bi:Reference>
			<bi:Reference src="#needleMinutes" name="value" type="set">
				<bi:Complex name="arguments">
					<bi:ServerAction async="true" group="time"
								property="#{serverTime.minute}" />
				</bi:Complex>
			</bi:Reference>
		<bi:Reference src="#needleSeconds" name="value" type="set">
			<bi:Complex name="arguments">
				<bi:ServerAction async="true" group="time"
						property="#{serverTime.second}" />
			</bi:Complex>
		</bi:Reference>
	</bi:EventListener>
</bi:Timer>

THE UPDATE ATTRIBUTE

Usually, by using piggybacking, BindowsFaces updates component properties that are mapped to managed bean properties when the managed bean is updated. However in some cases it's not a desirable behavior, especially in complicated BindowsFaces applications with significant exchange of data between client and server. Therefore the ServerAction and ServerActionEventListener components have an update property. If the update property is set with an id the response of the request will only update mapped properties of the corresponding component and children of this component.

THE RERENDER ATTRIBUTE

ServerAction and ServerActionEventlistener have a property called reRender. The reRender attribute is suitable for implementing dynamic ui:s that are dependent on data. The sample below show how to create a relation between 2 combo boxes.

<bi:ComboBox userValue="#{dataBean.country}">
	<bi:ComboBoxItem text="Choose a Country" userValue="none" selected="true" />
		<c:forEach var="country" items="#{dataBean.countries}">
			<bi:ComboBoxItem text="#{country}" />
		</c:forEach>
		<bi:ServerActionEventListener type="change" reRender="city" />
</bi:ComboBox>
<bi:ComboBox width="100" id="city" userValue="#{dataBean.city}">
	<bi:ComboBoxItem text="Choose a City" userValue="none" selected="true" />
	<c:forEach var="city" items="#{dataBean.cities}">
		<bi:ComboBoxItem text="#{city}" />
	</c:forEach>
</bi:ComboBox>	

JSF Expressions and Binding

PROPERTY MAPPING

Properties of Bindows Faces tags can be mapped to a managed bean property by using a JSF expression e.g.:

<bi:Label id="label" left="10" top="100" text="#{bean.number}"/>

The text property of this label will of course get the value of the "#{bean.number}" expression when rendered, and this value will also be updated whenever a Bindows Faces AJAX request is executed using the JsfRequest tag.

BINDING

All Bindows Faces tags can be bound to a property on a managed bean by using the attribute "binding" see below:

<bi:Label binding="#{bean.label}" left="10" top="200"/>

Below we how the accessors of the bounded label property can be implemented. In the eventListener some of the label properties are updated, those properties will be updated on the client side as well.

private Label label = null;
public Label getLabel() {
	if(label == null)
		label = Label.create();
	return label;
}
public void setLabel(Label label) {
	this.label = label;
}
//A event listener
public void eventListener(Event event) {
	label.setText("My text");
	label.setLeft(10);
	label.setTop(300);
}

JSF and Bindows Conjunction Features

Forms

Some of the BindowsFaces components automatically support form behavior. When using these component together with a ServerActionEventListener there form property will be updated on the server as well as any EL expression pointed property. The form enabled components and their form properties:

TextField -- text
TextArea -- text
ComboBox -- value, userValue
List -- value, userValue
Grid -- value
Spinner -- value
DataPicker -- selectedDate
Calendar -- selectedDate

JSTL

JSTL can be used for steering the rendering in BindowsFaces page, for server side flow such as loops or conditional statements.

BindowsFaces encapsulate the JSF navigation mechanism and enables navigation between BindowsFaces pages without reloading the page and without terminating the current Bindows application.

The snippets below show how to use this feature:

faces-config.xml - The navigation rules.

<navigation-rule>
		<display-name>sample3</display-name>
		<from-view-id>/sample3.jsp</from-view-id>
		<navigation-case>
			<from-outcome>page0</from-outcome>
			<to-view-id>/page0.jsp</to-view-id>
		</navigation-case>
	</navigation-rule>
	<navigation-rule>
		<display-name>sample3</display-name>
		<from-view-id>/sample3.jsp</from-view-id>
		<navigation-case>
			<from-outcome>page1</from-outcome>
			<to-view-id>/page1.jsp</to-view-id>
		</navigation-case>
	</navigation-rule>
	<navigation-rule>
		<display-name>sample3</display-name>
		<from-view-id>/sample3.jsp</from-view-id>
		<navigation-case>
			<from-outcome>page2</from-outcome>
			<to-view-id>/page2.jsp</to-view-id>
		</navigation-case>
	</navigation-rule>

sample3.jsp - The main Bindows application, notice the attribute containerId, it tells BindowsFaces where to put the result of the navigation.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib uri="http://www.bindows.net/taglib" prefix="bi"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>BindowsFaces sample showing AJAX Navigation.</title>
</head>
<body>
<f:view>
	<bi:Component top="10" left="10" width="400" height="300">
		<bi:Component id="pageContainer" top="0" left="0" right="0"
			bottom="30" border="2 solid blue"/>
		<bi:Button text="Navigate" top="273">
			<bi:ServerActionEventListener type="action"
				action="#{backingBean.navigate}" containerId="pageContainer" />
		</bi:Button>
	</bi:Component>
</f:view>
</body>
</html>

BackingBean.java - Contains the navigate method that decides where to navigate.

public class BackingBean {
	private int currentPage = -1;
	
	public String navigate() {
		int page = (currentPage == 2 ? currentPage = 0 : ++currentPage);
		return "page" + page;
	}
}

Page0.jsp - Page1.jsp and Page2.jsp are equal to Page0.jsp.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1"%>

<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@ taglib uri="http://www.bindows.net/taglib" prefix="bi"%>
<f:view>
	<bi:Component top="0" left="0" right="0" bottom="0">
		<bi:Label align="center" top="100" left="0" right="0" text="PAGE 0"
			font="24px" />
	</bi:Component>
</f:view>

Validation

The TextField and TextArea supports conversion and validation however since BindowsFaces is much more dynamic then ordinary JSF the messages are supplied through a managed bean called messageBean. This sample shows a simple form utilizing the validation mechanism.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="UTF-8"%>

<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib uri="http://www.bindows.net/taglib" prefix="bi"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>BindowsFaces sample showing a simple form.122222</title>
</head>
<body>
<table width="100%" border="0">
	<tr>
		<td><f:view>
			<bi:Window id="window" caption="Simple Form" movable="false" top="10"
				left="10" width="330" height="130" showClose="false"
				showMaximize="false" showMinimize="false" showIcon="false">

				<bi:Label left="10" top="10" text="Current Value: " />
				<bi:Label top="8" left="87" width="103" height="18"
					text="#{formBean.text}" border="2 inset" />

				<bi:Label id="error" left="10" top="30"
					text="#{messageBean.messageMap['myTextField'].summary}" />
				<bi:TextField left="10" top="50" width="180"
					id="myTextField" text="#{formBean.text}">
					<f:validateLength minimum="2" maximum="10" />
				</bi:TextField>

				<bi:Button left="10" top="80" text="Submit" preferredWidth="100">
					<bi:ServerActionEventListener type="action" />
				</bi:Button>

			</bi:Window>
		</f:view></td>
	</tr>
</table>
</body>
</html>

Live Scrolling

The Grid component of BindowsFaces supports live scrolling. The live scrolling mechanism is activated by setting the liveScrollingRows to a higher value then 0. The number of rows put in the grid when the page is loaded is determined by the property rows. Whenever the user scrolls the grid below the last row on the client, and there exists more rows in the server data, new rows is added to the grid. The number if new rows for each request caused by an "outside" scrolling is equivalent to the value of liveScrollingRows.

Binding Components to Arrays and Collections

Components such as list and grids usually have a children set of the same type. Is suitable that these children can be generated from collections or arrays returned by managed beans. The way these type of component is constructed in a BindowsFaces application is similar to the standard JSF dataTable component, however inside a column component both outputText or BindowsFaces components can be used. This sample shows how to construct a Grid from a collection using the standard column component and outputText:

<bi:Grid id="dt1" sourceValue="#{tableBean.perInfoAll}" var="item"
			left="0" top="0" right="0" bottom="100" rows="6" liveScrollRows="3">

	<h:column>
		<f:facet name="header">
			<h:outputText value="id" />
		</f:facet>
		<h:outputText value="#{item.id}"></h:outputText>
	</h:column>

	<h:column>
		<f:facet name="header">
			<h:outputText value="name" />
		</f:facet>
		<h:outputText value="#{item.name}"></h:outputText>
	</h:column>

	<h:column>
		<f:facet name="header">
			<h:outputText value="phone" />
		</f:facet>
		<h:outputText value="#{item.phone}"></h:outputText>
	</h:column>

	<h:column>
		<f:facet name="header">
			<h:outputText value="city" />
		</f:facet>
		<h:outputText value="#{item.city}"></h:outputText>
	</h:column>

	<h:column>
		<f:facet name="header">
			<h:outputText value="pin" />
		</f:facet>
		<h:outputText value="#{item.pin}"></h:outputText>
	</h:column>
</bi:Grid>

In BindowsFaces a combo box can be created using column as well, in this sample a ComboBoxItem is used instead of outputText.

<bi:ComboBox id="dt1" sourceValue="#{tableBean.perInfoAll}" var="item"
	     left="0" top="0" width="200">

	<h:column>
		<bi:ComboBoxItem text="#{item.name}"
			icon="#{item.city == 'aaa' ? 
'../bindows/html/images/alias.gif' : '../bindows/html/images/arrow.up.gif'}" />
	</h:column>
</bi:ComboBox>

The JsClassName Attribute

The jsClassName attribute tells the BindowsFaces renderes which JavaScript class should be used to create the client side representation of a specific component. All BindowsFaces component has a default jsClassName e.g. the Button component has BiButton as default, TextField has BiTextField... This makes it possible for the developer to use custom JavaScript implementations of the BindowsFaces component.

Resources and Themes

The "resources" part of a Bindows ADF (See the Bindows Tutorial) is used for loading additional scripts, custom classes, packages etc... In BindowsFaces the resource utility components ResourceScript, CustomClass and Package are exposed to the developer.

Observe that these components must be placed before any other BindowsFaces components to have any effect.

Use Custom Components or existing Bindows application in BindowsFaces

Using CustomClass or ResourceScript in conjunction with the jsClassName attribute enables use of custom components or existing application created in JavaScript and Bindows markup.

The sample below shows how to utilize a Bindows custom component created outside BindowsFaces by using the CustomClass component and the jsClassName attribute.

Notice that Complex is used to set additional attributes

<bi:CustomClass name="FieldEditControl" uri="../CustomClassTest_FieldEditControl.xml"/>
<bi:CustomClass name="PersonEditControl" uri="../CustomClassTest_PersonEditControl.xml"/>
<bi:Component left="0" top="0" right="0" bottom="0">
	<bi:Component jsClassName="PersonEditControl" left="10" top="10">
		<bi:Complex name="personFirstName" value="Donald"/>
		<bi:Complex name="personLastName" value="Duck"/>
		<bi:Complex name="personEMail" value="donald.duck@pondkings.org"/>
	</bi:Component>
</bi:Component>

Themes

The Bindows package contains 6 different predefined themes. To change the default theme the developer can use the Theme component. The Theme must be positioned before any other BindowsFaces components to have any effect.