I'm doing a hotel room reservation page with Java Server Faces. I have a base template that contains a hotel search, with an index template that is where I show the results. I'm loading all the hotels on the front page, like cover. And I show only 9 hotels so that they do not overflow the hotels of the DIV:
Ok, I have only 10 hotels registered in the database in total .... I want to make a pagination for my page where I display only 9 hotels per page .... the result of having this, as I have 10 hotels in the database, it would be that on the next page I should only see 1 single hotel.
This is my index page:
<?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:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<f:metadata>
<f:viewAction action="#{buscador.cargarPortada()}"/>
</f:metadata>
<body>
<ui:composition template="./templates/base.xhtml">
<ui:define name="content">
<h:form id="form2">
<h:dataTable value="#{buscador.display}" var="res">
<h:column>
<h:outputLabel value="#{res.a}" escape="false"/>
</h:column>
<h:column>
<h:outputLabel value="#{res.b}" escape="false"/>
</h:column>
<h:column>
<h:outputLabel value="#{res.c}" escape="false"/>
</h:column>
</h:dataTable>
</h:form>
</ui:define>
</ui:composition>
</body>
I am using a dataTable to display the results. I have two classes: a class that handles rows of the dataTable, and another class that constructs the display boxes of each hotel
With this class I construct each box in the table:
package Clases;
public class ResultElement {
private String nombre, imagen, localidad;
private String display;
public ResultElement(String nombre, String imagen, String localidad){
this.nombre=nombre;
this.imagen=imagen;
this.localidad=localidad;
display = "<div id='HotP'><b><p style=\"text-align:center;font-
style:italic;color:red\">" + nombre + "</p></b>"
+"<img src=\"resources/images/" + imagen +
"\"style=\"width:160px;height:70px;border:1px solid gray;\"/><br>"
+ "<span style=\"color: darkblue;text-align: center;\">"+
localidad +"</span></div>";
}
/**
* #return the nombre
*/
public String getNombre() {
return nombre;
}
/**
* #param nombre the nombre to set
*/
public void setNombre(String nombre) {
this.nombre = nombre;
}
/**
* #return the imagen
*/
public String getImagen() {
return imagen;
}
/**
* #param imagen the imagen to set
*/
public void setImagen(String imagen) {
this.imagen = imagen;
}
/**
* #return the localidad
*/
public String getLocalidad() {
return localidad;
}
/**
* #param localidad the localidad to set
*/
public void setLocalidad(String localidad) {
this.localidad = localidad;
}
/**
* #return the display
*/
public String getDisplay() {
return display;
}
/**
* #param display the display to set
*/
public void setDisplay(String display) {
this.display = display;
}
}
With this class I manage the rows of the table. I show 3 results per row:
package Clases;
public class DisplayResult {
private String A, B, C;
public DisplayResult(String a, String b, String c){
A = a;
B = b;
C = c;
}
/**
* #return the A
*/
public String getA() {
return A;
}
/**
* #param A the A to set
*/
public void setA(String A) {
this.A = A;
}
/**
* #return the B
*/
public String getB() {
return B;
}
/**
* #param B the B to set
*/
public void setB(String B) {
this.B = B;
}
/**
* #return the C
*/
public String getC() {
return C;
}
/**
* #param C the C to set
*/
public void setC(String C) {
this.C = C;
}
}
This class is where I will load the cover of the page and perform searches:
package Beans;
import Clases.DisplayResult;
import Clases.ResultElement;
import javax.inject.Named;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import java.sql.ResultSet;
import Database.GestorDB;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* #author SEMINARIO
*/
#Named(value = "portada")
#ManagedBean
#ViewScoped
public class Buscador {
private String fechaE, fechaS, localidad;
private int personas;
private static ArrayList<DisplayResult> displayList;
private ArrayList<String> aux = new ArrayList<>();
public Buscador() {
displayList = new ArrayList<>();
}
public String getFechaE() {
return fechaE;
}
public void setFechaE(String fechaE) {
this.fechaE = fechaE;
}
public String getFechaS() {
return fechaS;
}
public void setFechaS(String fechaS) {
this.fechaS = fechaS;
}
public String getLocalidad() {
return localidad;
}
public void setLocalidad(String localidad) {
this.localidad = localidad;
}
public int getPersonas() {
return personas;
}
public void setPersonas(int personas) {
this.personas = personas;
}
public ArrayList<DisplayResult> getDisplay() {
return displayList;
}
public void setDisplay(ArrayList<DisplayResult> listaResultado) {
Buscador.displayList = listaResultado;
}
public void agregarResultado(DisplayResult resultado){
Buscador.displayList.add(resultado);
}
public void limpiarResultados(){
Buscador.displayList.clear();
aux.clear();
}
public void calibrar(){
do{
if(aux.size()%3 != 0)
aux.add("");
}while(aux.size()%3 != 0);
}
public void cargarPortada(){
try{
ResultSet rs = GestorDB.getConsulta("SELECT HOTELES.NOMBRE AS A, HOTELES.IMGHOTEL, LOCALIDADES.NOMBRE AS B FROM HOTELES INNER JOIN LOCALIDADES"
+ " ON LOCALIDADES.IDLOCALIDADES = HOTELES.LOCALIDADES_IDLOCALIDADES FETCH FIRST 9 ROWS ONLY");
while(rs.next()){
ResultElement res = new ResultElement(rs.getString("A"), rs.getString("IMGHOTEL"),rs.getString("B"));
aux.add(res.getDisplay());
}
calibrar();
for(int i = 0; i < aux.size(); i+=3){
DisplayResult obj = new DisplayResult(aux.get(i),aux.get(i+1),aux.get(i+2));
displayList.add(obj);
}
} catch (SQLException ex) {
Logger.getLogger(Buscador.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
I thought of controlling the pagination of my page with my arrayList but the truth is that I do not know how to place it in the dataTable ...
Is there an easy and practical way to do it?
Native JSF does not have any support/have components for pagination.
You could go for a Component library like Primefaces, which has a pagination components like DataGrid .
Related
Given the component: https://www.primefaces.org/showcase/ui/input/oneMenu.xhtml
Full source for my test is at: https://github.com/dannymk/PrimefacesTest
Can't get the component to work with an Object using a converter. Not sure how to solve this one.
package org.primefaces.test;
import java.io.Serializable;
public class Player implements Serializable {
private Integer id;
private String name;
Player(Integer id, String name){
this.id = id;
this.name = name;
}
/**
* #return the id
*/
public Integer getId() {
return id;
}
/**
* #param id the id to set
*/
public void setId(Integer id) {
this.id = id;
}
/**
* #return the name
*/
public String getName() {
return name;
}
/**
* #param name the name to set
*/
public void setName(String name) {
this.name = name;
}
}
package org.primefaces.test;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
*
* #author Daniel Maldonado
*/
public class PlayerService implements Serializable{
private List<Player> available = new ArrayList<>();
public PlayerService() {
available.add(new Player(1, "One"));
available.add(new Player(2, "Two"));
available.add(new Player(3, "Three"));
available.add(new Player(4, "Four"));
available.add(new Player(5, "Five"));
}
/**
* #return the available
*/
public List<Player> getAvailable() {
return available;
}
/**
* #param available the available to set
*/
public void setAvailable(List<Player> available) {
this.available = available;
}
}
package org.primefaces.test;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.inject.Inject;
import javax.inject.Named;
/**
*
* #author Daniel Maldonado
*/
#Named
#FacesConverter(value = "playerConverter", managed = true)
public class PlayerConverter implements Converter<Player> {
#Inject
PlayerService service;
#Override
public Player getAsObject(FacesContext context, UIComponent component, String value) {
if (value != null && value.trim().length() > 0) {
Player found = service.getAvailable().stream()
.filter(player -> player.getName().equals(value))
.findAny()
.orElse(null);
return found;
}
return null;
}
#Override
public String getAsString(FacesContext context, UIComponent component, Player o) {
if (o != null){
return o.getName();
}
return null;
}
}
package org.primefaces.test;
import java.io.Serializable;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;
import lombok.Data;
#Data
#Named
#ViewScoped
public class TestView implements Serializable {
private String hello;
private List<Player> available;
private Player selected;
#Inject
PlayerService service;
#PostConstruct
public void init() {
setHello("Welcome to PrimeFaces!!!");
this.available = service.getAvailable();
}
/**
* #return the available
*/
public List<Player> getAvailable() {
return available;
}
/**
* #param available the available to set
*/
public void setAvailable(List<Player> available) {
this.available = available;
}
/**
* #return the selected
*/
public Player getSelected() {
return selected;
}
/**
* #param selected the selected to set
*/
public void setSelected(Player selected) {
this.selected = selected;
}
/**
* #return the hello
*/
public String getHello() {
return hello;
}
/**
* #param hello the hello to set
*/
public void setHello(String hello) {
this.hello = hello;
}
}
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
<title>PrimeFaces Test - SelectOneMenu</title>
<h:outputScript name="test.js" />
</h:head>
<h:body>
<h1>#{testView.hello}</h1>
<h:form id="frmTest">
<p:panelGrid id="playerPanel" columns="2">
<p:outputLabel value="Selected player: #{testView.selected.name}" />
<p:selectOneMenu id="playerContainer" value="#{testView.selected}" var="p" converter="playerConverter" >
<f:selectItem itemLabel="Select One" itemValue="" />
<f:selectItems value="#{testView.available}" var="actual" itemLabel="#{actual.name}" itemValue="#{actual}" />
<p:column>
#{p.name}
</p:column>
<p:ajax event="valueChange" update="playerPanel" />
</p:selectOneMenu>
</p:panelGrid>
</h:form>
</h:body>
</html>
I get errors like:
java.lang.ClassCastException: java.lang.String cannot be cast to org.primefaces.test.Player
at org.primefaces.test.PlayerConverter.getAsString(PlayerConverter.java:38)
It does not seem to matter what I change and believe me I have tried plenty of implementations of the converter and in the view using "#{palyerConverter}" instead of "playerConverter" and still can't get it to work.
Your problem is at this line:
<f:selectItem itemLabel="Select One" itemValue="" />
Currently you are passing an empty string as the itemValue, which is not expected by your converter. Either use itemValue="#{null}" or totally remove the itemValue from the no select option.
See also:
Best way to add a "nothing selected" option to a selectOneMenu in JSF
Finally got it to work with just a few changes thanks to #Jasper de Vries:
<?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:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
<title>PrimeFaces Test - SelectOneMenu</title>
<h:outputScript name="test.js" />
</h:head>
<h:body>
<h1>#{testView.hello}</h1>
<h:form id="frmTest">
<p:panelGrid id="playerPanel" columns="2">
<p:outputLabel value="Selected player: #{testView.selected.name}" />
<p:selectOneMenu id="playerContainer" value="#{testView.selected}" var="p" converter="playerConverter">
<f:selectItems value="#{testView.available}" var="actual" itemLabel="#{actual.name}" itemValue="#{actual}" />
<p:column>
#{p.name}
</p:column>
<p:ajax event="valueChange" update="playerPanel" />
</p:selectOneMenu>
</p:panelGrid>
</h:form>
</h:body>
</html>
and specially don't forget to implement the EQUALS method in the Object that is "listed":
package org.primefaces.test;
import java.io.Serializable;
import java.util.Objects;
public class Player implements Serializable {
private Integer id;
private String name;
Player(Integer id, String name){
this.id = id;
this.name = name;
}
#Override
public boolean equals(Object obj) {
if(obj == null)
return false;
if(!(obj instanceof Player))
return false;
Player compare = (Player) obj;
return Objects.equals(compare.getId(), this.getId());
}
#Override
public int hashCode() {
int hash = 1;
return hash * 31 + this.getName().hashCode();
}
/**
* #return the id
*/
public Integer getId() {
return id;
}
/**
* #param id the id to set
*/
public void setId(Integer id) {
this.id = id;
}
/**
* #return the name
*/
public String getName() {
return name;
}
/**
* #param name the name to set
*/
public void setName(String name) {
this.name = name;
}
}
I have to show multiple dynamic number of primefaces datatables with dynamic columns on single page. Everything works fine if number of columns in each dynamic datatable is same.
Wrong behaviour occurs when there are different number of columns in different tables. All the tables show as many columns as in the first table in the list.
Tested on:
Primefaces: 3.4 and 4.0
JSF 2.0
Here is the code demonstrating the problem:
EDIT: The following code is assigning different number of columns to different tables. The first table should have 8 columns, second should have 7 columns, and so on. But all the tables take up 8 columns; i.e. they take the number of columns from first table.
Expected Output: 5 datatables. First table having 8 columns, Second table 7 columns, Third table 6 columns, and so on. Expected Output Screenshot -- This is actually the output on pf 3.3
Actual Output: 5 tables, all having 8 columns. Data shown is correct. But empty extra columns are also being shown, which should not be shown. Actual Output Screenshot
test2.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:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<f:view contentType="text/html">
<h:head>
</h:head>
<h:body>
<h:form>
<ui:repeat value="#{tableBean.tables}" var="table">
<p:dataTable id="cars" var="car" value="#{table.carsSmall}"
style="font-size: 12px;'width: 70%;">
<p:columns value="#{table.columns}" var="column"
columnIndexVar="colIndex">
<f:facet name="header">
#{column.header}
</f:facet>
<h:outputText value="#{car[column.property]}"></h:outputText>
</p:columns>
</p:dataTable>
<br />
</ui:repeat>
</h:form>
</h:body>
</f:view>
</html>
TableBean.java:
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#ManagedBean(name = "tableBean")
#ViewScoped
public class TableBean implements Serializable
{
private static final long serialVersionUID = 1L;
private final static List<String> VALID_COLUMN_KEYS = Arrays.asList("model", "manufacturer", "year", "color");
private final static String[] colors;
private final static String[] manufacturers;
private String columnTemplate = "model manufacturer year";
static
{
colors = new String[10];
colors[0] = "Black";
colors[1] = "White";
colors[2] = "Green";
colors[3] = "Red";
colors[4] = "Blue";
colors[5] = "Orange";
colors[6] = "Silver";
colors[7] = "Yellow";
colors[8] = "Brown";
colors[9] = "Maroon";
manufacturers = new String[10];
manufacturers[0] = "Mercedes";
manufacturers[1] = "BMW";
manufacturers[2] = "Volvo";
manufacturers[3] = "Audi";
manufacturers[4] = "Renault";
manufacturers[5] = "Opel";
manufacturers[6] = "Volkswagen";
manufacturers[7] = "Chrysler";
manufacturers[8] = "Ferrari";
manufacturers[9] = "Ford";
}
private List<Car> carsSmall;
private List<ColumnModel> columns = new ArrayList<ColumnModel>();;
private List<TableBean> tables;
public List<TableBean> getTables()
{
if (tables == null)
{
tables = new ArrayList<TableBean>();
for (int i = 0; i < 5; i++)
{
TableBean t = new TableBean();
for (int j = 5; j > i; j--)
{
t.columnTemplate += " year";
t.createDynamicColumns();
}
tables.add(t);
}
}
return tables;
}
public TableBean()
{
carsSmall = new ArrayList<Car>();
populateRandomCars(carsSmall, 9);
createDynamicColumns();
}
private void populateRandomCars(List<Car> list, int size)
{
for (int i = 0; i < size; i++)
list.add(new Car(getRandomModel(), getRandomYear(), getRandomManufacturer(), getRandomColor()));
}
public List<Car> getCarsSmall()
{
return carsSmall;
}
private int getRandomYear()
{
return (int) (Math.random() * 50 + 1960);
}
private String getRandomColor()
{
return colors[(int) (Math.random() * 10)];
}
private String getRandomManufacturer()
{
return manufacturers[(int) (Math.random() * 10)];
}
private String getRandomModel()
{
return UUID.randomUUID().toString().substring(0, 8);
}
public List<ColumnModel> getColumns()
{
return columns;
}
public String[] getManufacturers()
{
return manufacturers;
}
public String[] getColors()
{
return colors;
}
static public class ColumnModel implements Serializable
{
private static final long serialVersionUID = 1L;
private String header;
private String property;
public ColumnModel(String header, String property)
{
this.header = header;
this.property = property;
}
public String getHeader()
{
return header;
}
public String getProperty()
{
return property;
}
#Override
public String toString()
{
return "[header=" + header + ", property=" + property + "]";
}
}
public void createDynamicColumns()
{
String[] columnKeys = columnTemplate.split(" ");
columns.clear();
for (String columnKey : columnKeys)
{
String key = columnKey.trim();
if (VALID_COLUMN_KEYS.contains(key))
{
columns.add(new ColumnModel(columnKey.toUpperCase(), columnKey));
}
}
}
}
Car.java:
import java.io.Serializable;
public class Car implements Serializable
{
private static final long serialVersionUID = 1L;
private String model;
private int year;
private String manufacturer;
private String color;
public Car(String model, int year, String manufacturer, String color)
{
super();
this.model = model;
this.year = year;
this.manufacturer = manufacturer;
this.color = color;
}
public String getModel()
{
return model;
}
public void setModel(String model)
{
this.model = model;
}
public int getYear()
{
return year;
}
public void setYear(int year)
{
this.year = year;
}
public String getManufacturer()
{
return manufacturer;
}
public void setManufacturer(String manufacturer)
{
this.manufacturer = manufacturer;
}
public String getColor()
{
return color;
}
public void setColor(String color)
{
this.color = color;
}
}
I think you should use Primefaces 3.3 because it is showing as expected as in my case.
For now this will work but i will try to get this fixed on Primefaces 4.0 too.
Please find attached image for the same. Image
I have tried to implement the autocomplete feature in primefaces but suggestions do not show up in my textbox. Can someone show me what I'm missing. theses are codes
udateCategory.xhtml
<p:panel header="Type in Category to Edit" >
<p:outputLabel value="Category Name"/>
<p:autoComplete value="#{categoryBean.selectedCategory}"
completeMethod="#{categoryBean.completeCategory}"
var="cat"
itemLabel="#{cat.categoryName}"
itemValue="#{cat}"
converter="#{catConverter}"
forceSelection="true"/>
<p:commandButton value="Update" action="#{category.saveCategory}"/>
</p:panel>
CategoryBean
public class CategoryBean implements Serializable{
private Category selectedCategory;
/**
* Creates a new instance of CategoryBean
*/
public CategoryBean() {
}
public List<Category> completeCategory (String query){
CategoryManager manager = new CategoryManager();//an instance of the manager
List<Category> suggestions = new ArrayList<>();//an instance of list
List<Category> allCategory = new ArrayList<>(); //populate the allCategory with data fro db
allCategory = manager.getAllCategory();
//checck to see if data exist in allCategory
if(!allCategory.isEmpty()){
System.out.println("kobla : allcategory has data");
}
else
{
System.out.println("kobla: no data in alcategory");
}
for(Category cat : allCategory){
if(cat.getCategoryName().startsWith(query)){
suggestions.add(cat);
}
}
//check to see if data exists in sugestions
if (!suggestions.isEmpty()) {
System.out.println("kobla : suggestions has data");
} else {
System.out.println("kobla: no data in suggestions");
}
return suggestions;
}
/**
* #return the selectedCategory
*/
public Category getSelectedCategory() {
return selectedCategory;
}
/**
* #param selectedCategory the selectedCategory to set
*/
public void setSelectedCategory(Category selectedCategory) {
this.selectedCategory = selectedCategory;
}
}
CategoryConverter
public class CategoryConverter implements Converter{
#Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if(value.trim().equals("")){
return null;
}
else{
try{
int id = Integer.parseInt(value);
List<Category> myCategory = new ArrayList<>();//
myCategory = new CategoryManager().getAllCategory();//load data fro db
for(Category cat : myCategory){
if(cat.getCategoryID() == id){
return cat;
}
}
}
catch(Exception e){
e.printStackTrace();
}
}
return null;
}
#Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
if(value == null || value ==""){
return null;
}
else
{
return String.valueOf(((Category)value).getCategoryName());
}
// throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
this works for me
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;
#ManagedBean
#ViewScoped
public class CategoryBean implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private Category selectedCategory;
#PostConstruct
public void init(){
selectedCategory = new Category();
}
public void saveCategory(){
System.out.println("saved "+this.selectedCategory);
}
public List<Category> completeCategory(String query) {
CategoryManager manager = new CategoryManager();// an instance of the
// manager
List<Category> suggestions = new ArrayList<>();// an instance of list
List<Category> allCategory = new ArrayList<>(); // populate the
// allCategory with data
// fro db
allCategory = manager.getAllCategory();
// checck to see if data exist in allCategory
if (!allCategory.isEmpty()) {
System.out.println("kobla : allcategory has data");
} else {
System.out.println("kobla: no data in alcategory");
}
for (Category cat : allCategory) {
if (cat.getCategoryName().startsWith(query)) {
suggestions.add(cat);
}
}
// check to see if data exists in sugestions
if (!suggestions.isEmpty()) {
System.out.println("kobla : suggestions has data");
} else {
System.out.println("kobla: no data in suggestions");
}
return suggestions;
}
/**
* #return the selectedCategory
*/
public Category getSelectedCategory() {
return selectedCategory;
}
/**
* #param selectedCategory
* the selectedCategory to set
*/
public void setSelectedCategory(Category selectedCategory) {
this.selectedCategory = selectedCategory;
}
}
and
import java.io.Serializable;
public class Category implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private int categoryID;
private String categoryName;
public int getCategoryID() {
return categoryID;
}
public void setCategoryID(int categoryID) {
this.categoryID = categoryID;
}
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
public Category(int categoryID, String categoryName) {
super();
this.categoryID = categoryID;
this.categoryName = categoryName;
}
public Category() {
super();
}
#Override
public String toString() {
return "Category [categoryID=" + categoryID + ", categoryName="
+ categoryName + "]";
}
}
and
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
#ManagedBean
#RequestScoped
public class CategoryConverter implements Converter, Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
#Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if(value.trim().equals("")){
return null;
}
else{
try{
int id = Integer.parseInt(value);
List<Category> myCategory = new ArrayList<>();//
myCategory = new CategoryManager().getAllCategory();//load data fro db
for(Category cat : myCategory){
if(cat.getCategoryID() == id){
return cat;
}
}
}
catch(Exception e){
e.printStackTrace();
}
}
return null;
}
#Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
if(value == null || value ==""){
return null;
}
else
{
return String.valueOf(((Category)value).getCategoryName());
}
// throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
and
<!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: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">
<h:head></h:head>
<h:body>
<h:form>
<p:outputLabel value="Category Name" />
<p:autoComplete
value="#{categoryBean.selectedCategory}"
completeMethod="#{categoryBean.completeCategory}"
var="cat"
itemLabel="#{cat.categoryName}"
itemValue="#{cat}"
converter="#{categoryConverter}"
forceSelection="true" />
<p:commandButton value="Update" action="#{categoryBean.saveCategory}" />
</h:form>
</h:body>
</html>
Hello i am Using PrimeFaces 4.0 and i need to pass object value in SelectOneMenu.
I am using converter to convert that from string format to Class object format.
These are the code files please help me...
lablevalue.xhtml
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
</h:head>
<h:body>
<h:form id="myform">
<p:growl showDetail="true"></p:growl>
<p:selectOneMenu value="#{itemlableAcction.idCard}" >
<f:converter converterId="converter.SelectMenUConverter" />
<f:selectItem itemLabel="Select" itemValue="" />
<f:selectItems value="#{itemlableAcction.idCards}" var="idv" itemLabel="#{idv.name}" itemValue="#{idv}" />
</p:selectOneMenu>
<h:commandButton action="#{itemlableAcction.onclickSubmit}" value="Submit"></h:commandButton>
</h:form>
</h:body>
</html>
ItemlableAcction
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import bo.IdCard;
#ManagedBean
public class ItemlableAcction {
List<IdCard> idCards = new ArrayList<IdCard>();
IdCard idCard;
public Object getIdCard() {
return idCard;
}
public void setIdCard(IdCard idCard) {
this.idCard = idCard;
}
public List<IdCard> getIdCards() {
return idCards;
}
public void setIdCards(List<IdCard> idCards) {
this.idCards = idCards;
}
public ItemlableAcction() {
IdCard card1 = new IdCard();
card1.setId(1);
card1.setName("ABC");
card1.setAddress("USA");
idCards.add(card1);
IdCard card2 = new IdCard();
card2.setId(2);
card2.setName("MNO");
card2.setAddress("INDIA");
idCards.add(card2);
IdCard card3 = new IdCard();
card3.setId(3);
card3.setName("XYZ");
card3.setAddress("Chaina");
idCards.add(card3);
}
public String onclickSubmit() {
IdCard ic = (IdCard) idCard;
System.out.println("In action id values are " + ic.getId() + " " + ic.getAddress());
return "";
}
}
SelectMenUConverter
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import bo.IdCard;
#FacesConverter("converter.SelectMenUConverter")
public class SelectMenUConverter implements Converter {
public SelectMenUConverter() {
System.out.println("Inside converter");
}
public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) {
System.out.println("One" + arg2);
IdCard idCard = new IdCard(arg2);
return idCard;
}
public String getAsString(FacesContext arg0, UIComponent arg1, Object value) {
System.out.println("Two" + value);
return value.toString();
}
}
Idcard
public class IdCard {
String name;
int id;
String address;
public IdCard() {
}
public IdCard(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
Imagine you have to implement converter for 100 classes.
If you don't want to implement a own Converter and get the data from exiting list, use:
SelectItems Converter Omnifaces
You have a complete example.
PD: Don't forget to implement toString with a unique id.(See documentation)
You're not searching and getting the required instance from the defined list (in your managed-bean) when getting its identifiant through getAsObject()'s method. You're just instanciating an additional new object through the converter. Try this:
#FacesConverter("converter.SelectMenUConverter")
public class SelectMenUConverter implements Converter {
...
#Override
public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) {
if (arg2 == null || arg2.isEmpty()) {return null;}
try {
return findIdCard(arg2); // here's where should be retreived the desired selected instance
} catch (NumberFormatException e) {
throw new ConverterException(new FacesMessage(("This is not a valid card id")), e);
}
}
...
public IdCard findIdCard(String id) {
Iterator<IdCard> iterator = idCards.iterator(); // "idCards" represents your idCards' list. It is not recognized yet in the converter
while(iterator.hasNext()) {
IdCard idc = iterator.next();
if(idc.getId() == Integer.valueOf(id).intValue()) {
return idc;
}
}
return null;
}
I'm getting this error while developping my application
javax.el.MethodNotFoundException: /test.xhtml #18,99
action="#{ComplexeController.saveComplexe}": Method not found:
fr.code.parc.controller.ComplexeController#97aead.saveComplexe()
test.xhtml :
<h:body>
<h1>Génération des Complexes</h1>
<h:form>
Nom Complexe: <h:inputText value="#{ComplexeController.complexe.nomComp}"/><br/>
Nom Zone: <h:selectOneMenu id="nomZone" value="#{ComplexeController.complexe.zoneParc}" converter="#{GenericConverter}">
<f:selectItems value="#{ZoneController.remplireItem()}"/>
</h:selectOneMenu>
<br/>
<h:commandButton action="#{ComplexeController.saveComplexe}" value="Insérer un nouveau complexe"/>
<h:commandButton action="#{ComplexeController.updateComplexe}" value="Modifier un complexe"/>
<br/>
<h:commandLink action="complexe" value="acceuil"/>
</h:form>
</h:body>
the entity Complexe.java
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
/**
* Complexe generated by hbm2java
*/
#Entity
#Table(name="COMPLEXE"
,schema="PROJET"
)
public class Complexe implements java.io.Serializable {
private String nomComp;
private ZoneParc zoneParc;
private Set<Parc> parcs = new HashSet<Parc>(0);
public Complexe() {
}
public Complexe(String nomComp) {
this.nomComp = nomComp;
}
public Complexe(String nomComp, ZoneParc zoneParc, Set<Parc> parcs) {
this.nomComp = nomComp;
this.zoneParc = zoneParc;
this.parcs = parcs;
}
#Id
#Column(name="NOM_COMP", unique=true, nullable=false, length=30)
public String getNomComp() {
return this.nomComp;
}
public void setNomComp(String nomComp) {
this.nomComp = nomComp;
}
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name="NOM_ZONEE")
public ZoneParc getZoneParc() {
return this.zoneParc;
}
public void setZoneParc(ZoneParc zoneParc) {
this.zoneParc = zoneParc;
}
#OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="complexe")
public Set<Parc> getParcs() {
return this.parcs;
}
#Override
public int hashCode() {
int hash = 0;
hash += (nomComp != null ? nomComp.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Complexe)) {
return false;
}
Complexe other = (Complexe) object;
if ((this.nomComp == null && other.nomComp != null) || (this.nomComp != null && !this.nomComp.equals(other.nomComp))) {
return false;
}
return true;
}
public void setParcs(Set<Parc> parcs) {
this.parcs = parcs;
}
}
and now ComplexeDaoImpl.java
import config.HibernateUtil;
import fr.code.parc.model.Complexe;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.Transaction;
/**
*
* #author raddaouirami
*/
public class ComplexeDaoImpl implements ComplexeDao{
#Override
public List<Complexe> list() {
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction t = session.beginTransaction();
List complexes = session.createQuery("from Complexe").list();
t.commit();
return complexes;
}
#Override
public Complexe getComplexe(String nomComp) {
Session session = HibernateUtil.getSessionFactory().openSession();
return (Complexe) session.load(Complexe.class, nomComp);
}
#Override
public void save(Complexe complexe) {
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction t = session.beginTransaction();
session.save(complexe);
t.commit();
}
#Override
public void update(Complexe complexe) {
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction t = session.beginTransaction();
session.update(complexe);
t.commit();
}
#Override
public void remove(Complexe complexe) {
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction t = session.beginTransaction();
session.delete(complexe);
t.commit();
}
}
and Finally ComplexeController.java
import fr.code.parc.dao.ComplexeDao;
import fr.code.parc.dao.ComplexeDaoImpl;
import fr.code.parc.model.Complexe;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
/**
*
* #author raddaouirami
*/
#ManagedBean
#SessionScoped
public class ComplexeController {
private Complexe complexe;
private DataModel listeComplexes;
private int selectedItemIndex;
/**
* Creates a new instance of ComplexeController
*/
public ComplexeController() {
complexe = new Complexe();
}
/* public Complexe getSelected() {
if (complexe == null) {
complexe = new Complexe();
selectedItemIndex = -1;
}
return complexe;
}*/
public DataModel getListeComplexes() {
List<Complexe> liste = new ComplexeDaoImpl().list();
listeComplexes = new ListDataModel(liste);
return listeComplexes;
}
/**
* #return the complexe
*/
public Complexe getComplexe() {
return complexe;
}
/**
* #param complexe the complexe to set
*/
public void setComplexe(Complexe complexe) {
this.complexe = complexe;
}
public String preparationAddComplexe(){
setComplexe(new Complexe());
return "test";
}
public String preparationEditComplexe(){
setComplexe((Complexe)(getListeComplexes().getRowData()));
return "test";
}
public String DeleteComplexe(){
Complexe complexes = (Complexe)(getListeComplexes().getRowData());
ComplexeDao dao = new ComplexeDaoImpl();
dao.remove(complexes);
return "complexe";
}
public String SaveComplexe(){
ComplexeDao dao = new ComplexeDaoImpl();
dao.save(getComplexe());
return "complexe";
}
public String UpdateComplexe(){
ComplexeDao dao = new ComplexeDaoImpl();
dao.update(complexe);
return "complexe";
}
}
How can I solve it?
In view you invoke saveComplexe
action="#{ComplexeController.saveComplexe}"
ComplexeController has only SaveComplexe method.
Either change to
action="#{ComplexeController.SaveComplexe}"
or rename method in ComplexeController to saveComplexe
2 Solutions:
Solution 1.
Change in test.xhtml : complexeController.saveComplexe [Notice first letter in complexeController is in smaller case]
<h:commandButton action="#{complexeController.saveComplexe}" value="Insérer un nouveau complexe"/>
<h:commandButton action="#{complexeController.updateComplexe}" value="Modifier un complexe"/>
Solution 2.
Change in ComplexeController.java:
#ManagedBean(name="ComplexeController ")
#SessionScoped
public class ComplexeController {
....
}
Read the Following Info about Configuring ManagedBeans in JSF:
There are 2 ways to use #ManagedBean to expose a Java Bean class to Managed Bean class.
Way 1.
#ManagedBean
public class ComplexeController{
....
}
In this case the bean exposed with same name but the first letter is smaller case, i.e., you can access the bean in Facelet as
#{complexeController}
Way 2.
#ManagedBean(name="myBean")
public class ComplexeController{
....
}
In this case the bean exposed with same name but the first letter is smaller case, i.e., you can access the bean in Facelet as
#{myBean}
Try to access the ManagedBean with first char to low case
e.g.
action="#{complexeController.saveComplexe}"
instead of
action="#{ComplexeController.saveComplexe}"