Contents of ui:repeat not updated with p:fileUpload - ajax

I am running a JSF2 web application with PrimeFaces 3.5 on GlassFish 3.1.2. I want to implement CSV import functionality, so that the read values are filled in to the components without page reload.
Technically, after a file upload with <p:fileUpload>, I want to update a component which creates the input fields iteratively with <ui:repeat>. Here is the simplified code of my view:
<ui:define name="content">
<h:form id="form" prependId="false" enctype="multipart/form-data">
<p:growl id="growl" showDetail="true" life="5000" />
<p:panel header="Values">
<h:panelGroup id="grid" layout="block">
<p:commandButton actionListener="#{table.handlePost}"
id="postTop" value="Save" update="growl" />
<p:commandButton id="dlTop" value="Export CSV" ajax="false"
onclick="PrimeFaces.monitorDownload(start, stop)"
icon="ui-icon-arrowthichk-s">
<p:fileDownload value="#{table.csv}" />
</p:commandButton>
<p:fileUpload fileUploadListener="#{table.handleFileUpload}"
mode="advanced" update="tableView, growl" sizeLimit="10000"
allowTypes="/(\.|\/)(csv)$/" label="Import CSV"
showButtons="false" />
<h:panelGroup id="tableView" layout="block">
<table>
<tr>
<th>Day</th>
<th>Value</th>
</tr>
<ui:repeat value="#{table.values}" varStatus="val" id="table">
<tr>
<td><h:outputText
value="#{table.date}-#{val.index+1}" /></td>
<td><h:inputText id="value"
value="#{table.values[val.index]}"
converter="javax.faces.Double" /></td>
</tr>
</ui:repeat>
</table>
</h:panelGroup>
<p:commandButton actionListener="#{table.handlePost}"
id="postBottom" value="Save" update="growl" />
<p:commandButton id="dlBottom" value="Export CSV" ajax="false"
onclick="PrimeFaces.monitorDownload(start, stop)"
icon="ui-icon-arrowthic hk-s">
<p:fileDownload value="#{table.csv}" />
</p:commandButton>
</h:panelGroup>
</p:panel>
</h:form>
</ui:define>
table bean:
#ViewScoped
#ManagedBean(name="table")
public class TableView { }
Values are read correctly, I can update any component to output table.values, except with <p:fileUpload>, contents of the <ui:repeat> are never updated. If I update tableView from any other component other than <p:fileUpload>, the contents of <ui:repeat> are updated correctly. What could be the problem?

I don't think the file upload component supports the ajax update tag, so you may have to do a full page refresh...you could do this in javascript by using: oncomplete="javascript:window.location.reload(true)"

Related

Page refresh calls the action listener function

I have a JSF application. In the home.xhtml, I have included 4 tabs. Each tab is a different xhtml form. The first form has an action listener. The problem is on all 4 tabs if I refresh (F5) the page, the action listener gets called.
On click of the command button, I check the DB to check if there are existing employees with the same details. If yes, I show the confirm dialog to proceed with Generation. If the user clicks Yes here, the new ID is generated. This generation function gets called again and again if I refresh the page. I made the call as ajax="false" as well but it does not help. If I make ajax="true", It does not let me change the tabs. The page sort of hangs. Please suggest me on how to stop this.
<h:form id="employeeIdGenerationForm" prependId="false">
<p:confirmDialog id="confirmationID" widgetVar="confirmationVar" header="Confirmation" showEffect="fade" hideEffect="explode"
message="#{employeeMaintenanceBean.employee.getWarningsList()}"
rendered="#{employeeMaintenanceBean.showExistingEmployeeWarning}" closable="false">
<p:commandButton value="Yes" styleClass="ui-confirmdialog-yes" icon="ui-icon-check" onclick="PF('confirmationVar').hide()"
actionListener="#{employeeMaintenanceBean.generateEmployeeID}" ajax="false"
update="#form:confirmation #form:msgPanel_EmployeeIDGeneration #form:firstName #form:surName" />
<p:commandButton value="No" styleClass="ui-confirmdialog-no" icon="ui-icon-close" onclick="PF('confirmationVar').hide()"/>
</p:confirmDialog>
<p:panel styleClass="messagePanel"
style="color: #004986; font-size: 15px;"
header="New Employee ID Generation">
<br />
<h:panelGrid columns="1" id="msgPanel_EmployeeIDGeneration"
width="100%" align="center" style="text-align:center;">
<p:messages />
</h:panelGrid>
<h:panelGrid columns="2" border="0">
<h:outputLabel styleClass="label" value="First Name" />
<p:inputText value="#{employeeMaintenanceBean.employee.firstName}"
id="firstName" required="true"
requiredMessage="First Name is mandatory" maxlength="50"
styleClass="value" />
<h:outputLabel styleClass="label" value="Last Name" />
<p:inputText value="#{employeeMaintenanceBean.employee.lastName}"
id="surName" required="true"
requiredMessage="Last Name is mandatory" maxlength="50"
styleClass="value" />
<h:outputLabel styleClass="label" value="Comments" />
<p:inputTextarea
value="#{employeeMaintenanceBean.employee.comments}" id="comments"
maxlength="256" styleClass="value" />
<p:commandButton id="generateID" ajax="false"
actionListener="#{employeeMaintenanceBean.isExistingEmployee}"
title="Generate Employee ID" value="Generate Employee ID" update="#form:confirmationID #form:msgPanel_EmployeeIDGeneration">
</p:commandButton>
</h:panelGrid>
</p:panel>
</h:form>
The main home.xhtml is:
<h:head/>
<h:body>
<ui:composition template="/template/common/commonLayout.xhtml">
<ui:define name="content">
<p:idleMonitor timeout="300000">
<p:ajax event="idle" listener="#{baseBean.sessionTimeOut}"/>
</p:idleMonitor>
<p:tabView id="tabView" activeIndex="#{tabViewBean.mainTabActiveIndex}" dynamic="true" cache="false">
<p:ajax event="tabChange" listener="#{tabViewBean.onMainTabChange}" update="tabView" />
<p:tab id="employeeIdGeneration" title="New Employee ID Generation" rendered="#{tabViewBean.currentUser.hasAccessToPage('employeeIdGeneration')}">
<ui:include src="employeeIdGeneration.xhtml"/>
</p:tab>
<p:tab id="employeeMaintenance" title="Update New Employee Details" rendered="#{tabViewBean.currentUser.hasAccessToPage('employeeMaintenance')}">
<ui:include src="employeeIdMaintenance.xhtml"/>
</p:tab>
<p:tab id="employeeHistoryView" title="New Employee Update History" rendered="#{tabViewBean.currentUser.hasAccessToPage('employeeHistoryView')}">
<ui:include src="employeeHistoryView.xhtml"/>
</p:tab>
<p:tab id="userAccessMaintenance" title="User Access Maintenance" rendered="#{tabViewBean.currentUser.hasAccessToPage('userAccessMaintenance')}">
<ui:include src="userMaintenance.xhtml"/>
</p:tab>
</p:tabView>
</ui:define>
</ui:composition>
</h:body>

p:ajaxStatus does not receive oncomplete event from lazy datatable

I'm using Primefaces 3.5 and trying to display a "loading" image while updating a lazy-loaded datatable. In the following AjaxStatus element, the "ajax-loader" image is displayed when datatable is updated by a commandButton action. However when ajax call and table update is completed, the image does not disappear. In other words onComplete event is not received.
<p:ajaxStatus style="width:260px;" id="ajaxStatusPanel">
<f:facet name="start">
<h:graphicImage value="../images/ajax-loader.gif" />
</f:facet>
<f:facet name="complete">
<h:outputText value="" />
</f:facet>
</p:ajaxStatus>
Here is a portion of the form that contains the commandButton and the datatable:
<h:form>
<p:panel toggleable="true" toggleSpeed="300" header="FILTER RESULTS">
<table align="center">
<tr>
<td>NAME: </td>
<td><h:inputText value="#{personBean.personLazyData.paramName}" /></td>
</tr>
<tr>
<td>PLACE OF BIRTH : </td>
<td><h:inputText value="#{personBean.personLazyData.paramPlaceOfBirth}" /></td>
</tr>
<tr>
<td colspan="2" align="center">
<p:commandButton value="Update" global="true"
actionListener="#{personBean.onFilterChanged}"
update="personListTable"/>
</td>
</tr>
</table>
</p:panel>
<p:dataTable id="personListTable" rendered="#{personBean.superUser}" var="person"
value="#{personBean.personLazyData}" emptyMessage="Not found."
paginator="true" rows="20" lazy="true" selection="#{personBean.selectedPersons}" global="true"
paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
rowsPerPageTemplate="20,50,100">
<f:facet name="header">SURVEYS</f:facet>
<p:column selectionMode="multiple" style="width:2%" />
<p:column headerText="ID" >
<h:outputText value="#{person.id}"/>
</p:column>
<p:column headerText="NAME" >
<h:outputText value="#{person.name}"/>
</p:column>
<p:column headerText="SURNAME" >
<h:outputText value="#{person.surname}" />
</p:column>
</p:dataTable>
Is there anybody who have faced a similar issue?
Another note: In cases where datatable is not rendered (or if I change rendered attribute to false), the loading image is displayed and disappeared for a very short while since no data is retrieved.
The issue is resolved when I updated primefaces version to 4.0

how i get clicked CommandLink id in Controller in JSF?

<ui:repeat value="#{prodCtr.paginator.model}" var="o">
<h:form>
<h:commandLink id="#{o.id}" action="ModelInfo.xhtml" actionListener="#{prodCtr.listener}">
<h:panelGrid columns="1" style="border: #ffffff">
<img src="resources/images/#{o.id}.jpg" style="width: 100px;height: 100px"/>
<h:outputLabel value="#{o.price} YTL" style="font-size: 12px;font-family: Georgia, Serif;color: #ff3300" />
<h:commandButton value="Sifaris et" class="button"/>
</h:panelGrid>
</h:commandLink>
</h:form>
</ui:repeat>
java.lang.IllegalArgumentException caught during processing of RENDER_RESPONSE 6 : UIComponent-ClientId=, Message=Empty id attribute is not allowed here
How can i CommandLink id dinamically?Is there an other way?
You don't need to specify the id attribute for the child components when using the <ui:repeat/> tag. It automatically does this.
If you do want to be in control of the id attribute, <ui:repeat/> is the wrong one to use for that. The reason is that at point in time that the components are being placed in the UIViewroot (essentially when the page is being constructed for the first time), the <ui:repeat/> component is not active, i.e. it's not being processed. So the var="o" is not available to the runtime and so nothing is available to be used as id.
To be in control of the id, you should be using the <c:forEach/> tag instead. Your code should look like this:
<c:forEach items="#{prodCtr.paginator.model}" var="o">
<h:form>
<h:commandLink id="#{o.id}" action="ModelInfo.xhtml" actionListener="#{prodCtr.listener}">
<h:panelGrid columns="1" style="border: #ffffff">
<img src="resources/images/#{o.id}.jpg" style="width: 100px;height: 100px"/>
<h:outputLabel value="#{o.price} YTL" style="font-size: 12px;font-family: Georgia, Serif;color: #ff3300" />
<h:commandButton value="Sifaris et" class="button"/>
</h:panelGrid>
</h:commandLink>
</h:form>
</c:forEach>

To refresh another JSF page on submit from one page

I am trying to add records to datatable by submitting a form built using JSF and primefaces which gets popped up from the page containing datatable.On submit of the form the data gets updated to database but i need to refresh/update the datatable with the submitted data.Is there any way using which i can refer the main page on submit from the form so that i can refresh/update the datatable.
JSF code snippet containing datatable
<h:form id="lpcForm">
<!-- <p:growl id="messages" showDetail="true" /> -->
<div id="content">
<h:commandLink ajax="true" id="cmdLinkAdd" value="Add" action="#{lpcBean.addRecord}"
target="_blank" update="#form" process="#this" />
<p:dataTable var="lpcData" id="lpcDataTable" widgetVar="lpcTable"
value="#{lpcBean.lpcIdList}" selection="#{lpcBean.selectedRows}"
editable="true" scrollable="true" scrollWidth="1110"
scrollHeight="330" styleClass="datatable">
<!--Contents of the table-->
</p:dataTable>
</div>
On clicking the command link i get the web page popup through which i can submit the data,the snippet of which is as below
<h:form id="addLpc">
<p:focus context="addLpc" />
<div align="center">
<h:panelGrid id="addLpcForm" columns="3" >
contents of the form
</h:panelGrid>
</div>
<div align="center">
<p:commandButton id="submitButton" value="Submit" ajax="true"
action="#{lpcRecordAddition.formSubmit}" />
<h:outputText />
</div>
</h:form>
on submit of this form i need the datatable in other page to get updated.
Use the following for the commandButton:
<p:commandButton id="submitButton" value="Submit" ajax="true"
action="#{lpcRecordAddition.formSubmit}" update=":lpcForm:lpcDataTable" />

Ajax not working with primefaces

In my JSF page I have form when I click submit button in the same page I need to show an static content. But When I click <p:commandbutton> nothing appears in the page. When I put ajax="false" then only action taken place but the Static content display in new page.
In my Backing bean I have used Session scoped. I am using JSF 2.0 and Primefaces 3.2.
My JSF Page.
<h:form>
<h:panelGroup rendered="#{not license.showForm}">
<p:panel header="License Key Request" >
<h:panelGrid columns="2" >
..
<h:outputText value="Bla bla"/>
..
<h:outputText value="Bla Bla" />
</h:panelGrid>
<TABLE>
..
<h:outputLabel for="name" value="Requestor Name : *" />
..
<p:inputText id="name" value="#{license.name}" required="true" requiredMessage="Name is required."/>
..
<h:outputLabel for="company" value="Company : * " />
..
<p:inputText id="company" value="#{license.company}" required="true" requiredMessage="Company is required."/>
..
</table>
<p:commandButton value="Form" id="btnAdd" process="#form"
action="#{license.add}" />
..
</table>
</p:panel>
</h:panelGroup>
<h:panelGroup rendered="#{license.showForm}" >
<h:outputText value="Bla Bla"/>
</h:panelGroup>
</h:form>
Your source code is somewhat confusing (e.g. you have two closing table tags). But I assume that you want to show the panelGroup at the bottom if the button is clicked.
The easiest way would be to add an update ="#form" to your commandButton:
<p:commandButton value="Form" id="btnAdd"
process="#form" update="#form"
action="#{license.add}" />
You don't need to update the whole form but only the specific component. Then you need to give the panelGroup an id attribute and use this attribute instead of #form. However, since it is not clear for me how your naming containers are organized, it could be puzzling to find the correct relative id.

Resources