Jsf 2, Displaying validation messages inside dataTable - jsf

I have a problem displaying validation errors that are triggered by ui components which are
nested inside a dataTable.
Here is the xhtml page, which contains a form with a static upper part, where an address can be entered.
Below that it shows order items where users can enter amounts of items they would like to order.
These items are being retrieved from a database table and are diplayed inside a dataTable.
<!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">
<ui:composition template="../templates/_standard.xhtml">
<ui:define name="pageHeadline">
#{msg['supplies.module_headline']}
</ui:define>
<ui:define name="pageContent">
<h:form id="supplies" styleClass="editForm" rendered="#{!suppliesHandler.sent}">
<h:panelGrid
columns="2"
columnClasses="tdLabel,tdValue"
rowClasses="row"
styleClass="leftPane"
>
<!-- row 1 -->
#{msg['supplies.account']}:
<h:panelGroup>
<h:inputText id="account" value="#{supply.contact.account}" tabindex="1" styleClass="text"/>
<h:message for="account" styleClass="error"/>
</h:panelGroup>
<!-- row 2 -->
#{msg['supplies.company']}:
<h:panelGroup>
<h:inputText id="company" value="#{supply.contact.company}" tabindex="2" styleClass="text"/>
<h:message for="company" styleClass="error"/>
</h:panelGroup>
<!-- row 3 -->
#{msg['supplies.street']}:
<h:panelGroup>
<h:inputText id="street" value="#{supply.contact.street}" tabindex="3" styleClass="text"/>
<h:message for="street" styleClass="error"/>
</h:panelGroup>
<!-- row 4 -->
#{msg['supplies.postcode']}:
<h:panelGroup>
<h:inputText id="postcode" value="#{supply.contact.postcode}" tabindex="4" styleClass="text"/>
<h:message for="postcode" styleClass="error"/>
</h:panelGroup>
<!-- row 5 -->
#{msg['supplies.city']}:
<h:panelGroup>
<h:inputText id="city" value="#{supply.contact.city}" tabindex="5" styleClass="text"/>
<h:message for="city" styleClass="error"/>
</h:panelGroup>
</h:panelGrid>
<h:panelGrid
columns="2"
columnClasses="tdLabel,tdValue"
rowClasses="row"
styleClass="rightPane"
>
<!-- row 2 -->
#{msg['supplies.contact']}:
<h:panelGroup>
<h:inputText id="contact" value="#{supply.contact.contact}" tabindex="6" styleClass="text"/>
<h:message for="contact" styleClass="error"/>
</h:panelGroup>
<!-- row 3 -->
#{msg['supplies.phone']}:
<h:panelGroup>
<h:inputText id="phone" value="#{supply.contact.phone}" tabindex="7" styleClass="text"/>
<h:message for="phone" styleClass="error"/>
</h:panelGroup>
<!-- row 4 -->
#{msg['supplies.email']}:
<h:panelGroup>
<h:inputText id="email" value="#{supply.contact.email}" tabindex="8" styleClass="text">
<f:validator validatorId="com.abc.myproduct.be.ui.validator" />
</h:inputText>
<h:message for="email" styleClass="error"/>
</h:panelGroup>
<!-- row 5 -->
#{msg['supplies.fax']}:
<h:panelGroup>
<h:inputText id="fax" value="#{supply.contact.fax}" tabindex="9" styleClass="text"/>
<h:message for="fax" styleClass="error"/>
</h:panelGroup>
</h:panelGrid>
<div class="spacer"></div>
<h:dataTable id="items"
styleClass="listing_large"
value="#{supply.supplyItems}"
headerClass="heading"
var="item">
<h:column>
<f:facet name="header">
#{msg['supplies.id']}
</f:facet>
<h:outputText value="#{item.supply_id}" />
</h:column>
<h:column>
<f:facet name="header">
#{msg['supplies.amount']}
</f:facet>
<h:inputText value="#{item.amount}" id="amount" styleClass="text" size="3" maxlength="3" style="width:50px"/>
</h:column>
<h:column>
<f:facet name="header">
#{msg['supplies.description']}
</f:facet>
<h:outputText value="#{item.description}" />
</h:column>
</h:dataTable>
<div><br/>
<h:messages globalOnly="true" layout="table" styleClass="error"/>
</div>
<h:panelGrid
columns="1"
columnClasses="tdLabel,tdValue"
rowClasses="row">
<!-- row 2 -->
<h:panelGroup>
<h:commandButton value="#{msg['general.submit']}" action="#{suppliesHandler.submitMessage}" styleClass="button"/>
</h:panelGroup>
</h:panelGrid>
</h:form>
<h:messages globalOnly="true" layout="table" rendered="#{suppliesHandler.sent}"/>
</ui:define>
</ui:composition>
</html>
Validation for the address part of the form works perfect.
Only the messages for this part of the form are not being displayed:
<h:dataTable id="items"
styleClass="listing_large"
value="#{supply.supplyItems}"
headerClass="heading"
var="item">
<h:column>
<f:facet name="header">
#{msg['supplies.id']}
</f:facet>
<h:outputText value="#{item.supply_id}" />
</h:column>
<h:column>
<f:facet name="header">
#{msg['supplies.amount']}
</f:facet>
<h:inputText value="#{item.amount}" id="amount" styleClass="text" size="3" maxlength="3" style="width:50px"/>
</h:column>
<h:column>
<f:facet name="header">
#{msg['supplies.description']}
</f:facet>
<h:outputText value="#{item.description}" />
</h:column>
</h:dataTable>
Validation is being carried out through BeanValidation:
public class SupplyItem implements Serializable {
private static final long serialVersionUID = 1L;
#Id
private long supply_id;
private String description;
private int orderNo;
#Transient
#Max(value=200)
private int amount;
/*
* constructor
*/
public SupplyItem() {
super();
}
public long getSupply_id() {
return supply_id;
}
public void setSupply_id(long supply_id) {
this.supply_id = supply_id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getOrderNo() {
return orderNo;
}
public void setOrderNo(int orderNo) {
this.orderNo = orderNo;
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
}
It gets actually being validated, however the messages are not being displayed...
12:29:45,860 Information [javax.enterprise.resource.webcontainer.jsf.renderkit] (http--127.0.0.1-8080-2) WARNUNG: FacesMessage(s) wurde(n) in die Warteschlange gestellt, aber möglicherweise nicht angezeigt.
sourceId=supplies:items:0:amount[severity=(ERROR 2), summary=(Allowed maximum is 200), detail=(Allowed maximum is 200)]
sourceId=supplies:items:1:amount[severity=(ERROR 2), summary=(supplies:items:1:amount: 'a' must be a number consisting of one or more digits.), detail=(supplies:items:1:amount: 'a' must be a number between -2147483648 and 2147483647 Example: 9346)]
Trying to set the id of the input field dynamically in conjunction with a
h:message for="" did not work,displaying it through h:messages globalOnly="true" neither.
Any help would be highly appreciated.

You have not put a <h:message> for the input field anywhere in the datatable. You need to put a
<h:message for="amount" />
somewhere in the datatable exactly there where you'd like to display them.
The <h:messages globalOnly="true"> only displays messages with a null client ID, so that surely won't work at all for messages with a non-null client ID. You'd need to remove globalOnly="true" in order to display messages which are not shown anywhere else.

Related

Button not rendered after upload file

I want to render a button after upload a file, I have selectOneMenuto chose options, when I upload the file with the first option, the button didn't rendered but it rendered after I chose the second option.
ManagedBean.java
private boolean viewImport;
public boolean isViewImport() {
return viewImport;
}
public void setViewImport(boolean viewImport) {
this.viewImport = viewImport;
}
public void processFiless(FileUploadEvent event) {
setViewImport(true);
}
import.xhtml
<ui:composition template="./../../../../template.xhtml">
<ui:define name="content">
<h:form id="form1" prependId="false">
<p:growl id="messages"/>
<h1><h:outputText value="#{customerData.importBatchTitle}" /></h1>
<div class="formSection">
<p:panel header="#{app['import.fileSelectionForm']}" id="importFile" toggleable="true" toggleSpeed="300">
<h:graphicImage styleClass="formimg" url="/images/orange/fleche2.gif"/><h:outputText value="#{app['import.contract.parameter.primal']}" />
<h:selectOneMenu value="#{customerData.parameterType}">
<f:selectItems value="#{customerData.parameterTypeItems}" />
<p:ajax actionListener="#{customerData.selectionParameterType}" event="change" update="form1"/>
</h:selectOneMenu>
<br/>
<br/>
<h:panelGroup rendered="#{customerData.viewUpload}">
<p:fileUpload update="form1" fileUploadListener="#{customerData.processFiless}" >
<p:ajaxStatus>
<f:facet name="start">
<h:graphicImage value="/images/ajaxloading.gif" />
</f:facet>
<f:facet name="complete" >
<h:outputText value="" />
</f:facet>
</p:ajaxStatus>
</p:fileUpload>
</h:panelGroup>
</p:panel>
<br/>
<f:subview id="modifyCustt" rendered="#{customerData.viewImport}">
<p:commandButton value="ok"></p:commandButton>
</f:subview>
</div>
</h:form>
</ui:define>
</ui:composition>

p:dataTable not updated by PrimeFaces.current().ajax().update

I am starting developpment with JSF and PrimeFace datatable. I have prepared the following xhtml page:
<!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:p="http://primefaces.org/ui">
<h:head>
<title>Find Capital of Countries</title>
</h:head>
<h:body>
<h:form id="FrmTest">
<p:dataTable id="ListSites" value="#{testing.SiteSearch()}" var="lst" editable="true">
<f:facet name="header">
List of Sites
</f:facet>
<p:column>
<f:facet name="header">
Site Code
</f:facet>
#{lst.stCode}
</p:column>
<p:column headerText="Site Description">
<h:outputText value="#{lst.stDescription}" />
</p:column>
<p:column headerText="is Active">
<div style="text-align: center;">
<p:selectBooleanCheckbox value="#{lst.stActive}" />
</div>
</p:column>
<p:column>
<f:facet name="header">
Site Active
</f:facet>
<div style="text-align: center;">
<h:outputText value= "#{lst.stActive}" />
</div>
</p:column>
<p:column>
<f:facet name="header">
Modified By
</f:facet>
#{lst.modifiedBy}
</p:column>
<p:column>
<f:facet name="header">
Modification Date
</f:facet>
#{lst.modifiedDate}
</p:column>
<p:column>
<f:facet name="header">
Has Error
</f:facet>
#{lst.hasError}
</p:column>
<p:column>
<f:facet name="header">
Error Description
</f:facet>
#{lst.errorDescription}
</p:column>
<p:column>
<f:facet name="header">
Row State
</f:facet>
#{lst.rowState}
</p:column>
</p:dataTable>
<h:outputLabel value="Enter Country Name:"/>
<h:inputText id="country" binding="#{testing.country}"
valueChangeListener="#{testing.findCapitalListener}"
immediate="true"
onchange="document.getElementById('findcapital').click();" />
<br/>
<br/>
<h:outputLabel value="Capital is: " />
<h:inputText id="capital" binding="#{testing.capital}" immediate="true"/>
<br/>
<br/>
<h:commandButton value="Submit" partialSubmit="true" />
<div style="visibility: hidden" >
<h:commandButton id="findcapital" value="findcapital" partialSubmit="true" immediate="true" />
</div>
</h:form>
</h:body>
</html>
I want entry made in text box named country to update datatable named ListSites. The associated listener is called (system.out.println made) but the primeface update is not made. Here is the listener:
```
public void findCapitalListener(ValueChangeEvent cdl) {
String country = cdl.getNewValue().toString();
System.out.println("Country is : " + country);
StringBuilder capitalCountry = new StringBuilder();
findCapital(country, capitalCountry);
capital.setValue(capitalCountry.toString());
siteDto = listSiteDto.get(0);
siteDto.setStDescription(capitalCountry.toString());
listSiteDto.set(0, siteDto);
PrimeFaces.current().ajax().update("FrmTest:ListSites");
//System.out.println("Capital is : " + capital.getValue());
//System.out.println("New DTO Description : " + siteDto.getStDescription());
System.out.println("New list Description : " + listSiteDto.get(0).getStDescription());
}
```
The problem was due to the fact that the function populating the datatable (SiteSearch()) was retrieving data from the database. At that stage I wanted to refresh the page display before updating the database. I replaced the function by the list getter, things are working properly now.

Multiple Composite Component with Backing Bean [duplicate]

I have a composite component (collapsiblePanel). The component uses the "collapsible" bean to provide the toggle function. When I use the same component multiple times on a page, each instance of the component is bound to the same bean instance. How Can I achieve something like a component scoped bean?
collapsibleTemp.xhtml:
<cc:interface>
<cc:attribute name="model" required="true">
<cc:attribute name="collapsed" required="true" />
<cc:attribute name="toggle" required="true"
method-signature="java.lang.String f()" />
</cc:attribute>
<cc:actionSource name="toggle" />
<cc:facet name="header" />
<cc:facet name="body" />
</cc:interface>
<cc:implementation>
<h:panelGroup layout="block" styleClass="collapsiblePanel-header">
<h:commandButton id="toggle" action="#{cc.attrs.model.toggle}"
styleClass="collapsiblePanel-img"
image="#{cc.attrs.model.collapsed ? '/resources/images/plus.png' : '/resources/images/minus.png'}" />
<cc:renderFacet name="header" />
</h:panelGroup>
<h:panelGroup layout="block" rendered="#{!cc.attrs.model.collapsed}">
<cc:insertChildren />
<cc:renderFacet name="body"></cc:renderFacet>
</h:panelGroup>
<h:outputStylesheet library="css" name="components.css" />
</cc:implementation>
The backing bean:
#ManagedBean
#ViewScoped
public class Collapsible {
private boolean collapsed = false;
public boolean isCollapsed() {
return collapsed;
}
public void setCollapsed(boolean collapsed) {
this.collapsed = collapsed;
}
public String toggle() {
collapsed = !collapsed;
return null;
}
}
Using Page
<h:form id="someid">
<jl:collapsibletemp id="collapsiblePanel1" model="#{collapsible}">
<f:facet name="header">
<h3>
<h:outputText value="Collapsible information" />
</h3>
</f:facet>
<f:facet name="body">
<h:outputText value="do something....." />
</f:facet>
<p />
</jl:collapsibletemp>
<jl:collapsibletemp id="collapsiblePanel2" model="#{collapsible}">
<f:facet name="header">
<h3>
<h:outputText value="Collapsible information" />
</h3>
</f:facet>
<f:facet name="body">
<h:outputText value="do some tabbing" />
</f:facet>
<p />
</jl:collapsibletemp>
<jl:collapsibletemp id="collapsiblePanel3" model="#{collapsible}">
<f:facet name="header">
<h3>
<h:outputText value="Collapsible information" />
</h3>
</f:facet>
<f:facet name="body">
<h:outputText value="notice board" />
</f:facet>
<p />
</jl:collapsibletemp>
</h:form>
You can use the componentType attribute of the <cc:interface> to define a "backing component".
E.g.
<cc:interface componentType="collapsiblePanel">
...
</cc:interface>
<cc:implementation>
...
<h:commandButton action="#{cc.toggle}" ... />
...
<h:panelGroup rendered="#{!cc.collapsed}" ...>
...
</cc:implementation>
with just a com.example.components.CollapsiblePanel
#FacesComponent(value="collapsiblePanel") // To be specified in componentType attribute.
public class CollapsiblePanel extends UINamingContainer { // Important! Must extend UINamingContainer.
private boolean collapsed;
public void toggle() {
collapsed = !collapsed;
}
public boolean isCollapsed() {
collapsed;
}
}
However, when you want to have multiple of those components, then you should declare physically separate instances of them in the view. If this needs to happen dynamically, then you need to use <c:forEach> to generate physically separate instances of them instead of <ui:repeat> with a single component. Otherwise you have to map all collapsed states by the client ID inside a Map<String, Boolean>. See for an example and more background information also Getting same instance of `componentType` in composite component on every use

JSF Method is called always two times

Hi I have a jsf datatabel using view scope, which allows sorting and pagination.
My problem is, that my BackingBean method for sorting is always called two times which would not be a big problem if not for sorting ascending/descending when sorting for the same row (which makes it obsolete).
Any ideas how to solve this problem? I've already read several blocks about this problem, but non was helping me in my case yet…
I also tried to change it to request scope but this just made my pagination disappear…
This is the BackingBean Methode which is only called from my facelet link:
/**
* Changing sorting of list of events by columns.
*
* #param event
* ActionListener for the sorting field.
*/
public void sort(String sortingAttribute) {
System.out.println("you called sort: " + ++x);
if (sortField.equalsIgnoreCase(sortingAttribute)) {
boolean sortAscHelp = (sortAsc) ? false : true;
sortAsc = sortAscHelp;
} else {
sortField = sortingAttribute;
}
try {
events = (eventListType.equalsIgnoreCase("search")) ?EventManager.getSearchResults(searchTitle, searchDate, searchLocation, sortField, sortAsc, offset, limit) : EventManager.getEventList(eventListType, offset, limit, sortField, sortAsc);
} catch (DatabaseException e) {
FacesContext fcxt = FacesContext.getCurrentInstance();
fcxt.addMessage(component.getClientId(),
new FacesMessage(e.toString()));
logger.error("Error while loading the sorted list of searched events.");
}
}
And here comes my facelet:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html">
<ui:composition template="../../templates/basicTemplate.xhtml">
<ui:define name="metadata">
<f:metadata>
<f:viewParam name="title" value="#{listEventsBean.searchTitle}"/>
<f:viewParam name="location" value="#{listEventsBean.searchLocation}"/>
<f:viewParam name="date" value="#{listEventsBean.searchDate}"/>
<f:viewParam name="eventListType" value="#{listEventsBean.eventListType}"/>
<f:viewParam name="page" value="#{listEventsBean.page}"/>
<f:viewParam name="sorting" value="#{listEventsBean.sortField}"/>
<f:viewAction action="#{listEventsBean.init}"/>
</f:metadata>
</ui:define>
<ui:define name="content">
<h:form>
<p style="color:#808080; font-weight:bold; font-size:large">#{msgs.listEvents_events}</p>
<br/>
<h:outputText style="color:green" value="#{msgs.listEvents_deleted}" rendered="#{listEventsBean.deleted}"/>
<h:dataTable id="eventTable" value="#{listEventsBean.getEvents()}" var="event" binding="#{listEventsBean.component}">
<h:column>
<f:facet name="header">
<h:commandLink value="#{msgs.listEvents_title}" action="#{listEventsBean.sort('title')}">
<f:attribute name="sortField" value="title"/>
</h:commandLink>
</f:facet>
<h:outputText value="#{event.title}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:commandLink value="#{msgs.listEvents_dateStart}" action="#{listEventsBean.sort('startofevent')}">
<f:attribute name="sortField" value="startOfEvent"/>
</h:commandLink>
</f:facet>
<h:outputText value="#{event.startOfEvent}">
<f:convertDateTime pattern="#{msgs.longDate}"/>
</h:outputText>
</h:column>
<h:column>
<f:facet name="header">
<h:commandLink value="#{msgs.listEvents_dateEnd}" action="#{listEventsBean.sort('endofevent')}">
<f:attribute name="sortField" value="endOfEvent"/>
</h:commandLink>
</f:facet>
<h:outputText value="#{event.endOfEvent}">
<f:convertDateTime pattern="#{msgs.longDate}"/>
</h:outputText>
</h:column>
<h:column>
<f:facet name="header">
<h:commandLink value="#{msgs.listEvents_price}" action="#{listEventsBean.sort('ticketprice')}">
</h:commandLink>
</f:facet>
<h:outputText value="#{event.ticketPrice}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="#{msgs.listEvents_action}"/>
</f:facet>
<h:button id="showDetails" value="#{msgs.listEvents_showDetails}"
outcome="showEvent">
<f:param name="eventID" value="#{event.eventID}"/>
</h:button>
<h:commandButton id="deleteEvent" value="#{msgs.listEvents_delete}"
action="#{listEventsBean.deleteEvent(event.eventID)}"
rendered="#{sessionBean.ld.systemAdmin}"
onclick="return confirm('#{msgs.listEvents_deleteMsg}')"/>
</h:column>
</h:dataTable>
<h:outputText style="color:blue" value="#{msgs.listEvents_emptyResult}" rendered="#{listEventsBean.notEmpty}"/>
<br />
<h:outputLink id="backToSearchLink" value="#{request.contextPath}/facelets/allUsers/searchEvents.xhtml" rendered="#{listEventsBean.notEmpty}">
<h:outputText value="#{msgs.listEvents_searchAgain}"/>
</h:outputLink>
<ui:repeat id="paginationEvent" var="p" value="#{listEventsBean.getPageNumbers()}">
<h:outputLink value="#{request.contextPath}/facelets/allUsers/listEvents.xhtml">
<h:outputText value="#{p.toString()}" />
<f:param name="page" value="#{p.toString()}" />
<f:param name="sorting" value="#{listEventsBean.sortField}"/>
<f:param name="eventListType" value="#{listEventsBean.eventListType}" />
</h:outputLink>
</ui:repeat>
</h:form>
</ui:define>
</ui:composition>
</ui:composition>
Damn it! I just found my bug!
I still had a binding attached to my dataTable (beginning of dataTable).
Because of my view scope binding causes errors. One seems to be to call my method in dataTable twice (Tanks to BalusC for this info). Deleted this and added messages by rendering them as h:outputText.
I am still open for any suggestions how to change my scope to request without loosing my pagination or how to add messages from my BackingBean differently to my application without rendering h:outputText and bindings.

<p:dataTable> single selection not appearing in dialog

I have trouble displaying my property details on the dialog, after generating the table. Results are shown, but the selected row is not shown on dialog. I have taken over the example from primefaces show case.
<!DOCTYPE html>
<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"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title>TODO supply a title</title>
<h:outputStylesheet library="css" name="styles.css" />
</h:head>
<h:body>
Dear customer!
<li>#{userDataManager.displayHotelTypeChoice(userDataManager.hotelChoice)}
</li>
<li>#{userDataManager.displayPaxChoice(userDataManager.pax)}
</li>
<li>You have chosen to check in : #{userDataManager.displayCheckinDate(userDataManager.checkinDate)}
</li>
<li>You have chosen to check out : #{userDataManager.displayCheckoutDate(userDataManager.checkoutDate)}
</li>
<li>Total Days of Stay : #{userDataManager.countNightsBetween(userDataManager.checkinDate,userDataManager.checkoutDate)}
</li>
<li>Total Nights of Stay : #{userDataManager.nights}
</li>
<br>
</br>
<h:form id="form">
<p:dataTable id="hotels" var="room" value="#{propertyDataTable.searchByHotelType
(userDataManager.hotelChoice, userDataManager.pax)}"
rowKey="#{room.propertyID}"
selection="#{propertyDataTable.selectedProperty}"
selectionMode="single"
resizableColumns="true">
<f:facet name="header">
#{userDataManager.displayHotelTypeChoice(userDataManager.hotelChoice)}<br></br>
Please select only one choice
</f:facet>
<p:column headerText="Property ID" >
#{room.propertyID}
</p:column>
<p:column headerText="Accommodation" >
#{room.accommodation}
</p:column>
<p:column headerText="Pax" >
#{room.pax}
</p:column>
<p:column headerText="Stars" >
#{room.stars}
</p:column>
<p:column headerText="Type" >
#{room.type}
</p:column>
<f:facet name="footer">
In total there are #{propertyDataTable.listSize(propertyDataTable.
searchByHotelType(userDataManager.hotelChoice,
userDataManager.pax))} hotels.
<p:commandButton id="viewButton" value="View" icon="ui-icon-search"
update=":form:display" oncomplete="hotelDialog.show()">
</p:commandButton>
</f:facet>
</p:dataTable>
<p:dialog id="dialog" header="Hotel Detail" widgetVar="hotelDialog" resizable="false"
width="200" showEffect="clip" hideEffect="fold">
<h:panelGrid id="display" columns="2" cellpadding="4">
<f:facet name="header">
<!--<p:graphicImage value="/resources/images/#{propertyDataTable.selectedProperty.type}.jpg"/>-->
<p:graphicImage value="/resources/images/Grand.jpg"/>
</f:facet>
<h:outputText value="Accommodation:" />
<h:outputText value="#{propertyDataTable.selectedProperty.accommodation }" />
<h:outputText value="Feature:" />
<h:outputText value="#{propertyDataTable.selectedProperty.feature}" />
<h:outputText value="Stars:" />
<h:outputText value="#{propertyDataTable.selectedProperty.stars}" />
</h:panelGrid>
</p:dialog>
</h:form>
<br></br>
<br></br>
<h:commandButton value="Book"
action="#{navigationController.showPage()}" >
<f:param name="page" value="book" />
</h:commandButton>
<br></br>
<h:commandButton value="HOME"
action="#{navigationController.showPage()}" >
<f:param name="page" value="home" />
</h:commandButton>
</h:body>
</html>
package dataTable;
import irms.entity.accommodation.Property;
import irms.entity.accommodation.Room;
import irms.session.accommodation.PropertySession;
import irms.session.accommodation.ReservationSession;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
/**
*
* #author Lawrence
*/
#ManagedBean(name = "propertyDataTable")
#ViewScoped
public class PropertyDataTable implements Serializable{
#EJB
private ReservationSession reservationSession;
#EJB
private PropertySession propertySession;
private List<Property> propertyList;
private int choice;
private Property selectedProperty;
private List<Room> list = new ArrayList();
public PropertyDataTable() {
}
public List<Property> getAllRooms() {
return reservationSession.getAllRooms();
}
public List<Property> searchByHotelType(String hotelType, Integer pax) {
this.propertyList = propertySession.searchByHotelType(hotelType, pax);
return propertyList;
}
public int listSize(List<Property> list){
return list.size();
}
public Room getRoom(String propertyID, Integer roomID) {
return propertySession.findRoom(propertyID, roomID);
}
public List<Room> getRoomList(String propertyID){
return propertySession.getRoomList(propertyID);
}
public ReservationSession getReservationSession() {
return reservationSession;
}
public void setReservationSession(ReservationSession reservationSession) {
this.reservationSession = reservationSession;
}
public PropertySession getPropertySession() {
return propertySession;
}
public void setPropertySession(PropertySession propertySession) {
this.propertySession = propertySession;
}
public List<Property> getPropertyList() {
return propertyList;
}
public void setPropertyList(List<Property> propertyList) {
this.propertyList = propertyList;
}
public int getChoice() {
return choice;
}
public void setChoice(int choice) {
this.choice = choice;
}
public Property getSelectedProperty() {
return selectedProperty;
}
public void setSelectedProperty(Property selectedProperty) {
this.selectedProperty = selectedProperty;
}
public List<Room> getList() {
return list;
}
public void setList(List<Room> list) {
this.list = list;
}
}
You Must add ActionListener in your viewButton commandButton
change your xhtml page like this:
<!DOCTYPE html>
<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"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title>TODO supply a title</title>
<h:outputStylesheet library="css" name="styles.css" />
</h:head>
<h:body>
Dear customer!
<li>#{userDataManager.displayHotelTypeChoice(userDataManager.hotelChoice)}
</li>
<li>#{userDataManager.displayPaxChoice(userDataManager.pax)}
</li>
<li>You have chosen to check in : #{userDataManager.displayCheckinDate(userDataManager.checkinDate)}
</li>
<li>You have chosen to check out : #{userDataManager.displayCheckoutDate(userDataManager.checkoutDate)}
</li>
<li>Total Days of Stay : #{userDataManager.countNightsBetween(userDataManager.checkinDate,userDataManager.checkoutDate)}
</li>
<li>Total Nights of Stay : #{userDataManager.nights}
</li>
<br>
</br>
<h:form id="form">
<p:dataTable id="hotels" var="room" value="#{propertyDataTable.searchByHotelType
(userDataManager.hotelChoice, userDataManager.pax)}"
rowKey="#{room.propertyID}"
resizableColumns="true">
<f:facet name="header">
#{userDataManager.displayHotelTypeChoice(userDataManager.hotelChoice)}<br></br>
Please select only one choice
</f:facet>
<p:column headerText="Property ID" >
#{room.propertyID}
</p:column>
<p:column headerText="Accommodation" >
#{room.accommodation}
</p:column>
<p:column headerText="Pax" >
#{room.pax}
</p:column>
<p:column headerText="Stars" >
#{room.stars}
</p:column>
<p:column headerText="Type" >
#{room.type}
</p:column>
<f:facet name="footer">
In total there are #{propertyDataTable.listSize(propertyDataTable.
searchByHotelType(userDataManager.hotelChoice,
userDataManager.pax))} hotels.
<p:commandButton id="viewButton" value="View" icon="ui-icon-search"
update=":form:display" oncomplete="hotelDialog.show()">
<f:setPropertyActionListener value="#{room}" target="#{propertyDataTable.selectedProperty}" />
</p:commandButton>
</f:facet>
</p:dataTable>
<p:dialog id="dialog" header="Hotel Detail" widgetVar="hotelDialog" resizable="false"
width="200" showEffect="clip" hideEffect="fold">
<h:panelGrid id="display" columns="2" cellpadding="4">
<f:facet name="header">
<!--<p:graphicImage value="/resources/images/#{propertyDataTable.selectedProperty.type}.jpg"/>-->
<p:graphicImage value="/resources/images/Grand.jpg"/>
</f:facet>
<h:outputText value="Accommodation:" />
<h:outputText value="#{propertyDataTable.selectedProperty.accommodation }" />
<h:outputText value="Feature:" />
<h:outputText value="#{propertyDataTable.selectedProperty.feature}" />
<h:outputText value="Stars:" />
<h:outputText value="#{propertyDataTable.selectedProperty.stars}" />
</h:panelGrid>
</p:dialog>
</h:form>
<br></br>
<br></br>
<h:commandButton value="Book"
action="#{navigationController.showPage()}" >
<f:param name="page" value="book" />
</h:commandButton>
<br></br>
<h:commandButton value="HOME"
action="#{navigationController.showPage()}" >
<f:param name="page" value="home" />
</h:commandButton>
</h:body>
</html>

Resources