I am using primefaces on the frontend and populating a selectOneList using an arraylist in my backing bean
I want to have the array list separated by new lines to make some logical separations
How can I add an element to an ArrayList that will be rendered as an empty line ?
The following code will help you to achieve the functionality you want, that is to enter some empty line in <p:selectOneListBox>. Now I am not sure if it is a feature of this component that to squeeze out the empty string. So "" will not work.
This is a sample managed bean:
package app.so.dev.web.controller;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import app.so.dev.web.model.Student;
#ManagedBean(name = "so15350373")
#ViewScoped
public class SO15350373 implements Serializable{
private static final long serialVersionUID = 2190171095461884759L;
private List<Student> students;
private int selected;
#PostConstruct
public void init() {
students = new ArrayList<Student>();
students.add(new Student(1, "Student 1"));
students.add(new Student(2, " "));
students.add(new Student(3, "Student 3"));
students.add(new Student(4, " "));
students.add(new Student(5, "Student 5"));
students.add(new Student(6, "Student 6"));
}
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
public int getSelected() {
return selected;
}
public void setSelectedStudent(int selected) {
this.selected = selected;
}
}
The Student is a simple POJO having two field id and name. For the sake of brevity, I am not showing this class :P.
And this is the xhtml:
<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core" xmlns:p="http://primefaces.org/ui" template="/WEB-INF/templates/globalTemplate.xhtml">
<ui:define name="title">15350373</ui:define>
<ui:define name="content">
<h:form>
<p:selectOneListbox value="#{so15350373.selected}" id="list">
<f:selectItems value="#{so15350373.students}" var="student" itemLabel="#{student.name}" itemValue="#{student.id}" />
</p:selectOneListbox>
</h:form>
</ui:define>
</ui:composition>
Related
I'm building a simple e-shop with JSF. There is a page with a list of all the products (product-list.xhtml) and then a detail page for each product (product.xhtml). product-list.xhtml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
</h:head>
<h:body>
<f:view>
<h:outputText value="Number of items in the cart: #{shoppingCart.numberOfSelectedProducts}"/>
<h:link value="Cart" outcome="cart.xhtml"/>
<h:dataTable value="#{productController.products}" var="p">
<h:column>
#{p.name}
<h:commandLink action="product.xhtml" value="Detail">
<f:actionListener target="#{product.id}" value="#{p.id}"/>
</h:commandLink>
</h:column>
<h:column>
</h:column>
</h:dataTable>
</f:view>
</h:body>
</html>
then the product.xhtml looks following:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<head></head>
<!--f:metadata>
<f:event type="preRenderView" listener="#{shoppingCart.loadSelectedProduct(param.id)}"/>
</f:metadata -->
<body>
<f:view>
<h:graphicImage value="resources/images/img.jpg"/>
<h:outputLabel value="The value of shoppingCart.selectedProduct is: #{shoppingCart.selectedProduct.id}"/>
</f:view>
</body>
</html>
When I run the App in the debugger, the value set correctly to the selectedProduct attribute, but then it's not accessible in the page - the output of product.xhtml looks following (if the chosen product has ID 4):
The value of shoppingCart.selectedProduct is:
Products on the main page are loaded from RequestScoped bean's (productController) property. The ShoppingCart is then a SessionScoped bean with injected productController instance.
package main.java;
import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
import java.io.Serializable;
import java.util.List;
#Named
#SessionScoped
public class ShoppingCart implements Serializable {
private List<Product> selectedProducts;
private int numberOfSelectedProducts;
private Product selectedProduct;
public Product getSelectedProduct() {
return selectedProduct;
}
public void setSelectedProduct(Product selectedProduct) {
this.selectedProduct = selectedProduct;
}
public List<Product> getSelectedProducts() {
return selectedProducts;
}
public void setSelectedProducts(List<Product> selectedProducts) {
this.selectedProducts = selectedProducts;
}
public int getNumberOfSelectedProducts() {
return numberOfSelectedProducts;
}
public void setNumberOfSelectedProducts(int numberOfSelectedProducts) {
this.numberOfSelectedProducts = numberOfSelectedProducts;
}
}
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
#ViewScoped
#Named
public class ProductController implements Serializable {
private List<Product> products;
#Inject
private ShoppingCart shoppingCart;
public void setProducts(List<Product> products) {
this.products = products;
}
public ShoppingCart getShoppingCart() {
return shoppingCart;
}
public void setShoppingCart(ShoppingCart shoppingCart) {
this.shoppingCart = shoppingCart;
}
public List<Product> getProducts() {
return products;
}
//v teto metode se pote budou nacitat produkty z DB
#PostConstruct
public void loadItems(){
products = new ArrayList<>();
products.add(new Product(1, "Nazev1", 11, "Popis1"));
products.add(new Product(2, "Nazev2", 22, "Popis2"));
products.add(new Product(3, "Nazev3", 33, "Popis3"));
products.add(new Product(4, "Nazev4", 44, "Popis4"));
products.add(new Product(5, "Nazev5", 55, "Popis5"));
products.add(new Product(6, "Nazev6", 66, "Popis6"));
products.add(new Product(7, "Nazev7", 77, "Popis7"));
}
public Product findById(final int id) {
List<Product> product = products.stream().filter(p -> p.getId() == id).limit(1).collect(Collectors.toList());
return product.get(0);
}
}
package main.java;
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import java.io.Serializable;
#Named
#ViewScoped
public class Product implements Serializable {
private int id;
private String name;
private double price;
private String description;
public Product(int id, String name, double price, String description) {
this.id = id;
this.name = name;
this.price = price;
this.description = description;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
#PostConstruct
public void init(){
System.out.println("Product created");
}
}
If you add a #PostConstruct method to your #SessionScoped bean like this:
#PostConstruct
public void init() {
System.out.println("ShoppingCart.init()");
}
You will notice that your bean is instantiated several times per request - at least one time for each #{shoppengCart...} expression. This is because using the deprecated annotation #javax.faces.bean.SessionScoped within CDI environment behaves like #NoneScoped.
You should instead use javax.enterprise.context.SessionScoped for your shopping cart.
For display of a selected product I would suggest to add a #ViewScoped bean (javax.faces.view.ViewScoped, not javax.faces.bean.ViewScoped) or even #RequestScope if you don't do AJAX stuff. (javax.enterprise.context.RequestScoped, not javax.faces.bean.RequestScoped).
Which IDE do you use - didn't it notify you that the sope used by you is deprecated?
For further reading see: How to choose the right bean scope?
In addition to the scope problem, you should probably use f:viewParam instead of f:event to inject the URL query parameter into the bean:
Instead of:
<f:metadata>
<f:event type="preRenderView" listener="#{shoppingCart.loadSelectedProduct(param.id)}"/>
</f:metadata>
do this:
<f:metadata>
<f:viewParam name="id" value="#{productDisplayBean.selectedProductId}"/>
</f:metadata>
This question already has an answer here:
How to send form input values and invoke a method in JSF bean
(1 answer)
Closed 7 years ago.
I have a inputText that i want to retrieve the value from but it looks like it`s not calling the setter method in my bean class. This is my bean class:
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "employees")
public class Employee implements Serializable{
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private int id;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
public Employee() {}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
I am trying to get the firstName string in my ManagedBean class but it returns null. This is my controller class:
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import com.myapp.model.Employee;
#ManagedBean(name = "controller")
#SessionScoped
public class EmployeeController {
private Employee employee;
#PostConstruct
public void init()
{
employee = new Employee();
}
public Employee getEmployee()
{
return employee;
}
public void showInfo()
{
System.out.println("first name: " + employee.getFirstName());
}
}
This is my .xhtml file
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<h:body>
<h2>Input:</h2>
<br/>
<p:panelGrid columns="2">
<p:outputLabel value = "First Name:" />
<p:inputText value = "#{controller.employee.firstName}" />
</p:panelGrid>
<br/>
<h:form>
<p:commandButton value="Save Edits" action="#{controller.showInfo()}"> </p:commandButton>
</h:form>
</h:body>
</html>
What am i doing wrong?
The <p:inputText> component must be part of the <h:form> component that is being submitted:
<h:form>
<h2>Input:</h2>
<br/>
<p:panelGrid columns="2">
<p:outputLabel value = "First Name:" />
<p:inputText value = "#{controller.employee.firstName}" />
</p:panelGrid>
<br/>
<p:commandButton value="Save Edits" action="#{controller.showInfo()}" />
</h:form>
I'm new to PrimeFaces tried out an example in PrimeFaces datatable
public class Datatable {
private String fname;
private String lname;
private int age;
public Datatable(String fname, String lname, int age) {
// TODO Auto-generated constructor stub
}
public String getFname() {
return fname;
}
public void setFname(String fname) {
this.fname = fname;
}
public String getLname() {
return lname;
}
public void setLname(String lname) {
this.lname = lname;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Here in the class I have declared what are the fields in the data table
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
#ManagedBean(name="solodat")
#RequestScoped
public class Solodata implements Serializable{
private static final long serialVersionUID = 1L;
public Solodata() {}
private List<Datatable>addeta;
public List<Datatable> getAddeta() {
return addeta;
}
public void setAddeta(List<Datatable> addeta) {
this.addeta = addeta;
}
#PostConstruct
public void init() {
List<Datatable> addeta=new ArrayList<Datatable>();
addeta.add( new Datatable("man","eater",14));
addeta.add( new Datatable("solo","world",28));
addeta.add( new Datatable("antan","evanious",20));
addeta.add( new Datatable("hi","daa",29));
addeta.add( new Datatable("thallu","vandi",30));
addeta.add( new Datatable("prime","faces",1000));
addeta.add( new Datatable("crime","shit",1412));
addeta.add( new Datatable("shit","head",18));
}
}
Here in list I have get that values:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://www.java.com/jsf/html"
xmlns:f="http://www.java.com/jsf/core"
xmlns:p="http://www.primefaces.org/ui">
<h:head>
<title>DATA TABLES DEMO</title>
</h:head>
<h:body>
<h:form>
<h1>output values</h1>
<p:dataTable var="sol" value="#{solodat.addeta}" >
<p:column headerText="LASTNAME">
<h:outputText value="#{sol.lname}"/>
</p:column>
<p:column headerText="age">
<h:outputText value="#{sol.age}"/>
</p:column>
<p:column headerText="first">
<h:outputText value="#{sol.fname}"/>
</p:column>
</p:dataTable>
</h:form>
</h:body>
</html>
This is the xhtml page to get the bean values by data table but JSF is showing an empty page. Any help would be appreciated.
Try this and let us know (using CDI, removing the useless constructor, and initializing addeta properly)
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.inject.Named;
import javax.enterprise.context.RequestScoped;
#Named("solodat")
#RequestScoped
public class Solodata {
private List<Datatable> addeta;
public List<Datatable> getAddeta() {
return addeta;
}
public void setAddeta(List<Datatable> addeta) {
this.addeta = addeta;
}
#PostConstruct
public void init() {
addeta=new ArrayList<Datatable>();
addeta.add( new Datatable("man","eater",14));
addeta.add( new Datatable("solo","world",28));
addeta.add( new Datatable("antan","evanious",20));
addeta.add( new Datatable("hi","daa",29));
addeta.add( new Datatable("thallu","vandi",30));
addeta.add( new Datatable("prime","faces",1000));
addeta.add( new Datatable("crime","shit",1412));
addeta.add( new Datatable("shit","head",18));
}
}
And replace the facelet with this one (I changed the first lines)
<!DOCTYPE html>
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>DATA TABLES DEMO</title>
</h:head>
<h:body>
<h:form>
<h1>output values</h1>
<p:dataTable var="sol" value="#{solodat.addeta}" >
<p:column headerText="LASTNAME">
<h:outputText value="#{sol.lname}"/>
</p:column>
<p:column headerText="age">
<h:outputText value="#{sol.age}"/>
</p:column>
<p:column headerText="first">
<h:outputText value="#{sol.fname}"/>
</p:column>
</p:dataTable>
</h:form>
</h:body>
</html>
Now make sure you have placed Primefaces library at the right place, and that the app is being deployed on a running server without errors.
Edit: The reason you don't have data , is due to Datatable's constructor, which is incomplete.
Replace
public Datatable(String fname, String lname, int age) {
// TODO Auto-generated constructor stub
}
by
public Datatable(String fname, String lname, int age) {
this.fname = fname;
this.lname = lname;
this.age = age;
}
Small mistake: You are initializing a new local variable in init().
List<Datatable> addeta = new ArrayList<Datatable>();
Change it to:
this.addeta = new ArrayList<Datatable>();
You should use <!DOCTYPE html> instead of
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
and also change your are initializing as noone answer.
See also : Wrong doctype when one is specified in composite view
Let's say I have a list of all the days in a month and I want to print it as a calendar. I want a week on each line and then a row break
in my example below, I will get a day on each row, like this:
Which is the best way to get 7 days on each row like this in JSF?
Example code:
View:
<h:dataTable value="#{myController.dayList}" var="day">
<h:column>
<h:outputText value="#{day}"/>
</h:column>
</h:dataTable>
Backbean:
#ManagedBean(name = "myController")
#SessionScoped
public class MyController {
private List <int> dayList;
public MyController()
{
dayList = getAllDaysInMonth();
}
public List <int> getAllDaysInMonth()
{
.....
}
public List <int> getDayList()
{
return dayList;
}
public void setDayList(List <int> dayList)
{
this.dayList = dayList;
}
}
if you would like to use Primefaces in your Project, you could do it in this way.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<body>
<p:dataGrid value="#{myController.dayList}" var="day" columns="7">
<p:panel style="text-align: center; background-color: skyblue; width: 100px; height: 100px;">
Day ${day}
</p:panel>
</p:dataGrid>
</body>
</html>
The Controller class
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
#Named(value = "myController")
#SessionScoped
public class MyController implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
List<Integer> dayList = new ArrayList<>();
public MyController() {
}
#PostConstruct
public void init() {
for(int i = 1; i <= 31; i++) {
dayList.add(new Integer(i));
}
}
public List<Integer> getDayList() {
return dayList;
}
public void setDayList(List<Integer> dayList) {
this.dayList = dayList;
}
}
Looks not very nice, but does what you need.
Patrick
I am following this example: http://mkblog.exadel.com/2008/11/richfaces-built-in-sorting/
it its said that arrows should appear beside the header and the user can click it to sort.
But I cannot get the arrow appear. You help appreciated.
The code I use:
newwonder.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:rich="http://richfaces.org/rich">
<h:head>
<title>Requirement Workflow</title>
</h:head>
<h:body>
<rich:dataTable value="#{newWondersBean.sevenNewWonders}" var="wonder">
<rich:column sortBy="#{wonder.name}">
<f:facet name="header">Name</f:facet>
<h:outputText value="#{wonder.name}" />
</rich:column>
<rich:column sortBy="#{wonder.location}">
<f:facet name="header">Location</f:facet>
<h:outputText value="#{wonder.location}" />
</rich:column>
<rich:column>
<f:facet name="header">Image</f:facet>
<h:graphicImage url="#{wonder.imageUrl}" />
</rich:column>
</rich:dataTable>
</h:body>
</html>
NewWondersBean.java
package wonder;
import java.util.ArrayList;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#ManagedBean
#ViewScoped
public class NewWondersBean {
private ArrayList <Wonder> sevenNewWonders = new ArrayList <Wonder>();
#PostConstruct
public void init () {
sevenNewWonders = new ArrayList <Wonder>();
sevenNewWonders.add(new Wonder("Chichen Itza", "Mexico", "http://upload.wikimedia.org/wikipedia/commons/thumb/7/7a/Chichen-Itza-Castillo-Seen-From-East.JPG/90px-Chichen-Itza-Castillo-Seen-From-East.JPG"));
sevenNewWonders.add(new Wonder("Christ the Redeemer", "Brazil", "http://upload.wikimedia.org/wikipedia/commons/thumb/5/50/CorcovadofotoRJ.jpg/90px-CorcovadofotoRJ.jpg"));
sevenNewWonders.add(new Wonder("Colosseum", "Italy", "http://upload.wikimedia.org/wikipedia/commons/thumb/5/53/Colosseum_in_Rome%2C_Italy_-_April_2007.jpg/90px-Colosseum_in_Rome%2C_Italy_-_April_2007.jpg"));
sevenNewWonders.add(new Wonder("Great Wall of China", "China", "http://upload.wikimedia.org/wikipedia/commons/thumb/1/16/GreatWallNearBeijingWinter.jpg/90px-GreatWallNearBeijingWinter.jpg"));
sevenNewWonders.add(new Wonder("Machu Picchu", "Peru", "http://upload.wikimedia.org/wikipedia/commons/thumb/1/13/Before_Machu_Picchu.jpg/90px-Before_Machu_Picchu.jpg"));
sevenNewWonders.add(new Wonder("Petra", "Jordan", "http://upload.wikimedia.org/wikipedia/commons/thumb/0/06/PetraMonastery.JPG/90px-PetraMonastery.JPG"));
sevenNewWonders.add(new Wonder("Taj Mahal", "India", "http://upload.wikimedia.org/wikipedia/commons/thumb/c/c8/Taj_Mahal_in_March_2004.jpg/90px-Taj_Mahal_in_March_2004.jpg"));
}
public ArrayList <Wonder> getSevenNewWonders() {
return sevenNewWonders;
}
}
Wonder.java
package wonder;
public class Wonder {
public Wonder(String string, String string2, String string3) {
// TODO Auto-generated constructor stub
this.name = string;
this.location = string2;
this.imageUrl = string3;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setLocation(String location) {
this.location = location;
}
public String getLocation() {
return location;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
public String getImageUrl() {
return imageUrl;
}
private String name;
private String location;
private String imageUrl;
}
As I understand it sorting has changed with Richfaces 4.
You will need to have a Map <String, SortOrder> and you will need to add an attribute to your rich:column where sortOrders is the above Map and vendor is the key for a given column.
sortOrder="#{bean.sortsOrders['vendor']}">
After that sorting is pretty much auto-magic, but the icon's are also not in Richfaces 4 so you will manually have to add those based on the value of the SortOrder enum for each column.
I think it is a pain and a step backwards from 3.x but that is what is needed to get sorting working.
You can always check out the RichFaces Showcase site for more info
http://showcase.richfaces.org/richfaces/component-sample.jsf?demo=extendedDataTable&sample=edt-sorting&skin=blueSky
EDIT: (Jan 2013)
With the upcoming RichFaces 4.3 Automatic Sorting is being added back in, and will include the arrows and what not. The link above should still have a good option for that.
EDIT: (Sep 2013)
RF is now in version 4.3.4 and the automatic sorting is still not back. It only works on the rich:extendedDataTable but not the rich:dataTable