I am a newbie in JSF. I am using JSF 2 and there is a list being populated by my bean file. In my .xhtml file, I want to display this information as 2 columns.
In bean class
List modules;(Contains module.enable module.name)
The list has say 30 modules. I want to display all these modules information in 2 columns. For eg: I want to display first module information(module.enable module.name) in one column and the second in second column. Or it can be first 15 modules in first column and the remaining 15 in second column. Tried with both h:dataTable and h:panelGrid but couldn't get it working.
Any help would be highly appreciated.
Thanks
Shyju
This is my code to resolve the issue using the varStatus property of ui:repeat
<h:panelGrid id="moduleList" columns="2" border="1" >
<f:facet name="header">
<h:outputText value="Modules"/>
</f:facet>
<ui:repeat value="#{EnableCodeBean.modules}" var="modules" varStatus="status">
<h:panelGroup>
<h:selectBooleanCheckbox value="#{modules.enable}"/>
<h:outputText value="#{modules.name}"/>
</h:panelGroup>
<f:verbatim rendered="#{status.index mod 2 == 1}">
</td></tr><tr><td>
</f:verbatim>
<f:verbatim rendered="#{status.index mod 2 == 0}">
</td><td>
</f:verbatim>
</ui:repeat>
</h:panelGrid>
By playing with some <h:dataTable>'s attributes' values, we can make something like that:
The attribute first, idicates to the first index of the list to start displaying from, and the rows's one, indicates to the rows' number to be diplayed starting from the begining index designed if explicited, else, it displays from the 1st row and so on.
Here's a kickoff example of this, relying on 2 <h:dataTalbe> tags included in one <h:panelGrid coulmns="2">, and relying only on 4 modules for simplification's purpose, 2 per every column. Every <h:dataTable> tag must have different value of its first attribute :
The Backing-bean:
#ManagedBean
#RequestScoped
public class ModuleBacking{
private List<Module> modules = new ArrayList<Module>();
public ModuleBacking() {
}
#PostConstruct
public void insertion() {
Module m1 = new Module("math",true);
Module m2 = new Module("english",false);
Module m3 = new Module("physics",false);
Module m4 = new Module("chimics",true);
modules.add(m1);
modules.add(m2);
modules.add(m3);
modules.add(m4);
}
public List<Module> getModule() {
return modules;
}
public List<Module> displayModules(){
return modules;
}
}
The view :
<h:body>
<h:panelGrid columns="2" cellspacing="3" cellpadding="3" style="border-style: solid" rules="all" >
<f:facet name="header">
<h:outputText value="First 2 modules" style="padding-right:80px "/>
<h:outputText value="Second 2 modules"/>
</f:facet>
<h:dataTable value="#{moduleBacking.displayModules()}" var="m" rules="all" first="0" rows="2">
<h:column>
<f:facet name="header" ><h:outputText value="Module's name" /></f:facet>
<h:outputText value="#{m.name}" />
</h:column>
<h:column>
<f:facet name="header" ><h:outputText value="Module's enabling" /></f:facet>
<h:outputText value="#{m.enable}" />
</h:column>
</h:dataTable>
<h:dataTable value="#{moduleBacking.displayModules() }" var="m" rules="all" first="2" rows="2">
<h:column>
<f:facet name="header" ><h:outputText value="Module's name" /></f:facet>
<h:outputText value="#{m.name}" />
</h:column>
<h:column>
<f:facet name="header" ><h:outputText value="Module's enable" /></f:facet>
<h:outputText value="#{m.enable}" />
</h:column>
</h:dataTable>
</h:panelGrid>
</h:body>
In your case, the two <h:dataTable> seem to be like these :
<h:dataTable value="#{moduleBacking.displayModules()}" var="m" rules="all" first="0" rows="15">
<h:dataTable value="#{moduleBacking.displayModules()}" var="m" rules="all" first="15" rows="15">
Related
I have a complicate JSF that contain dataTable with filter in each one of the columns.
In order to make sure that the generate button will fetch all the data first I need to clear all the filters when the user press the button.
I try to do use onclick but then I couldn’t see the blockUI I also try on complete (ajax) but again it was not working properly with all the other items (blockUI ,message).
I decided to try to clear the filters via server side but only dataTable.reset() is working.
I have no more ideas how to clean the filters ???
Is this API working ?
Appreciate your help
Thanks
<h:panelGrid columns="1" style="width: 100%">
<p:panel id="vt-panel">
<h:panelGrid columns="5" cellpadding="2" >
<h:outputText value="Start Date" />
<p:calendar id="vt-start" value="#{vtRepBean.startDate}" binding="#{startDateComponent}" maxlength="9" size="9" pattern="dd-MMM-yy" title="dd-MMM-yy" required="true" maxdate="#{vtRepBean.endDate}">
<p:ajax event="dateSelect" listener="#{vtRepBean.handleStartDateSelect}" update=":mainForm:vt-end"/>
</p:calendar>
<h:outputText value="End Date" />
<p:calendar id="vt-end" value="#{vtRepBean.endDate}" maxlength="9" size="9" pattern="dd-MMM-yy" title="dd-MMM-yy" required="true" mindate="#{vtRepBean.startDate}">
<p:ajax event="dateSelect" listener="#{vtRepBean.handleEndDateSelect}" update=":mainForm:vt-start"/>
</p:calendar>
<p:commandButton
id="genVtBtn"
value="Generate"
actionListener="#{vtRepBean.handleVTGenerateButton}"
update=":mainForm:vt-panel,:mainForm:vt-panel-table">
</p:commandButton>
</h:panelGrid>
</p:panel>
</h:panelGrid>
<p:growl id="vt_message" showDetail="true" autoUpdate="true"/>
<h:panelGroup id="vt-panel-table">
<p:dataTable id="vtDataTable"
widgetVar="vtWidget"
var="reportObject"
value="#{vtRepBean.reportObjectsList}"
rendered="#{vtRepBean.renderVTReport}"
filteredValue="#{vtRepBean.filteredVTList}"
paginator="true"
paginatorPosition="bottom"
paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
rowsPerPageTemplate="50,100,200"
rows="50"
style="width: 100%">
<p:columnGroup type="header">
<p:row>
<p:column colspan="5" headerText="VT request"/>
<p:column colspan="1" headerText="Dis" />
</p:row>
<p:row>
<p:column headerText="CREATE DATE" sortBy="#{reportObject.log.createDate}" filterBy="#{reportObject.log.createDate}" filterMatchMode="contains"/>
<p:column headerText="IP" sortBy="#{reportObject.log.ip}" filterBy="#{reportObject.log.ip}" filterMatchMode="contains"/>
</p:row>
</p:columnGroup>
<p:column >
<h:outputText value="#{reportObject.log.createDate}"/>
</p:column>
<p:column >
<h:outputText value="#{reportObject.log.ip}"/>
</p:column>
</p:dataTable>
<p:commandLink rendered="#{vtRepBean.renderVTReport}" ajax="false" onclick="PrimeFaces.monitorDownload(showStatus, hideStatus)">
<p:graphicImage value="resources/images/excel.png" title="excel" style="border-color: white"/>
<p:dataExporter id="xlsReport"
type="xls"
target="vtDataTable"
fileName="VTReport"
postProcessor="#{vtRepBean.postProcessXLS}"/>
</p:commandLink>
</h:panelGroup>
<p:blockUI widgetVar="blockVTPanel" trigger="genvtBtn" block="vt-panel">
<div class="disable-scroll">
<p:graphicImage value="resources/images/ajax-loader.gif"/>
</div>
</p:blockUI>
DataTable dataTable = (DataTable) FacesContext.getCurrentInstance().getViewRoot().findComponent("mainForm:vtDecomDataTable");
if (!dataTable.getFilters().isEmpty()) {
logger.info("dataTable.getFilters().isEmpty() :" + dataTable.getFilters().isEmpty());
dataTable.getFilters().clear();// not working
dataTable.getFilteredValue().clear();// not working
dataTable.setFilteredValue(null);// not working
dataTable.setFilters(null);// not working
dataTable.setFilterMetadata(null);// not working
dataTable.reset();// working
RequestContext requestContext = RequestContext.getCurrentInstance();
requestContext.update("mainForm:vtDecomDataTable");
}
To clear all the inputs of the filters you can do it by javascript:
<p:commandButton onclick="PF('vtWidget').clearFilters()" />
vtWidget is the widgetVar of the datatable.
Basically clearFilters() will clear the fields for you and call filter(), and the filter function would update your datatable, which in turns will empty the filtered list.
Note: This would work only if the filters were inputText. If you have custom components then you should implement your own clear based on the components that you have.
Sometimes if you have custom components, you need to empty the filtered list manually, as you did in the comments!
This is how i solved my problem.
RequestContext requestContext = RequestContext.getCurrentInstance();
requestContext.execute("PF('widget_orderDataTable').clearFilters()");
Hope its help.
For clearing custom filters you can use primefaces resetInput, along with clearFilters() discussed in other answers, and a custom actionListener method. See code snippets below:
<p:dataTable id="dataTable" widgetVar="dataTable"
value="#{bean.listOfObjects}" var="object">
<p:commandButton value="Clear All Filters"
onclick="PF('dataTable').clearFilters()"
actionListener="#{controller.clearAllFilters}"
update="dataTable">
<p:resetInput target="dataTable" />
</p:commandButton>
Controller.java
public void clearAllFilters() {
DataTable dataTable = (DataTable) FacesContext.getCurrentInstance().getViewRoot().findComponent("form:dataTable");
if (!dataTable.getFilters().isEmpty()) {
dataTable.reset();
RequestContext requestContext = RequestContext.getCurrentInstance();
requestContext.update("form:dataTable");
}
}
I hope this helps anyone looking to clear custom filters.
For Primefaces 7 and above, use the following:
public void clearAllFilters() {
DataTable dataTable = (DataTable) FacesContext.getCurrentInstance().getViewRoot().findComponent("form:dataTable");
if (!dataTable.getFilters().isEmpty()) {
dataTable.reset();
PrimeFaces.current().ajax().update("form:dataTable");
}
}
When I make selection in dataTable it gives error below
[javax.faces.FacesException: DataModel must implement org.primefaces.model.SelectableDataModel when selection is enabled or you need to define rowKey attribute]]
But in my dataTable rowKey attribute is already define and I checked it's value is unique. What could be the possible reason I am getting this error
DataTable code is as below
<p:dataTable id="scenarioDataTableId" var="scenarioDataTable" value="#{myBean.scenarioApplicationColumnBOList}" tableStyle="width:90%" rowKey="scenarioDataTable.scenarioApplicationColumnId" selection="#{myBean.selectedScenarioApplicationColumnRow}" >
<f:facet name="header">Database Columns That will be updated in this Scenario</f:facet>
<p:ajax event="rowSelectRadio" listener="#{myBean.editSelectedScenarioApplicationColumnAction}"></p:ajax>
<p:column selectionMode="single" style="width:10%" />
<p:column id="Id" headerText="Id" >
#{scenarioDataTable.scenarioApplicationColumnId}
</p:column>
<p:column id="scenarioId" headerText="Scenario Id" >
#{scenarioDataTable.scenarioId}
</p:column>
<p:column id="appId" headerText="Application Column Id" >
#{scenarioDataTable.applicationColumnId}
</p:column>
<p:column id="tableNameId" headerText="Table Name" >
#{scenarioDataTable.tableName}
</p:column>
<p:column id="columnNameId" headerText="Column Name" >
#{scenarioDataTable.columnName}
</p:column>
<p:column id="columnValidValueId" headerText="Column Valid Value" >
#{scenarioDataTable.columnValidValue}
</p:column>
<p:column id="dbActionId" headerText="DB Action" >
#{scenarioDataTable.dbAction}
</p:column>
<f:facet name="footer">
<p:commandButton value="Add New Row" action="#{myBean.openDialogScenarioUpdateColumn}" oncomplete="dialogScenarioUpdateColumn.show()" rendered="#{myBean.scenarioInputFieldRendered}"></p:commandButton>
<p:spacer width="20" ></p:spacer>
<p:commandButton id="editButton" value="Edit" action="#{myBean.editSelectedScenarioApplicationColumnAction}" update=":formSelectCriteria:ScenarioMainPanel" ></p:commandButton>
<p:spacer width="20" ></p:spacer>
<p:commandButton id="deleteButton" value="Delete"></p:commandButton>
</f:facet>
</p:dataTable>
Take a look at the Primefaces Showcase. A rowKey must refer to an attribute shown in your p:dataTable (which is an attribute of one of your #{myBean.scenarioApplicationColumnBOList} objects), e.g.
rowKey="#{scenarioDataTable.scenarioApplicationColumnId}"
but not
rowKey="scenarioDataTable.scenarioApplicationColumnId"
I am working with Primefaces 3.5, Spring 3.2, JSF 2.2 and Apache is my server.
My problem is that whenever i click on the row, the row select event is never triggered in my backing bean and my store details panel is never updated.
My backing bean is in request scope and contains onRowSelect method.
However when i change my backing bean to sessions scope(it requires a few changes in backing bean), instant row selection works.
For the simplicity of my question i have modified my code to include only relevant part. In my param, for the sake of testing i just put existing customer with ID 35 in my test page.
Here is my dialog.xhtml
<h:form id="customerListingsForm">
<p:dialog id="manageStoresDialog"
header="Manage #{manageStoreBean.store.owner.name}'s Stores"
widgetVar="manageStoresDlg"
modal="true"
resizable="false">
<p:panelGrid id="storePanel" rendered="#{manageStoreBean.owner != null}">
<f:facet name="header">
<p:row>
<p:column>Store Details</p:column>
<p:column>Customer Store List</p:column>
</p:row>
</f:facet>
<p:row>
<p:column>
<p:panelGrid id="storeDetails">
<p:row>
<p:column>Name: </p:column>
<p:column>
<h:inputText value="#{manageStoreBean.store.name}" />
</p:column>
</p:row>
<p:row>
<p:column>Description: </p:column>
<p:column>
<h:inputText value="#{manageStoreBean.store.description}" />
</p:column>
</p:row>
<p:row>
<p:column>Short Code: </p:column>
<p:column>
<h:inputText value="#{manageStoreBean.store.shortCode}" />
</p:column>
</p:row>
<p:row>
<p:column>Owner name:</p:column>
<p:column>
<h:inputText value="#{manageStoreBean.store.owner.name}" readonly="true" />
</p:column>
</p:row>
<p:row>
<p:column>Store Type: </p:column>
<p:column>
<p:selectOneMenu
id="storeTypeSelected"
value="#{manageStoreBean.placeType}"
var="storeType"
style="height:25px"
converter="#{placeTypeConverter}">
<f:selectItems
value="#{manageStoreBean.typeList}"
var="storeTypeItem"
itemLabel="#{storeTypeItem.code}"
itemValue="#{storeTypeItem}"/>
<p:column>#{storeType.description}</p:column>
</p:selectOneMenu>
</p:column>
</p:row>
<p:row>
<p:column>Country: </p:column>
<p:column>
<p:selectOneMenu
id="storeCountrySelected"
value="#{manageStoreBean.country}"
var="country"
style="height:25px"
converter="#{countryConverter}">
<f:selectItems
value="#{manageStoreBean.countryList}"
var="countryItem"
itemLabel="#{countryItem.isoNumericCode}"
itemValue="#{countryItem}"/>
<p:column>#{country.isoNumericCode}</p:column>
</p:selectOneMenu>
</p:column>
</p:row>
<p:row>
<p:column>Localisation: </p:column>
<p:column>
<p:selectOneMenu
id="storeLocalisationSelected"
value="#{manageStoreBean.localisationData}"
var="storeLocal"
style="height:25px"
converter="#{localisationConverter}">
<f:selectItems
value="#{manageStoreBean.localisationList}"
var="local"
itemLabel="#{local.regionCode}"
itemValue="#{local}"/>
<p:column>#{storeLocal.id} - #{storeLocal.regionCode}</p:column>
</p:selectOneMenu>
</p:column>
</p:row>
</p:panelGrid>
</p:column>
<p:column style="width:250px">
<p:dataTable id="stores"
var="store"
value="#{manageStoreBean.storeList}"
rowKey="#{store.id}"
scrollHeight="240"
scrollable="true"
selectionMode="single"
selection="#{manageStoreBean.selectedStore}"
lazy="true">
<p:ajax event="rowSelect" immediate="true"
listener="#{manageStoreBean.onRowSelect}"
update=":customerListingsForm:storeDetails"/>
<p:column headerText="Salon Name">
<h:outputText value="#{store.name}" />
</p:column>
<p:column headerText="ID">
<h:outputText value="#{store.id}" />
</p:column>
</p:dataTable>
</p:column>
</p:row>
</p:panelGrid>
<p:commandButton
value="Save"
action="#{manageStoreBean.saveStore}"
oncomplete="manageStoresDlg.hide()">
<f:param name="storeCustomerId" value="#{manageStoreBean.owner.id}" />
</p:commandButton>
<h:outputText value=" " />
<p:commandButton
value="Close"
oncomplete="manageStoresDlg.hide()"/>
</p:dialog>
<p:commandButton value="Add Store"
oncomplete="manageStoresDlg.show()"
update=":customerListingsForm:manageStoresDialog"
process="#this">
<f:param name="storeCustomerId" value="35" />
</p:commandButton>
</h:form>
Also i'm new to primefaces and web dev, but did a lot of learning myself before i started this project.
I spent 2 days try to understand what's wrong and searched all web but could not find any solution. May be i'm missing something or doing wrong not sure.
Any help is much appreciated.
Try making your bean view scoped.
If you are making it request scoped, then you are telling JSF to throw out all of your existing data every time the user is done talking to your server. So it makes no sense to have JSF run a listener on an existing page. In particular, PrimeFaces has a tendency to malfunction when it encounters an odd set of scopes.
See also Difference between View and Request scope in managed beans
By searching a lot of stuff on the internet i came to conclusion that datatable does not work very well with backing bean in request scope when table is loaded using dynamic argument. That is very shame. I do not see any other option but to implement viewscope in spring for my beans.
My xhtml contains input fields, where user can input numeric or alphabet values. Using an ajax call I am validating the input value and throwing a validation error on the . But even after entering invalid characters and error message, user may still hit the 'Save' button. Once the user hits the Save button it triggers a method in the Controller. Is there a way I can check for validation errors on p:messages inside the controller using the FacesContext.getCurrentInstance().
xhtml code
<!-- Messages -->
<p:messages id="errorMessages" globalOnly="false" showDetail="true" showSummary="false" closable="true" />
<!-- Column input field-->
<p:column>
<f:facet name="header">
<h:outputText value="Input Amount" escape="false" />
</f:facet>
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{row.amount}" escape="false">
<f:convertNumber maxFractionDigits="3" minFractionDigits="3"
maxIntegerDigits="5" />
</h:outputText>
</f:facet>
<f:facet name="input">
<p:inputText id="input" value="#{row.amount}" maxlength="10"
size="10">
<f:convertNumber maxFractionDigits="3" minFractionDigits="3"
maxIntegerDigits="5" />
<f:validator validatorId="hourlyValueValidator" for="input" />
<p:ajax event="change" partialSubmit="true" process="input"
update=":#{p:component('errorMessages')}" />
</p:inputText>
</f:facet>
</p:cellEditor>
</p:column>
<!-- Save Button -->
<p:commandButton id="btnSubmit" value="Save"
update=":#{p:component('tblScrollPnl')} :#{p:component('errorMessages')}"
action="#{controller.saveValues()}" ajax="true" />
Controller in ViewScope
public void saveValues() throws Exception {
FacesContext context = FacesContext.getCurrentInstance();
List<FacesMessage> errorMsgList = context.getMessageList("globalMessages");
......
......
......
}
You don't need to get messages from the bean side for validation, as you experienced, view side validation occur but doesn't block your action.
There is couple of thing wrongs in your view, to fix your problem you need to change the process attribute of your p:commandButton, ortherwise only the button is processed (by default process="#this", so the validation is skipped.
<p:commandButton id="btnSubmit" value="Save" process="#form" update=":tblScrollPnl :errorMessages" action="#{controller.saveValues()}" />
Also note that I've removed ajax="true" since it is by default and fixed major problems in update="".
You should also rearrange your validators :
<p:inputText id="input" value="#{row.amount}" maxlength="10" size="10" validator="hourlyValueValidator">
<f:convertNumber maxFractionDigits="3" minFractionDigits="3" maxIntegerDigits="5" />
</p:inputText>
I have an issue with view scoped bean. I know it's common question but I didn't get right answer. I have a datatable that is responsible for showing search results upon user entered search some criteria.
Here is xhtml:
<html xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:p="http://primefaces.org/ui">
<h:panelGroup id ="adminReportLogList">
<p:dataTable value="#{adminLogView.lazyModelReport}" var="model" id="reportLogList" lazy="true" paginator="true" rows="20" paginatorAlwaysVisible="false" paginatorPosition="bottom" emptyMessage="emppty list" styleClass="dtable" style="table-layout: fixed; width: 100%"
paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}" rowsPerPageTemplate="5,10,15,20">
<p:column headerText="Report number" sortBy="#{model.reportNumber}">
<h:outputText value="#{model.reportLogId}"/>
</p:column>
<p:column headerText="Report date" sortBy="#{model.reportDate}">
<h:outputText value="#{model.reportDate}">
<f:convertDateTime pattern="yyyy/MM/dd hh:mm:ss"/>
</h:outputText>
</p:column>
<p:column headerText="Search date" sortBy="#{model.searchLogId.searchDate}">
<h:outputText value="#{model.searchLogId.searchdate}">
<f:convertDateTime pattern="yyyy/MM/dd hh:mm:ss"/>
</h:outputText>
</p:column>
<p:column headerText="User name" sortBy="#{model.searchLogId.loginLogId.username}">
<h:outputText value="#{model.searchLogId.loginLogId.username}"/>
</p:column>
<p:column headerText="Customer number" sortBy="#{model.customerId}">
<h:outputText value="#{model.customerId.registernumber}"/>
</p:column>
<p:column headerText="Customer name" sortBy="#{model.customerId}">
<h:outputText value="#{model.customerId.name}"/>
</p:column>
</p:dataTable>
</h:panelGroup>
<br/>
// SEARCH PANEL
<p:panel>
<h:panelGrid columns="3" styleClass="insGrid" id="reportLogSearchPanel">
<h:outputText value="User: "/>
<p:inputText id="reportLogSearchByUserName" value="#{adminLogView.searchUserName}">
<p:watermark for="reportLogSearchByUserName" value ="Customer name"/>
</p:inputText>
<h:message for="reportLogSearchByUserName" id="msgReportLogSearchByUserName" styleClass="errorMessage"/>
<h:outputText value="Customer id number: "/>
<p:inputText id="reportLogSearchByCustomerName" value="#{adminLogView.searchCustomerName}">
<p:watermark for="reportLogSearchByCustomerName" value="Customer id number"/>
</p:inputText>
<h:message for="reportLogSearchByCustomerName" id="msgReportLogSearchBySearchDate" styleClass="errorMessage"/>
<h:outputText value="Report date "/>
<p:inputText id="reportLogSearchByReportDate" value="#{adminLogView.searchReportDate}">
<p:watermark for="reportLogSearchByReportDate" value="Report date YYYY/MM/DD"/>
</p:inputText>
<h:message for="reportLogSearchByReportDate" id="msgReportLogSearchByReportDate" styleClass="errorMessage"/>
<h:panelGroup/>
<h:commandButton value="Search" styleClass="btn" action="#{adminLogView.searchReport()}">
<f:ajax render =":form:adminReportLogList :form:reportLogList" execute=":form:reportLogSearchPanel"/>
</h:commandButton>
</h:panelGrid>
</p:panel>
which is used in tag in another xhtml which is: /I think it's not cause in this case/
<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets"
template="./../templates/admin_main.xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<ui:define name="content">
<h:panelGroup id="include">
<ui:include src="#{adminLogView.page}.xhtml"/>
</h:panelGroup>
</ui:define>
</ui:composition>
Here is my bean
#Named(value = "adminLogView")
#ViewScoped
public class AdminLogView implements Serializable{
#EJB
private LogServiceLocal logService;
private List<Reportlog> ReportLogList;
String page = "reportLog";
LazyDataModel<Reportlog> lazyModelReport;
LazyDataModel<Loginlog> lazyModelLogin;
LazyDataModel<Searchlog> lazyModelSearch;
String searchCustomerName;
String searchUserName;
String searchReportDate;
#PostConstruct
public void init(){
this.lazyModelReport = new LazyReportLogDataModel(this.logService);
}
public void searchReport(){
Map<String, String> filter = new HashMap<String, String>();
if(this.searchCustomerName != null && !this.searchCustomerName.isEmpty())
filter.put("customerName", this.searchCustomerName);
if(this.searchReportDate != null && !this.searchReportDate.isEmpty())
filter.put("reportDate", this.searchReportDate);
if(this.searchUserName != null && !this.searchUserName.isEmpty())
filter.put("userName", this.searchUserName);
this.lazyModelReport.load(0, 30, null, SortOrder.UNSORTED, filter);
}
}
When we navigate to a page above then #postConstruct method called multiple times, even with sessionScoped. Even when we click search Button in same view, bean is initialized again. Only RequestScope works fine.
Is there I misunderstand or forgot. PS.
Thanks in advance.
Do you have the correct SessionScoped? javax.enterprise.context.SessionScoped
Do you have Myfaces CODI or any other adapter on the classpath? Otherwise #ViewScoped has undocumented behavior since it is a JSF-2 scope.
If you have the correct #SessionScoped the behavior noted is completely unknown problem for me at least.
Also:
#Named(value = "adminLogView")
the value you give here is what it would default to. Might as well skip setting value like that.
Good luck
#javax.faces.bean.ViewScoped can't work with CDI. for that reason you need to use SeamFaces or MyFaces CODI to benefit from the viewscope services.
CDI offers extensions to create your own scope so you can implement the context and use the #NormalScope to do this.
CDI fires an event AfterBeanDiscovery after each bean call
You can use CDI extension to #Observes this event and add your context implementation
In your scope implementation you can :
Use Contextual to get your bean by its name from FacesContext ViewRoot Map and return it after each ajax call back
Use CreationalContext if the bean name from first step is not found to create it in the FacesContext ViewRoot Map
for a more in-depth explanation i recommand this link : http://www.verborgh.be/articles/2010/01/06/porting-the-viewscoped-jsf-annotation-to-cdi/