I have a datatable which has a "delete" button at each row,
and I want to re-render the table when the data at the row is deleted.
But I can not make f:ajax work properly.
Here is the datatable at facelet page:
<h:form>
<h:dataTable value="#{adminPanelBean.activitiesList}" var="activityItem" id="allActivities"
styleClass="datatable" cellpadding="2" cellspacing="4"
columnClasses="ColName,colType,colTime,colPlace,colSummary" >
<h:column>
<f:facet name="header">
<h:outputText value="Etkinlik"/>
</f:facet>
<h:outputText value="#{activityItem.name} "/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Türü"/>
</f:facet>
<h:outputText value="#{activityItem.type}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Tarih "/>
</f:facet>
<h:outputText value="#{activityItem.time}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Yer "/>
</f:facet>
<h:outputText value="#{activityItem.place}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Açıklama "/>
</f:facet>
<h:outputText value="#{activityItem.summary}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value=" "/>
</f:facet>
**<h:commandButton value="Delete activity" onclick="if(confirm(' Delete #{activityItem.name} ?'))return true; else return false;" action="#{adminPanelBean.deleteActivity(activityItem.id)}">
<f:ajax event="click" render="allActivities" execute="#all" immediate="true"/>
<f:param name="activityId" value ="#{activityItem.id}" />
</h:commandButton>**
</h:column>
</h:dataTable>
</h:form>
When I refresh the page, I see the row is deleted. But I want it to be done dynamically.
In the action method you need to remove the item from the list as well (and thus not only from the DB). I'd suggest to pass the whole item instead of only the ID so that you can utilize List#remove() method.
action="#{adminPanelBean.deleteActivity(activityItem)}">
So that you can do
public void deleteActivity(Activity activity) {
activitiesList.remove(activity);
// ...
}
Unrelated to the concrete problem, they way how you used confirm() is pretty clumsy.
onclick="if(confirm(' Delete #{activityItem.name} ?'))return true; else return false;"
That function returns a boolean already. You do not need to test the obtained boolean within an if in order to return another boolean. Just simplify it as follows:
onclick="return confirm('Delete #{activityItem.name}?')"
Related
In an application based on Seam 2.2.1, JSF 1.2, Richfaces 3.3.3, I have a datatable with clickable rows.
In the last column, I have an icon (trash). Clicking here should execute a different method (delete). The standard onRowClick event should not apply.
Is there any easy way to accomplish this?
<rich:panel headerClass="panelHeader" styleClass="panel">
<f:facet name="header">Header</f:facet>
<rich:dataTable id="myTable" value="#{myModel}" var="k">
<a4j:support event="onRowClick" action="#{myAction.selectItem(k, facesContext.viewRoot.viewId)}"
reRender="myTable"/>
<rich:column>
<f:facet name="header">
<h:outputText value="Normal Column - should be clickable"/>
</f:facet>
<h:outputText value="#{k.name}"/>
</rich:column>
<rich:column >
<f:facet name="header">
<h:outputText value="Only Click on Icon should react to Mouseclick"/>
</f:facet>
<s:graphicImage value="/img/bin_closed.gif">
<a4j:support event="onclick"
action="#{myAction.deleteItem(k)}"
reRender="myTable"
ajaxSingle="true" limitToList="true"
onsubmit="if(!confirm('Really?')) { return false; }" />/>
</s:graphicImage>
</rich:column>
</rich:dataTable>
</rich:panel>
I found the solution to my problem. For the column that contains the icon, I put the icon into another <a4j:outputPanel element like this: `
Now, only the action method is executed when clicking on the icon.
Here is the full solution:
<rich:panel headerClass="panelHeader" styleClass="panel">
<f:facet name="header">Header</f:facet>
<rich:dataTable id="myTable" value="#{myModel}" var="k">
<a4j:support event="onRowClick" action="#{myAction.selectItem(k, facesContext.viewRoot.viewId)}"
reRender="myTable"/>
<rich:column>
<f:facet name="header">
<h:outputText value="Normal Column - should be clickable"/>
</f:facet>
<h:outputText value="#{k.name}"/>
</rich:column>
<rich:column >
<f:facet name="header">
<h:outputText value="Only Click on Icon should react to Mouseclick"/>
</f:facet>
<a4j:outputPanel onclick="event.stopPropagation()">
<s:graphicImage value="/img/bin_closed.gif">
<a4j:support event="onclick"
action="#{myAction.deleteItem(k)}"
ajaxSingle="true" limitToList="true"
onsubmit="if(!confirm('Really?')) { return false; }" />/>
</s:graphicImage>
</a4j:outputPanel>
</rich:column>
</rich:dataTable>
</rich:panel>
I have a primefaces datatable with the attribute editable="true" so I can't edit the rows dynamically. I have two fields: an inputText and a selectOneMenu. I want to be able to add rows dynamically from the footer. I added empty field in the footer and when the user click a button, I want to add the new line to the datatable with the correct values.
Here is the code I have:
<h:form>
...
<p:dataTable value="#{bean.myObjects}" id="myDatatable" editable="true" var="obj">
<f:facet name="header">
<h:outputText value="My Datatable" />
</f:facet>
<p:column headerText="My String value">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{obj.myString}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{obj.myString}"/>
</f:facet>
</p:cellEditor>
<f:facet name="footer">
<h:inputText value="#{bean.myNewObject.myString}" />
</f:facet>
</p:column>
<p:column headerText="My List Value">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{bean.myListValue ? 'yes' : 'no'}" />
</f:facet>
<f:facet name="input">
<h:selectOneMenu value="#{bean.myListValue}" >
<f:selectItem itemValue="true" itemLabel="yes" />
<f:selectItem itemValue="false" itemLabel="no" />
</h:selectOneMenu>
</f:facet>
</p:cellEditor>
<f:facet name="footer">
<h:selectOneMenu value="#{bean.myNewObject.myListValue}" >
<f:selectItem itemValue="true" itemLabel="yes" />
<f:selectItem itemValue="false" itemLabel="no" />
</h:selectOneMenu>
</f:facet>
</p:column>
<p:column>
<p:rowEditor />
<f:facet name="footer">
<h:commandButton actionListener="#{bean.addRow}">
<f:ajax execute="myDatatable" render="myDatatable" />
</h:commandButton>
</f:facet>
</p:column>
</p:dataTable>
...
</h:form>
In my bean, I just have this for the addRow method:
public void addRow() {
this.myObjects.add(this.myNewObject);
this.myNewObject = new MyObject();
}
and the init:
#PostConstruct
public void init() {
this.myObjects = Controller.getAllMyObjects();
this.myNewObject = new MyObject();
}
I could precise that the bean is in ViewScope. The result is that the line is added, the string value is correct but the list value is always "no" even if I set it to true with this.myNewObject.setMyListValue(true) in the bean after instanciate the object.
I know that this is something with to render or the execute of attributes.
If I change the line:
<f:ajax execute="myDatatable" render="myDatatable" />
to:
<p:ajax update="#form" />
the list value is true but the string value is not set.
How to be sure that both of my attribute are rendered and how can I get there values without submiting the whole form?
Thanks
Is it possible to place a button inside of a header of a panel?
What I've read the following should work, but I haven't been able to get it to work.
<p:panel id="panel">
<f:facet name="header">
<p:commandButton value="Click"/>
</f:facet>
<p:panel>
Thanks to all who can help
Replace header to actions
<p:panel>
<f:facet name="actions">
<p:commandButton value="Click"/>
</f:facet>
<p:panel>
<h:form>
<p:panel id="panel">
<f:facet name="header">
<p:commandButton value="Click"/>
</f:facet>
</p:panel>
</h:form>
Try this, in header or footer...
<f:facet name="footer">
<p:commandButton value="Update Total" update="tabla_gral" styleClass="ui-priority-primary" id="ajax2" actionListener="#{consumoMaterial.actualizarSaldos}"/>
</f:facet>
I have a requirement like " On selection of catalog, I would like to fetch the data from database. One of catalog is having very huge data like (25000 and above records. To get these records from db and display in fronted I am using JSF dataTable tag". As mentioned below. But this is taking more and more time. Some times page is also getting timed out. can any body help me.
enter code here
<h:column>
<f:facet name="header">
<h:outputText value="Sr.No." />
</f:facet>``
<h:outputText value=" #{PromoCodeDefinitionBean.table.rowIndex+1}" styleClass="blackboldSmall" />
</h:column>
<h:column rendered="#{PromoCodeDefinitionBean.except}">
<f:facet name="header">
<h:selectOneMenu id="useCountAll" onchange="changeValue();">
<h:outputText value="Use Count " />
<f:selectItem itemLabel="Count" itemValue=""/>
<f:selectItem itemLabel="1" itemValue="1"/>
<f:selectItem itemLabel="2" itemValue="2"/>
<f:selectItem itemLabel="3" itemValue="3"/>
<f:selectItem itemLabel="4" itemValue="4"/>
<f:selectItem itemLabel="5" itemValue="5"/>
</h:selectOneMenu>
</f:facet>
<h:inputText id="useCount" binding="#{PromoCodeDefinitionBean.userCount}" value="#{output.checkvalue}" size="2" styleClass="mandFieldClass"></h:inputText>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="User Name" />
</f:facet>
<h:outputText value=" #{output.userName}" styleClass="blackboldSmall" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Email" />
</f:facet>
<h:outputText value=" #{output.emailId}" styleClass="blackboldSmall" />
<h:inputHidden id="emailId" binding="#{PromoCodeDefinitionBean.email}" value="#{output.emailId}"></h:inputHidden>
</h:column>
<h:column rendered="#{PromoCodeDefinitionBean.except}">
<f:facet name="header">
<h:selectBooleanCheckbox id="BulkMovementAll" onclick="checkUncheckAll();" ><h:outputText value="Select All " />
<br></h:selectBooleanCheckbox>
</f:facet>
<h:selectBooleanCheckbox binding="#{PromoCodeDefinitionBean.checkedSelectedUser}" value="#{output.ischecked}" id="BulkMovement" onclick="test1(this.id)" />
<h:outputText id="checkboxvalue1" value="#{output.ischecked}" style="display: none; text-align:center;" />
</h:column>
</h:dataTable>
Please help me to improve my displaying logic.
Thanks in advance.
You can use Paginator & only fetch few records(e.g 10 rows) at a time & give user option to scroll over the pages.
I would like to update a component showing data related to the info displayed in the current page of a primefaces dataTable but I couldn't find any info about intercepting ajax events like
onRowsPerPageChange or onPageChanged.
Is there any way to do that?
Using primefaces 3.0.M3 and Glassfish 3.1
Here is my table. The component I want to update is another dataTable inside the footer of the first one:
<p:dataTable id="timbrature_dt"
value="#{timbratureMBean.dataModel}"
paginator="true"
rows="12"
lazy="true"
paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
rowsPerPageTemplate="6,12,24"
currentPageReportTemplate="#{msgs.pagina} {currentPage} #{msgs.of} {totalPages}"
var="tdett"
widgetVar="ttable"
selection="#{timbratureMBean.selezione}"
selectionMode="single">
<p:ajax event="rowSelect" listener="#{timbratureMBean.onRowSelect}"
update="display :timbrature_dt:giustificativi_dt"
oncomplete="timbDialog.show()" />
<f:facet name="header">
<h:panelGrid columns="1" columnClasses="columnclass-noborders">
<p:outputPanel>
<h:outputText value="#{msgs.dal}: " />
<p:calendar value="#{timbratureMBean.daData}"
pattern="dd/MM/yyyy"
locale="it"
showButtonPanel="true"
navigator="true"
mindate="01/01/2003"
maxdate="#{timbratureMBean.oggi}">
<p:ajax event="dateSelect" listener="#{timbratureMBean.dataChangeListener}"
update="timbrature_dt :timbrature_dt:giustificativi_dt" />
</p:calendar>
<h:outputText value=" #{msgs.al}: " />
<p:calendar value="#{timbratureMBean.aData}"
pattern="dd/MM/yyyy"
locale="it"
showButtonPanel="true"
navigator="true"
mindate="01/01/2003"
maxdate="#{timbratureMBean.oggi}">
<p:ajax event="dateSelect" listener="#{timbratureMBean.dataChangeListener}"
update="timbrature_dt :timbrature_dt:giustificativi_dt" />
</p:calendar>
</p:outputPanel>
<h:outputText value="#{msgs.timbrature}"/>
</h:panelGrid>
</f:facet>
<p:column>
<f:facet name="header">
#{msgs.data_comp}
</f:facet>
<amp:outputData value="#{tdett.sDtComp}"/>
</p:column>
<p:column>
<f:facet name="header">
#{msgs.data_reale}
</f:facet>
<amp:outputData value="#{tdett.sDtTimb}"/>
</p:column>
<p:column>
<f:facet name="header">
#{msgs.terminale}
</f:facet>
<h:outputText value="#{tdett.nrTer}"/>
</p:column>
<p:column filterBy="#{tdett.eU}" filterOptions="#{timbratureMBean.euOptionList}">
<f:facet name="header">
#{msgs.verso}
</f:facet>
<h:panelGroup>
<h:outputText value="#{msgs.entrata}" rendered="#{tdett.eU == 'E'}"/>
<h:outputText value="#{msgs.uscita}" rendered="#{tdett.eU == 'U'}"/>
</h:panelGroup>
</p:column>
<p:column>
<f:facet name="header">
#{msgs.ora_valida}
</f:facet>
<h:outputText value="#{tdett.oraValida}"/>
</p:column>
<p:column>
<f:facet name="header">
#{msgs.ora_reale}
</f:facet>
<h:outputText value="#{tdett.oraReale}"/>
</p:column>
<f:facet name="footer">
<p:dataTable id="giustificativi_dt"
value="#{timbratureMBean.dataList}"
var="gius"
widgetVar="gtable">
<f:facet name="header">
<h:panelGrid columns="1" columnClasses="columnclass-noborders">
<h:outputText value="#{msgs.giustificativi}"/>
</h:panelGrid>
</f:facet>
<p:column>
<f:facet name="header">
#{msgs.voce}
</f:facet>
<h:outputText value="#{gius.voce}"/>
</p:column>
<p:column>
<f:facet name="header">
#{msgs.dal}
</f:facet>
<amp:outputData value="#{gius.sDtIGius}"/>
</p:column>
<p:column>
<f:facet name="header">
#{msgs.al}
</f:facet>
<amp:outputData value="#{gius.sDtFGius}"/>
</p:column>
<p:column>
<f:facet name="header">
#{msgs.nr_giorni}
</f:facet>
<h:outputText value="#{gius.nrGiorni}"/>
</p:column>
<p:column>
<f:facet name="header">
#{msgs.ora_inizio}
</f:facet>
<amp:outputNvl value="#{gius.oraIGius}" nullval="-"/>
</p:column>
<p:column>
<f:facet name="header">
#{msgs.ora_fine}
</f:facet>
<amp:outputNvl value="#{gius.oraFGius}" nullval="-"/>
</p:column>
<p:column>
<f:facet name="header">
#{msgs.nr_ore}
</f:facet>
<amp:outputNvl value="#{gius.nrOre}" nullval="-"/>
</p:column>
<p:column>
<f:facet name="header">
#{msgs.nr_minuti}
</f:facet>
<amp:outputNvl value="#{gius.nrMinuti}" nullval="-"/>
</p:column>
</p:dataTable>
</f:facet>
</p:dataTable>
<p:dialog header="Info" widgetVar="timbDialog" resizable="false"
width="200" showEffect="clip" hideEffect="clip">
<h:panelGrid id="display" columns="2" cellpadding="4">
<h:outputText value="Data:" style="font-weight: bold"/>
<amp:outputData value="#{timbratureMBean.selezione.sDtComp}" />
<h:outputText value="Pausa pranzo ridotta: " style="font-weight: bold"/>
<h:outputText value="#{timbratureMBean.gestPausaPranzo}" />
<h:outputText value="Timbratura non allineata: " style="font-weight: bold"/>
<h:outputText value="#{timbratureMBean.timbNonAllineate}" />
</h:panelGrid>
</p:dialog>
Hou,
there is an event for changing a page, see here
http://cagataycivici.wordpress.com/2011/06/10/datatable-hooks/
<p:datatable paginator="true" rows="10" value="#{bean.items}" var="item">
<p:ajax event="page" listener="#{bean.onPaginate}" update="othercomponents" oncomplete="alert('done')"... />
...
though I am still looking for an event for onChangeRows
but, my current problem is only storing user choices, in fact that page event solves storing both on what page I am and how many rows are selected. If onPaginate implements in this way:
public void onPaginate(PageEvent event){
logger.info("I am on page:"+event.getPage());
logger.info("Rows per page set:"+((org.primefaces.component.datatable.DataTable)event.getSource()).getRows());
}
You can see what page you are on and how many rows are selected. And this event is triggered both when you change a page or change how many rows shown.
My solution is using Primefaces 5.2.x.
I found a pretty easy way to implement this, one of the problems I had with udik's solution was that when the onPaginate() method was called, it didn't have the newest selected value.
So here's what I did to make sure you always had the latest value and could save/load it to the database or a cookie or something (we save to a cookie).
<p:dataTable
.....
paginator="true"
paginatorPosition="bottom"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
currentPageReportTemplate="Total records: {totalRecords}, showing page {currentPage} of {totalPages}"
rowsPerPageTemplate="25,50,100"
rows="#{controller.rowsPerPage}"
.....
>
.....
<p:ajax event="page" oncomplete="rowsPerPageUpdate()" />
.....
</p:dataTable>
<p:remoteCommand name="rowsPerPageUpdate" actionListener="#{controller.onPaginate}" />
and then our controller looks like this:
#Dependent
#Named
public class TableController implements Serializable {
private String rowsPerPage = "25"; //default value
.....
public void onPaginate() {
//save to the cookie
}
.....
}
Basically the magic happens in the remoteCommand, which will fire after the ajax event to insure that controller.rowsPerPage has been properly updated.