how to create multiple jsf datatable on click of command button - jsf

as per my requirement I have to create multiple blank datatable in ui on click of a button .
user can continuously add more tables on click .
as per my understanding I can add one datatable and can iterate over collection but how to add more.
<h:commandButton immediate="true" styleClass="search_btn" value="Search" >
<f:ajax listener="#{relationBean.searchRelation}" event="click" />
</h:commandButton>
<h:commandButton immediate="true" value="Add Value">
<f:ajax listener="#{relationBean.addTable}" execute="relationId" event="click" />
</h:commandButton>
<div class="clear"> </div>
<h:dataTable rendered="#{relationBean.flagForDatatable}" value="# {relationBean.elementRelationList}" var="element">
<h:column>
<f:facet name="header"> Relation Type Name</f:facet>
<h:outputText value="#{element.relationType}" />
</h:column>
<h:column>
<f:facet name="header"> Value</f:facet>
<h:inputText value="#{element.relationForm}" />
</h:column>
<h:column>
<f:facet name="header">language</f:facet>
<h:outputText value="#{element.languageCode.languageName}" />
</h:column>
<h:column>
<f:facet name="header"> Delete</f:facet>
<h:commandButton value="Delete" />
</h:column>
</h:dataTable>

You can just use <ui:repeat> to iterate over a collection and render the same JSF component structure multiple times.
<ui:repeat value="#{bean.datatables}" var="datatable">
<h:dataTable value="#{datatable.value}" var="item">
...
</h:dataTable>
</ui:repeat>
In the command button, just add a new item to the collection behind #{bean.datatables}.

Belwo is the applied logic
<h:inputText id="relationId" class="relationship" value="#{relationBean.relationName}" required="true" requiredMessage="Enter relation">
<f:ajax></f:ajax>
</h:inputText> </div>
<h:commandButton styleClass="search_btn" >
<f:ajax listener="#{relationBean.searchRelation}" event="click" render="addBtn" execute="#all"/>
</h:commandButton>
<h:messages id="msgGlobal" globalOnly="true"/>
<h:commandButton id="addBtn" disabled="#{relationBean.showButton}" class="addvalue" value="Add Value">
<f:ajax listener="#{relationBean.addValue}" render="r" event="click" />
</h:commandButton>
<div class="clear"> </div>
<h:panelGroup id="r" >
<c:forEach id="repeat" items="#{relationBean.datatables}" var="">
<h:dataTable id="datatable" value="#{relationBean.languageDTOList}" var="lang">
<h:column>
<f:facet name="header"> Relation Type Name</f:facet>
<h:outputText value="#{relationBean.relationName}" />
</h:column>
<h:column>
<f:facet name="header"> Value</f:facet>
<h:inputText />
</h:column>
<h:column>
<f:facet name="header">language</f:facet>
<h:outputText value="#{lang.languageName}" />
</h:column>
<h:column>
<f:facet name="header"> Delete</f:facet>
<h:commandButton styleClass="remove_icon" value="Delete" >
</h:commandButton>
</h:column>

Related

JSF crud popup opens before value gets submitted

In my crud application I want to select a row and then display that row data in a popup. navigating to another page works and it displays the data. when I try to display it in my popup no values are displayed. I could be wrong but I think the popup opens before the method prepareView is done.
code block:
<h:column>
<f:facet name="header">
<h:outputText value=" "/>
</f:facet>
<h:commandLink id="myLink" value="Action" action="#{timeLoggingDetailController.prepareView}" rendered="#{item.timeLoggingId eq AdminTimeLogging.filteredId}" styleClass="auto-style5">
<rich:componentControl target="popup" operation="show"/>
</h:commandLink>
</h:column>
</h:dataTable>
</h:panelGroup>
</h:form>
<rich:popupPanel id="popup" modal="false" autosized="true" resizeable="false" domElementAttachment="form">
<f:facet name="header">
<h:outputText value="Approval level" />
</f:facet>
<f:facet name="controls">
<h:outputLink value="#" onclick="#{rich:component('popup')}.hide();
return false;">
Close
</h:outputLink>
</f:facet>
<h:form id="submitForm">
<h:panelGrid columns="2">
<h:outputText value="#{bundle.ViewTimeLoggingDetailLabel_date}"/>
<h:outputText value="#{timeLoggingDetailController.selected.date}" title="#{bundle.ViewTimeLoggingDetailTitle_date}">
<f:convertDateTime pattern="MM/dd/yyyy" />
</h:outputText>
<h:outputText value="#{bundle.ViewTimeLoggingDetailLabel_description}"/>
<h:outputText value="#{timeLoggingDetailController.selected.description}" title="#{bundle.ViewTimeLoggingDetailTitle_description}"/>
<h:outputText value="#{bundle.ViewTimeLoggingDetailLabel_normalHours}"/>
<h:outputText value="#{timeLoggingDetailController.selected.normalHours}" title="#{bundle.ViewTimeLoggingDetailTitle_normalHours}"/>
<h:outputText value="#{bundle.ViewTimeLoggingDetailLabel_overtimeHours}"/>
<h:outputText value="#{timeLoggingDetailController.selected.overtimeHours}" title="#{bundle.ViewTimeLoggingDetailTitle_overtimeHours}"/>
<h:outputText value="#{bundle.ViewTimeLoggingDetailLabel_doubleTimeHours}"/>
<h:outputText value="#{timeLoggingDetailController.selected.doubleTimeHours}" title="#{bundle.ViewTimeLoggingDetailTitle_doubleTimeHours}"/>
<h:outputText value="#{bundle.ViewTimeLoggingDetailLabel_approvalLevelsId}"/>
<h:outputText value="#{timeLoggingDetailController.selected.approvalLevelsId}" title="#{bundle.ViewTimeLoggingDetailTitle_approvalLevelsId}"/>
</h:panelGrid>
<br />
<h:panelGrid class="auto-style4">
<h:commandLink action="#{timeLoggingDetailController.update}" value="#{bundle.EditTimeLoggingDetailSaveLink}" onclick="#{rich:component('popup')}.hide();" styleClass="linkbutton"/>
</h:panelGrid>
</h:form>
</rich:popupPanel>
</ui:define>
</ui:composition>
</html>
You may want to use <a4j:commandLink>, it provides oncomplete event which is fired when the action completes.
This should work for you:
<a4j:commandLink id="myLink" value="Action" actionListener="#{timeLoggingDetailController.prepareView}" rendered="#{item.timeLoggingId eq AdminTimeLogging.filteredId}" styleClass="auto-style5">
<rich:componentControl event="complete" target="popup" operation="show"/>
</a4j:commandLink>

jsf page not refreshed on commandlink click

I want to refresh page on click of activate/deactivate command link,
I used so many tricks but its not getting refresh(fully or partially)
Below is my datatable
<h:panelGroup id="r" >
<h:dataTable id="datatableIterator" value="#{relationBean.datatables}" var="datatable" cellspacing="1" cellpadding="0" border="1" class="role_detail_section">
<h:column>
<h:dataTable id="relationIterator" value="#{datatable}" var="item" binding="#{bind}">
<h:column>
<f:facet name="header"> Relation Type Name</f:facet>
<h:outputText value="#{item.relationType}" />
</h:column>
<h:column>
<f:facet name="header">language</f:facet>
<h:outputText value="#{item.language.languageName}" />
</h:column>
<h:column>
<f:facet name="header"> Value</f:facet>
<h:inputText value="#{item.relationForm}" />
</h:column>
<h:column>
<h:panelGroup rendered="#{bind.rowIndex eq 0}" id="rrr" >
<p:commandLink ajax="true" action="#{relationBean.deactivateRelationById(item.relationId)}" rendered="#{item.status.statusId==3}" value="Deativate" update="#form rrr" process="#this">
</p:commandLink>
<p:commandLink ajax="true" action="#{relationBean.activateRelationById(item.relationId)}" rendered="#{item.status.statusId==1}" value="Activate" update="#form rrr" process="#this">
</p:commandLink>
</h:panelGroup>
</h:column>
</h:dataTable>
</h:column>
<h:column>
<f:facet name="header">Delete</f:facet>
<p:commandLink action="#{relationBean.deleteDataTable}" immediate="true" update="#form" process="#this" ajax="true">
<h:graphicImage value="../images/delete.png" />
<f:setPropertyActionListener target="#{relationBean.deleteId}" value="#{datatable}" />
</p:commandLink>
</h:column>
My bean is viewScoped
changes are reflects once I press f5 manually.

Rerendered components don't work properly

I am creating a view in JSF where after executing some action with a4j:commandButton some elements are rerendered. For example I click on a button which invokes a backing bean method such as executeProcess (this adds a process to a list), and when it finishes updates a data table (shows the available processes). The data table also has some other buttons to execute specific actions over every process, but when I press one of this the page seems to reload entirely without invoking the action, then if I press the same button again it works. What is happening?
Component List an execute:
<div class="line_left" style="float:right">
<a4j:outputPanel id="execProcessPanel" layout="block"
ajaxRendered="true">
<ui:fragment rendered="#{tapeTapeForm.size > 0}">
<h:form id="executeProcess">
<h:outputText value="Ejecuta Proceso" />
<br />
<h:outputLabel id="inputFilesLabel" for="inputFile" value="Archivo" />
<h:selectOneListbox id="inputFile" size="5" required="true"
requiredMessage="Debes seleccionar un archivo"
value="#{tapeTapeForm.inputFile}">
<f:selectItems value="#{tapeTapeForm.inputFiles}" var="file"
itemLabel="#{file}" itemValue="#{file}" />
</h:selectOneListbox>
<br />
<h:message for="inputFile" errorClass="" />
<br />
<a4j:commandButton value="Ejecutar" styleClass="button"
action="#{tapeTapeForm.executeProcess}"
render="resultListPanel execProcessPanel messages"
limitRender="true">
<f:setPropertyActionListener value="0"
target="#{tapeTapeForm.tipoProceso}" />
</a4j:commandButton>
<a4j:commandButton value="Revisión" styleClass="button"
action="#{tapeTapeForm.executeProcess}"
render="resultListPanel execProcessPanel messages"
limitRender="true">
<f:setPropertyActionListener value="1"
target="#{tapeTapeForm.tipoProceso}" />
</a4j:commandButton>
</h:form>
</ui:fragment>
</a4j:outputPanel>
</div>
Component Data Table:
<a4j:outputPanel id="resultListPanel" layout="block"
ajaxRendered="true">
<h2>
<h:outputText value="Listado de Procesos Tape to Tape" />
</h2>
<rich:dataTable id="resultList" var="item" rows="0"
value="#{tapeTapeForm.processes}" noDataLabel="Sin Procesos">
<rich:column sortable="true" sortBy="#{item.id}">
<f:facet name="header">
<h:outputText value="ID" />
</f:facet>
<center>
<h:outputText value="#{item.id}" />
</center>
</rich:column>
<rich:column>
<f:facet name="header">
<h:outputText value="Nombre Archivo" />
</f:facet>
<center>
<h:outputText value="#{item.inputFileName}" />
</center>
</rich:column>
<rich:column>
<f:facet name="header">
<h:outputText value="Archivo Salida" />
</f:facet>
<center>
<h:outputText value="#{item.outputFileName}"
title="Clic para descargar el archivo de salida" />
</center>
</rich:column>
<rich:column>
<f:facet name="header">
<h:outputText value="Tipo Proceso" />
</f:facet>
<center>
<h:outputText value="Reporte"
title="Este proceso generará un reporte"
rendered="#{item.tipoProceso == 0}" />
<h:outputText value="Revisión"
title="Se realizará una revisión del archivo"
rendered="#{item.tipoProceso == 1}" />
</center>
</rich:column>
<rich:column>
<f:facet name="header">
<h:outputText value="Estatus" />
</f:facet>
<center>
<h:outputText value="#{item.status.description}"
title="#{item.status.detail}" />
</center>
</rich:column>
<rich:column>
<f:facet name="header">
<h:outputText value="Progreso" />
</f:facet>
<rich:progressBar value="#{item.avance}" minValue="0"
enabled="false" rendered="#{item.status.id == 3}"
maxValue="#{item.total}" label="#{item.avance} / #{item.total}" />
</rich:column>
<rich:column>
<f:facet name="header">
<h:outputText value="Detener" />
</f:facet>
<h:form rendered="#{item.status.id == 2 or item.status.id==3}">
<h:commandLink action="#{tapeTapeForm.stopProcess}" value="STOP"
onclick="#{rich:component('ajaxLoadingModalBox')}.show()">
<f:setPropertyActionListener target="#{tapeTapeForm.id}"
value="#{item.id}" />
</h:commandLink>
</h:form>
</rich:column>
<rich:column>
<f:facet name="header">
<h:outputText value="Eliminar" />
</f:facet>
<h:form rendered="#{item.status.id !=2 and item.status.id != 3}">
<h:commandLink action="#{tapeTapeForm.removeProcess}"
value="ELIMINAR">
<f:setPropertyActionListener target="#{tapeTapeForm.id}"
value="#{item.id}" />
</h:commandLink>
</h:form>
</rich:column>
</rich:dataTable>
</a4j:outputPanel>
I'm using RichFaces 4.2.2
Get rid of the multiple forms, wrap everything in one and then use if you need to limit the scope of execution.

Can not save the changes made in a datatable

So I have the following table:
<h:dataTable id="shoppingCartTable" value="#{cartBean.shoppingCartList}" var="shoppingCartItem" width="100%" >
<h:column>
<f:facet name="header">
<h:outputText value="Item" />
</f:facet>
<h:commandLink value="#{shoppingCartItem.name}">
</h:commandLink><br/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Quantity" />
</f:facet>
<h:inputText id="quantity" value="#{shoppingCartItem.quantity}" size = "2" /><br/>
</h:column>
</h:dataTable>
With the following commandButton
<p:commandButton
value="Submit"
>
<f:ajax event="click"
execute="shoppingCartTable"
render="#all" />
</p:commandButton>
Now there is a lot of other stuff on the page and all I want to do is update the Quantity values of the shopping cart items but this does not seem to be working. Am I doing something wrong?
Try to replace f:ajax with p:commandButton attributes:
<p:commandButton value="Submit" update="#all" process="shoppingCartTable"/>

Why <h:dataTable> make all rows as same as "selected row" value?

I've ArrayList Collection carry the values properly , but the problem when i rendered it in h:dataTable tag the rows become all same value like in the picture.
<h:dataTable value="#{contactController.contacts }" var="contact"
rowClasses="oddRow, evenRow" styleClass="contactTable"
headerClass="headerTable" columnClasses="normal,centered"
rendered="#{not empty contactController.contacts }">
<h:column>
<f:facet name="header">
<h:column>
<h:outputText value="Name" />
</h:column>
</f:facet>
<h:outputText
value="#{contactController.contact.firstName }#{ contactController.contact.secondName }" />
</h:column>
<h:column>
<f:facet name="header">
<h:column>
<h:outputText value="Action" />
</h:column>
</f:facet>
<h:panelGrid columns="2">
<h:commandLink value="remove"
action="#{contactController.remove }">
<f:setPropertyActionListener value="#{contact }"
target="#{contactController.selectedContact }" />
</h:commandLink>
<h:commandLink value="edit" action="#{contactController.read}">
<f:setPropertyActionListener value="#{contact }"
target="#{contactController.selectedContact }" />
</h:commandLink>
</h:panelGrid>
</h:column>
</h:dataTable>
Any suggestion? .
I think there are two problems with your code.
First you don't need the bean's name in your columns. Simply use the content of the var attribute (in your case "contact" and not "contactController.contact")
Second: The h:column inside f:facet is not correct. Put the h:outputText directly into f:facet.
Change your first column this way:
<h:column>
<f:facet name="header">
<h:outputText value="Name" />
</f:facet>
<h:outputText value="#{contact.firstName} #{contact.secondName }" />
</h:column>

Resources