JavaServer Faces with Eclipse
This article describes how to develop JavaServer Faces web applications with Eclipse WTP JSF tooling. It demonstrates managed beans, validators, external resource bundles and the JSF navigation concept.
This tutorial was developed with Java 1.6, JavaServerFaces 1.2, the Apache MyFaces JSF implementation, Tomcat 6.0 and Eclipse 3.6.
Table of Contents
JavaServer Faces (JSF) is a UI component based Java Web application framework. JSF is serverbased, e.g. the JSF UI components and their state are represented on the server with a defined life-cycle of the UI components. JSF is part of the Java EE standard.
This articles provides an introduction to JSF using only standard JSF features. For the usage of special Apache Trinidad features please see Apache Myfaces Trinidad with Eclipse - Tutorial .
A JSF application consists of web pages with JSF UI components. A JSF application requires also some configuration files ("faces-config.xml" and
web.xml
).
The faces-config.xml defines:
- Managed Bean - the data elements of the JSF application (managed beans and backing beans) Represents a Java class which will be created dynamically during runtime of the JSF application. It can be defined for which scope the bean is valid (Session, Request, Application or none).
- the navigation between web pages
- data validators - Used to check the validity of UI input
- data converters -Used to translate between UI and model
Managed beans are simple Java objects (POJO's) which are declared in "faces-config.xml" and can be used in an JSF application. For example you can define a Java object "Person". Once you define the object in faces-config.xml you can use the attributes of Person in your JSF UI components, e.g. by binding the value "firstName" of this object to an JSF input field.
JSF uses the Unified Expression Language (EL) to bind UI components to object attributes or methods.
In JSF you can access the values of a managed bean via value binding. For value binding the universal Expression Language (EL) is used (to access bean and / or methods). In JSF you do not need to specify the get() or set() method but just the variable name.
Method binding can be used to bind a JSF component, e.g. a button to an method of a Java class.
To use JSF you need:
- JSF Implementation (in the form of the JSF jars)
- The JSTL tags library
- A Java runtime environment
- A web-container to use JSF in (for example Tomcat)
JSP has the following main features:
- JSP is based on the Model-View-Controller concept
- JSP has a stateful UI component model, e.g. each component is aware of its data
- JSF separates the functionality of a component from the display of the component. The renderer is responsible of displaying the component for a certain client. This renderer can get exchanged. The standard renderer for JSF components is the HTML renderer.
- JSP support listeners on UI components
- JSP support data validation, data binding and data conversion between the UI and the model
JSF is based on the following configuration files:
- web.xml - General web application configuration file
- faces-config.xml - Contains the configuration of the JSF application.
JSF requires the central configuration list
web.xml
in the directory WEB-INF of the application. This is similar to other web-applications which are based on servlets.
You must specify in
web.xml
that a "FacesServlet" is responsible for handling JSF applications. "FacesServlet" is the central controller for the JSF application. "FacesServlet" receives all requests for the JSF application and initializes the JSF components before the JSP is displayed.
For JSP development you need the Eclipse WTP and an installed Tomcat. See Installation of Eclipse WTP and Tomcat.
A JSF library is required. We will later use Eclipse to download and install the Apache MyFaces JSF implementation during project creation.
Download the JSLT library from https://jstl.dev.java.net/.
Our first JSF example will be a celsius to fahrenheit convertor.
Create a new Dynamic Web Project "de.vogella.jsf.first". Under "Configuration" select "JavaServer Faces v1.2".
Press next until you see the following screen.
The first time you create a JSF project you need to install / download a JSF implementation. Press the "Download library..." button and select the Apache Library and install it.
Press Manage libraries and create a library for JSTL.
Click "Finish". Your project has been created
Review the
web.xml
file. It has an entry for the Faces Servlet and for the servlet mapping. Also the file "faces-config.xml" has been created.
Create a package "de.vogella.jsf.first.model" and the class "TemperatureConvertor".
package de.vogella.jsf.first.model; public class TemperatureConvertor { private double celsius; private double fahrenheit; private boolean initial= true; public double getCelsius() { return celsius; } public void setCelsius(double celsius) { this.celsius = celsius; } public double getFahrenheit() { return fahrenheit; } public boolean getInitial(){ return initial; } public String reset (){ initial = true; fahrenheit =0; celsius = 0; return "reset"; } public String celsiusToFahrenheit(){ initial = false; fahrenheit = (celsius *9 / 5) +32; return "calculated"; } }
Double-click on faces-config.xml in the WEB-INF directory and select the tab "ManagedBeans".
Press add and maintain your class.
The result should look like the following:
Select your project, right-click on it, select New -> JSP. Create the JSP page "Convertor.jsp". Use the "New JavaServer Faces (JSF) Page (html)" template.
Change the code to the following.
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ taglib prefix="f" uri="http://java.sun.com/jsf/core"%> <%@ taglib prefix="h" uri="http://java.sun.com/jsf/html"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Celsius to Fahrenheit Convertor</title> </head> <body> <f:view> <h:form> <h:panelGrid columns="2"> <h:outputLabel value="Celsius"></h:outputLabel> <h:inputText value="#{temperatureConvertor.celsius}"></h:inputText> </h:panelGrid> <h:commandButton action="#{temperatureConvertor.celsiusToFahrenheit}" value="Calculate"></h:commandButton> <h:commandButton action="#{temperatureConvertor.reset}" value="Reset"></h:commandButton> <h:messages layout="table"></h:messages> </h:form> <h:panelGroup rendered="#{temperatureConvertor.initial!=true}"> <h3> Result </h3> <h:outputLabel value="Fahrenheit "></h:outputLabel> <h:outputLabel value="#{temperatureConvertor.fahrenheit}"></h:outputLabel> </h:panelGroup> </f:view> </body> </html>
Select Convertor.jsp, right mouse-click- >run as -> run on server.
Congratulations. You should be able to use your JSF application.
JFP application can get styles via css files. To load a style sheet include the following in your JSP page in the header section. This then related to a mystyle.css file under your folder WebContent/css..
<LINK href="<%=request.getContextPath()%>/css/mystyle.css" rel="stylesheet" type="text/css">
This second JSF application will add validation, resource bundles and navigation as additional functionality.
Create a new package de.vogella.jsf.starter.model and the following class.
package de.vogella.jsf.starter.model; public class User { private String name; private String password; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String login(){ // Image here a database access to validate the users if (name.equalsIgnoreCase("tester") && password.equalsIgnoreCase("tester")){ return "success"; } else { return "failed"; } } }
Create the following class.
package de.vogella.jsf.starter.model; import java.util.Random; public class Card { private int left; private int right; private int result = 0; public Card() { Random random = new Random(); int i = 0; int j = 0; do { i = random.nextInt(10); } while (i <= 4); do { j = random.nextInt(100); } while (j <= 20); left = i; right = j; } public int getLeft() { return left; } public void setLeft(int left) { this.left = left; } public int getRight() { return right; } public void setRight(int right) { this.right = right; } // Controller public String show() { result = left * right; return "success"; } public String clear() { result = 0; return "clear"; } public int getResult() { return result; } public void setResult(int result) { this.result = result; } }
Double-click on faces-config.xml and select the tab "ManagedBeans". Register your User.java and Card.java as managed beans.
JSP allows to define validators which allows to check certain values which are placed in the UI. Create therefore the following class.
package de.vogella.jsf.starter.validator; import javax.faces.application.FacesMessage; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.validator.Validator; import javax.faces.validator.ValidatorException; public class LoginValidator implements Validator { public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { String user = (String) value; if (!user.equalsIgnoreCase("tester")) { FacesMessage message = new FacesMessage(); message.setDetail("User " + user + " does not exists"); message.setSummary("Login Incorrect"); message.setSeverity(FacesMessage.SEVERITY_ERROR); throw new ValidatorException(message); } } }
Select your faces-config.xml and select the tab Component. Select Validators and press Add.
With JSP it is easy to use resource bundles for the static text in your JSP application. Create the following file "messages.properties" in your source folder under the package "de.vogella.jsf.starter".
user=User password=Password login=Login hello=Moin left=Left Side right=Right Side result= Result show= Show Result next= New Test reset= Reset
Create a new JSP page "LoginView.jsp" and change the code to the following:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ taglib prefix="f" uri="http://java.sun.com/jsf/core"%> <%@ taglib prefix="h" uri="http://java.sun.com/jsf/html"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Login</title> </head> <body> <f:view> <f:loadBundle basename="de.vogella.jsf.starter.messages" var="msg" /> <h:form> <h:panelGrid columns="2"> <h:outputLabel value="#{msg.user}"></h:outputLabel> <h:inputText value="#{user.name}"> <f:validator validatorId="de.vogella.jsf.starter.validator.LoginValidator" /> </h:inputText> <h:outputLabel value="#{msg.password}"></h:outputLabel> <h:inputSecret value="#{user.password}"> </h:inputSecret> </h:panelGrid> <h:commandButton action="#{user.login}" value="#{msg.login}"></h:commandButton> <h:messages layout="table"></h:messages> </h:form> </f:view> </body> </html>
Lets explain a few fields.
Table 1.
Element | Description |
---|---|
<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core"%> <%@ taglib prefix="h" uri="http://java.sun.com/jsf/html"%> | Makes the core and html tags available in the page |
<f:view> | Indicates that the following will use JSF components. |
<f:loadBundle basename="de.vogella.jsf.starter.messages" var="msg"/> | load the resource / message bundle which is then available in the application under the name msg |
<h:form> | Starts a form |
<h:outputLabel value="#{msg.user}"></h:outputLabel> | Define a label which used the text user define in the resource bundle |
<h:inputText tabindex="1" value="#{user.name}"></h:inputText> | Define a input field which used the managed bean user and maps to field name |
<h:inputSecret tabindex="2" value="#{user.password}"> | Masked input files, mapped to the managed bean user and field password |
<h:commandButton action="#{user.login}" value="#{msg.login}"></h:commandButton> | The button is mapped to the method user.login |
Create another JSP "Trainer.jsp" with the following code.
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ taglib prefix="f" uri="http://java.sun.com/jsf/core"%> <%@ taglib prefix="h" uri="http://java.sun.com/jsf/html"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Insert title here</title> </head> <body> <f:view> <f:loadBundle basename="de.vogella.jsf.starter.messages" var="msg" /> <h:form> <h:panelGrid columns="3"> <h:outputLabel value="#{msg.left}"></h:outputLabel> <h:inputText id="left" value="#{card.left}"></h:inputText> <h:message for="left"></h:message> <h:outputLabel value="#{msg.right}"></h:outputLabel> <h:inputText id="right" value="#{card.right}"> </h:inputText> <h:message for="right"></h:message> </h:panelGrid> <h:commandButton action="#{card.show}" value="#{msg.show}"></h:commandButton> <h:commandButton action="#{card.clear}" value="#{msg.reset}" immediate="true"></h:commandButton> <h:messages layout="table"></h:messages> </h:form> <h:panelGrid rendered="#{card.result!=0}" columns="3"> <h:outputLabel value="#{msg.result}"></h:outputLabel> <h:inputText id="result" value="#{card.result}"> </h:inputText> <h:message for="result"></h:message> </h:panelGrid> </f:view> </body> </html>
Create another JSP FailedLogin.jsp with the following code.
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ taglib prefix="f" uri="http://java.sun.com/jsf/core"%> <%@ taglib prefix="h" uri="http://java.sun.com/jsf/html"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Insert title here</title> </head> <body> <f:view> <h1>Failed Login.</h1> </f:view> </body> </html>
Select your faces-config.xml and select the tab "Navigation Rule". Make the palette available if necessary.
Select Page and click in the workarea. Add LoginView and Trainer to the workspace.
Click on Link, then on LoginView and then on Trainer. You should have now an arrow which indicates a navigation rule.
Click in the Palette on Select. Select then the arrow and the properities view. Input "success" in the From – Outcome
Add a navigation rule so that in the case the user does not use the right user / password you send him to the failure page.
We will now extend the example from the previous chapter to a math trainer. The system will propose two number and the user must multiply both values and input the result.
This JSF application will use a controller which handles the JSF logic. This will allow you to create a domain model without application logic.
This example will also demonstrate the usage of dependency injection in JSF.
Create a new package de.vogella.jsf.card.model and the following class.
package de.vogella.jsf.card.model; import java.util.Random; public class Card { private int left; private int right; public Card() { Random random = new Random(); int i = 0; int j = 0; do { i = random.nextInt(10); } while (i <= 4); do { j = random.nextInt(100); } while (j <= 20); left = i; right = j; } public int getLeft() { return left; } public void setLeft(int left) { this.left = left; } public int getRight() { return right; } public void setRight(int right) { this.right = right; } }
Create the following class CardController.
package de.vogella.jsf.card.controller; import javax.faces.application.FacesMessage; import javax.faces.component.UIPanel; import javax.faces.context.FacesContext; import de.vogella.jsf.card.model.Card; public class CardController { private Card card; private UIPanel resultPanel; private int result; public CardController() { } public String checkResult() { FacesContext context = FacesContext.getCurrentInstance(); resultPanel.setRendered(true); if (checkOperation()) { context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Correct", null)); } else { context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Incorrect", null)); } return null; } private boolean checkOperation() { return (card.getLeft() * card.getRight() == result); } public UIPanel getResultPanel() { return resultPanel; } public void setResultPanel(UIPanel resultPanel) { this.resultPanel = resultPanel; } public int getResult() { return result; } public void setResult(int result) { this.result = result; } public String next() { FacesContext context = FacesContext.getCurrentInstance(); if (checkOperation()){ resultPanel.setRendered(false); card = new Card(); return null; } else { context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Incorrect", null)); } return null; } public Card getCard() { return card; } public void setCard(Card card) { this.card = card; } }
This class has a field resultPanel. This field will later get connected to a UIComponent (panel) from the JSP.
Double-click on faces-config.xml and select the tab "ManagedBeans". Register the classes "CardController" and "Card" as managed beans. The scope of card will be set to none as it will be inserted into the ControllerCard via dependency injection. In the initialization tab maintain the data as displayed in the screenshot. The value #{card} refers to the managed bean "card".
The generated XML code should look like the following (you see this if you select the tab "Source".
<managed-bean> <managed-bean-name>cardController</managed-bean-name> <managed-bean-class>de.vogella.jsf.card.controller.CardController</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> <managed-property> <property-name>card</property-name> <property-class>de.vogella.jsf.card.model.Card</property-class> <value>#{card}</value> </managed-property> </managed-bean> <managed-bean> <managed-bean-name>card</managed-bean-name> <managed-bean-class>de.vogella.jsf.card.model.Card</managed-bean-class> <managed-bean-scope>none</managed-bean-scope> </managed-bean>
Create the following file "messages.properties" in your source folder under the package "de.vogella.jsf.card".
left=Left Side right=Right Side result=Result show= Check next= Next
Create a new JSP page "Trainer.jsp" and change the code to the following:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ taglib prefix="f" uri="http://java.sun.com/jsf/core"%> <%@ taglib prefix="h" uri="http://java.sun.com/jsf/html"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Insert title here</title> </head> <body> <h1> Train your Brain</h1> <h3>Please calculate the result </h3> <f:view> <f:loadBundle basename="de.vogella.jsf.card.messages" var="msg" /> <h:form> <h:panelGrid columns="3"> <h:panelGrid columns="2"> <h:outputLabel value="#{msg.left}"></h:outputLabel> <h:outputLabel id="left" value="#{cardController.card.left}"></h:outputLabel> <h:outputLabel value="#{msg.right}"></h:outputLabel> <h:outputLabel id="right" value="#{cardController.card.right}"> </h:outputLabel> <h:outputLabel value="#{msg.result}"></h:outputLabel> <h:inputText id="result" value="#{cardController.result}"></h:inputText> </h:panelGrid> </h:panelGrid> <h:commandButton action="#{cardController.checkResult}" value="#{msg.show}"></h:commandButton> <h:commandButton action="#{cardController.next}" value="#{msg.next}" type="submit"></h:commandButton> <h:messages layout="table"></h:messages> <h:panelGroup binding="#{cardController.resultPanel}" rendered="false"> <h:message for="result"></h:message> </h:panelGroup> </h:form> </f:view> </body> </html>
From the previously examples you should be able to read most of the fields. What is new is that is use now the binding. Binding allows to bind certain UIControls to a managed bean. This way be bind the panel for the result to the controller. The controller can then set the rendered attribute of this UIControl depending on the user settings.
Lets now create a JSF application for maintaining a Todo list. The main new thing we will cover is the handling of tables in JSF. These tables will be created based on a Java collection from the managed bean.
Create a new package de.vogella.jsf.todo.model and the following class.
package de.vogella.jsf.todo.model; import java.util.Calendar; public class Todo { private String id; private String title; private String description; private int priority; private Calendar dueDate; public Todo(String title, String description, int priority) { this.title = title; this.description = description; this.priority = priority; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public int getPriority() { return priority; } public void setPriority(int priority) { this.priority = priority; } public Calendar getDueDate() { return dueDate; } public void setDueDate(Calendar dueDate) { this.dueDate = dueDate; } }
Create the package de.vogella.jsf.todo.controller and the following class TodoController.
package de.vogella.jsf.todo.controller; import java.util.ArrayList; import java.util.List; import javax.faces.component.UICommand; import javax.faces.component.UIForm; import javax.faces.event.ActionEvent; import javax.faces.model.SelectItem; import de.vogella.jsf.todo.model.Todo; public class TodoController { // domain model related variables private List<Todo> todos; private Todo todo; // JavaServerFaces related variables private UIForm form; private UIForm tableForm; private UICommand addCommand; public TodoController() { todos = new ArrayList<Todo>(); todos.add(new Todo("Learn JFS", "Finish this article", 1)); todos.add(new Todo("Stop drinking to much coffee", "Coffee is evil!", 3)); } public String addNew() { todo = new Todo("", "", 3); form.setRendered(true); addCommand.setRendered(false); return null; } public String save() { todos.add(todo); form.setRendered(false); addCommand.setRendered(true); return null; } public String cancel() { todo = null; form.setRendered(false); addCommand.setRendered(true); return null; } public String delete() { todos.remove(todo); return null; } public void displayTable(ActionEvent event) { if (event.getComponent().getId().equalsIgnoreCase("hide")) { tableForm.setRendered(false); } else { tableForm.setRendered(true); } } public List<SelectItem> getPriorities() { List<SelectItem> list = new ArrayList<SelectItem>(); list.add(new SelectItem(1, "High")); list.add(new SelectItem(2, "Medium")); list.add(new SelectItem(3, "Low")); return list; } public List<Todo> getTodos() { return todos; } public void setTodos(List<Todo> todos) { this.todos = todos; } public Todo getTodo() { return todo; } public void setTodo(Todo todo) { this.todo = todo; } public UIForm getForm() { return form; } public void setForm(UIForm form) { this.form = form; } public UICommand getAddCommand() { return addCommand; } public void setAddCommand(UICommand addCommand) { this.addCommand = addCommand; } public UIForm getTableForm() { return tableForm; } public void setTableForm(UIForm tableForm) { this.tableForm = tableForm; } }
Double-click on faces-config.xml and select the tab "ManagedBeans". Register the TodoController.
In your folder WebContent create a folder css. Create a file mystyle.css with the following content.
table.todo { border: 1px solid #CCCCCC; } table.todo th { background: #EFEFEF none repeat scroll 0 0; border-top: 1px solid #CCCCCC; font-size: small; padding-left: 5px; padding-right: 4px; padding-top: 4px; vertical-align: top; } table td:first-child { font-weight:bold; } table .first { width: 120px; } table .rest { width: 400px; } table.todo { border-top: 1px solid #CCCCCC; font-size: small; padding-left: 5px; padding-right: 4px; padding-top: 4px; vertical-align: top; }
Create a new JSP page "Todo.jsp" and change the code to the following:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ taglib prefix="f" uri="http://java.sun.com/jsf/core"%> <%@ taglib prefix="h" uri="http://java.sun.com/jsf/html"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Insert title here</title> <LINK href="<%=request.getContextPath()%>/css/mystyle.css" rel="stylesheet" type="text/css"> </head> <body> <h3>Todo list</h3> <f:view> <h:messages layout="table"></h:messages> <%-- Possibility to start a new Todo --%> <h:form> <h:commandLink binding="#{todoController.addCommand}" accesskey="n" action="#{todoController.addNew}" value="Add new Todo"> </h:commandLink> </h:form> <h:form binding="#{todoController.form}" rendered="false" styleClass="todo"> <h:panelGrid columns="2"> <h:outputText value="Title"></h:outputText> <h:inputText value="#{todoController.todo.title}" required="true" requiredMessage="Title is required"> </h:inputText> <h:outputText value="Description"></h:outputText> <h:inputTextarea value="#{todoController.todo.description}" cols="40" rows="4"></h:inputTextarea> <h:outputText value="Prio"></h:outputText> <h:selectOneMenu validatorMessage="required" value="#{todoController.todo.priority}"> <f:selectItems value="#{todoController.priorities}" /> </h:selectOneMenu> </h:panelGrid> <h:panelGroup> <h:commandButton action="#{todoController.save}" value="Save" accesskey="s"> </h:commandButton> <h:commandButton action="#{todoController.cancel}" value="Cancel" accesskey="c" immediate="true"> </h:commandButton> </h:panelGroup> </h:form> <%-- These buttons allow to show and hide the table --%> <h:form> <h:panelGrid columns="2"> <h:commandLink id="hide" actionListener="#{todoController.displayTable}" value="Hide Table"> </h:commandLink> <h:commandLink id="show" actionListener="#{todoController.displayTable}" value="Show Table"> </h:commandLink> </h:panelGrid> </h:form> <%-- Here we start the form for the data table --%> <h:form binding="#{todoController.tableForm}"> <%-- Here we start the data table --%> <h:dataTable value="#{todoController.todos}" var="todo" styleClass="todo" headerClass="todoheader" columnClasses="first, rest"> <h:column> <%-- Via this facet we define the table header (column 1) --%> <f:facet name="header"> <h:column> <h:outputText value="Prio"></h:outputText> </h:column> </f:facet> <h:outputText value="#{todo.priority}"></h:outputText> </h:column> <h:column> <%-- Via this facet we define the table header (column 2) --%> <f:facet name="header"> <h:column> <h:outputText value="Title"></h:outputText> </h:column> </f:facet> <h:outputText value="#{todo.title}"></h:outputText> </h:column> <h:column> <%-- Via this facet we define the table header (column 3) --%> <f:facet name="header"> <h:column> <h:outputText value="Description"></h:outputText> </h:column> </f:facet> <h:outputText value="#{todo.description}"></h:outputText> </h:column> <h:column> <%-- Via this facet we define the table header (column 4) --%> <f:facet name="header"> <h:column> <h:outputText value="Actions"></h:outputText> </h:column> </f:facet> <h:panelGrid columns="2"> <h:commandLink value="delete" action="#{todoController.delete}"> <f:setPropertyActionListener target="#{todoController.todo}" value="#{todo}" /> </h:commandLink> </h:panelGrid> </h:column> </h:dataTable> </h:form> </f:view> </body> </html>
You have added a actionListener. This can call a method which can receive an object of type ActionEvent. actionListeners are nice if you want to use the same method with different parameters.
We also use selectOneMenu which allows to select a value from a pre-defined list.
The main new thing here is h:datatable tag. This tag defines a table. value can get a list as a parameter and var define the variable which will be used to create each row. This is very similar to the foreach loop.
The other new element is the setPropertyActionListener. This allow you to listener to changes for this link, e.g. a mouse click. This copies the current selected row into the field todo. The method delete from the controller will then remove this elements from the list.
No comments:
Post a Comment