When the user clicks on a button or a link with JavaScript enabled, the browser collects the HTML form data and submits it to the web server for processing. It is important to note that web pages may contain multiple forms, provided that the forms are not nested. Also, typically the browser can only submit one form at a time. (We will look at how to use Ajax to submit multiple forms at the same time, later in this book.) Therefore, any UI components that should have their values included in the JSF lifecycle for a particular request should be contained within the same form. In this section, we will look at common ways to submit an HTML form using JSF components.
The standard JSF HTML component library includes components that can be used to render and submit an HTML form. Any components within the form are included in the form submission and will have their user input values sent to the server, converted, and validated during the JSF request processing lifecycle.
To display a form on a JSF page, you can use the<h:form>
tag. This tag renders a UIForm
component as an HTML form using the default HTML RenderKit. This produces an HTML form tag at request time. In JSF, we should always use the<h:form>
tag and not the actual HTML form tag to render a form because the JSF<h:form>
tag renders additional hidden form fields containing important information about the UI component tree for the current view.
The<h:form>
tag component is very common in JSF views, as almost all components need to be included in a form in order to be functional. A JSF view may contain several forms, and in general it is a good idea to divide your user interface into separate forms when it can accept different types of unrelated information from the user.
A good example is a JSF view that has a page header with a user sign-in form, and a content area with a user feedback form. The UI components and bindings involved in authentication have nothing to do with the components and bindings involved in gathering feedback from the user, so these two groups of components should be organized into separate forms. In JSF, all the components in a form are updated when that form is submitted. Therefore, we want to group related controls together and isolate them from groups of other, unrelated controls.
Before an HTML form can be submitted, the user must click on or invoke a user interface component that has been designated as a form submission component. Typically, this is an HTML input element of the type submit
or image
rendered as a button or an image in the browser, but using JavaScript it can also be a hyperlink, checkbox, radio button, select menu, or any other visible or non-visible element on the page.
To begin with a simple example, let's look at how to submit a form using a button or a link component. The standard JSF component library includes two components that are commonly used to submit a form. The HtmlCommandButton
component is rendered as a submit button by the<h:commandButton>
tag, and the HtmlCommandLink
component is rendered as a hyperlink by the<h:commandLink>
tag.
The<h:commandButton>
tag should have at least a label value. In this example, the component simply submits the form when it is invoked, and nothing else.
<h:commandButton value="Submit" />
The HtmlCommandButton
component can also invoke our application logic when it is pressed. The component in this example now submits the form and, if conversion and validation are successful, it then calls a method in our backing bean. This is achieved by specifying a method expression for the button using the JSF EL. We can "wire" several HtmlCommandButton
components to different methods in our backing bean.
<h:commandButton value="Add" actionListener="#{backingBean.addWord}" /> <h:commandButton value="Remove" actionListener="#{backingBean.removeWord}" />
The Java method in our BackingBean
class would be implemented as follows:
public void removeWord(ActionEvent event) { words.remove(word); }
In this example, we can add to or remove words from a collection of words that is stored in our backing bean using a simple JSF user interface.
The<h:commandLink>
tag is similar to the<h:commandButton>
tag. The value
attribute also specifies the label, and both the tags have an actionListener
attribute that registers a backing bean method on the component using a JSF EL method expression.
<h:commandLink value="Add" actionListener="#{backingBean.addWord}" /> <h:outputText value=" | " /> <h:commandLink value="Remove" actionListener="#{backingBean.removeWord}" />
The same screen continues to function in exactly the same way after we replace our command buttons with command links.