I have a dataTable, to which I want to add column with a Delete button for each row.
My issue is, that I don't know how to change the currentItem member variable of my bean class, before the delete method is called in the command button's actionListener.
I've tried adding a setPropertyActionListener tag:
<p:column>
<p:commandButton value="Delete" actionListener="#{itemBean.deleteItem}" process="#this"
update="table StartButtonForm">
<f:setPropertyActionListener value="#{item}" target="#{itemBean.currentItem}"/>
</p:commandButton>
</p:column>
but the value only gets changed after itemBean.deleteItem is called in the button's actionListener, so currentItem is not updated in time and the wrong item gets deleted.
Does anyone know how to change the currentItem whenever you hover with your mouse over a row?
Here is the whole table in my xhtml file in case it's important:
<p:dataTable id="table" var="item" value="#{itemBean.unrankedItems}" selection="#{itemBean.currentItem}"
selectionMode="single" rowKey="#{item.name}" rowSelectMode="add">
<p:ajax event="rowSelect" listener="#{itemBean.onRowSelect}"/>
<p:column>
<h:outputText value="#{item.name}"/>
</p:column>
<p:column>
<p:commandButton value="Delete" actionListener="#{itemBean.deleteItem}" process="#this"
update="table StartButtonForm">
<f:setPropertyActionListener value="#{item}" target="#{itemBean.currentItem}"/>
</p:commandButton>
</p:column>
</p:dataTable>
There is an exact Showcase example for your scenario with a Delete button in each row.
See: https://www.primefaces.org/showcase/ui/data/datatable/crud.xhtml
Related
In an edit screen, I'm using p:ajax to grab the selected value in an autocomplete field and fill in other fields in the form. But when ajax is running in question it is updating the information in the database table (update). How do I block this behavior? After all I should only do this when I clicked the save button.
Code:
<h:panelGroup>
<p:autoComplete id="demandaBeanDemandaLogradouroNome" value="#{demandaBean.demanda.logradouro}"
var="_item" minQueryLength="3" maxResults="15" required="true"
itemLabel="#{_item.nome}" itemValue="#{_item}" converter="#{logradouroBean.converter}"
completeMethod="#{logradouroBean.buscaLogradouro}" title="Busca pelo Logradouro">
<p:column>
<h:outputText value="#{_item.categoria.descricao}"/>
</p:column>
<p:column>
<h:outputText value="#{_item.nome}"/>
</p:column>
<p:ajax partialSubmit="true" immediate="true" event="itemSelect" update="demandaBeanDemandaBairro demandaBeanDemandaCruzamento"
listener="#{logradouroBean.buscaComplementoSelectEvent}"/>
</p:autoComplete>
<p:message for="demandaBeanDemandaLogradouroNome" styleClass="error"/>
</h:panelGroup>
I have found that what happens is that Hibernate synchronizes the persistent objects and if you change it it automatically updates in the database. To solve, I used an auxiliary object with the #Transient tag. Thanks.
How do I do to get the selected data that dataTable? I use this way because it is the "Edit" of a register.
<p:dataTable id="dataTable" var="valor" style="width:100%; text-align:center"
value="#{beanMensagemXContato.dataModelMsg}"
selection="#{beanMensagemXContato.selectedMensagemAssociada}"
paginator="true" rows="6" >
<f:facet name="header">
Mensagens
</f:facet>
<p:column style="width:5%">
<p:selectBooleanCheckbox value="#{valor.associada}" >
<p:ajax process="#form" event="valueChange" listener="# {beanMensagemXContato.adicionarMensagemContato}">
<f:param name="messageSelecionada" value="#{beanMensagemXContato.msgAssociada}" />
</p:ajax>
</p:selectBooleanCheckbox>
</p:column>
...
</p:dataTable>
I would pick the data by Bean as the event SelectEvent:
public void adicionarMensagemContato (SelectEvent event){
Mensagem mensagem = ((MensagemAssociada) event.getObject()).getMensagem();
MensagemAssociada mensagemAssociada = (MensagemAssociada) event.getObject();
...
}
But I could not take the data with the event ValueChange. I've tried with SelectEvent by tag selectionMode = "multiple", managed to get the data selected at that moment, the data previously selected and read from the database does not appear, use only when the way listed above in xhtml.
Already I appreciate the help.
The selection is stored in your bean field:
selection="#{beanMensagemXContato.selectedMensagemAssociada}"
If the adicionarMensagemContato method is located in the same bean, you can access you selection without a problem:
public void adicionarMensagemContato (SelectEvent event){
doSomething(this.selectedMensagemAssociada);
}
Another way is to use f:setPropertyActionListener - it allows you to store element from current row in a bean field (example below shows how to access current element in action invoked by button click):
<p:dataTable var="objectFromCurrentRow" ...>
...
<p:column ...>
<p:button ... action=#{beanMensagemXContato.performAnActionOnCurrentElement} ...>
<f:setPropertyActionListener value="#{objectFromCurrentRow}" target="#{beanMensagemXContato.selectedMensagemAssociada}" />
</p:button>
...
I have a tabView where each tab contains a datatable. I have it set up like so
<p:tabView id="tabView" styleClass="manage-tab-view" prependId="false"
activeIndex="#{managementTabBean.activeIndex}" dynamic="true" cache="false">
<p:tab id="users" title="#{msg['TeamManagement.Tabs.Users']}" >
<ui:include src="tab1.xhtml" />
</p:tab>
<p:tab id="athletes" title="#{msg['TeamManagement.Tabs.Athletes']}">
<ui:include src="tab2.xhtml" />
</p:tab>
</p:tabView>
Within each tab I am trying to show a datatable. Right now I have it set up like this:
Tab1:
<h:form id="userProfileViewForm" prependId="false">
<p:dataTable var="userProfile" value="#{userProfileListBean.objects}"
id="userProfilesTable" sortBy = "#{userProfile.lastName}" sortFunction = "#{userProfileListBean.sortUserLastName}" sortOrder = "ascending" lazy="true">
<p:column sortBy="#{userProfile.lastName}" sortFunction = "#{userProfileListBean.sortUserLastName}" id="userName">
p:commandLink>
<p:commandLink rendered="#{!appContextBean.isCWContext()}"
onclick="window.location.href='userBS.xhtml?id=#{userProfile.id}'">
<div class="clickable-cell">
<h:outputText
value="#{userProfile.firstName} #{userProfile.lastName}" />
</div>
</p:commandLink>
</p:column>
...more columns...
Tab2: Similar DataTable
<p:dataTable var="athlete" value="#{athleteListBean.objects}"
tableStyle="width:auto" sortBy="#{athlete.getDisplayName()}" sortFunction = "#{athleteListBean.sortAthleteDisplayName}" id="athletesTable"
sortOrder="#{athleteListBean.getListSortOrderDesc()}" lazy="true" paginator="true" rows="15" paginatorPosition="bottom"
paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}">
<p:column sortBy="#{athlete.getDisplayName()}" sortFunction = "#{athleteListBean.sortAthleteDisplayName}" id="athleteColumn">
<h:outputText styleClass="athlete-listing athlete-name" value="#{athlete.firstInitial} #{athlete.lastName}" />
</p:column>
As you can see I have a custom initial sorting function set up for both datatables.
For some reason the first tab sorting function gets called, and the second tab sorting function does not. After I swapped the tabs in the tabview, tab2 sorting function gets called, but tab1 doesnt.
Basically the initial sorting function only gets called on the datatable of the first tab, based on the order of tabs in the tab view. Can anyone tell me why this is happening?
Thank you for your help.
I had a similar problem, in my case on the second tab had a p:dataTable with p:columnToggler, and clicking on the button to hide or display columns are displayed in black and could not remove the columns.
The solution I found was to add on event "tabChange" in p:ajax inside p:TabView
In this way the problem was solved and I already work properly on p:columnToggler.
Maybe you serve to the problem you have with the order of the p:dataTable.
Here I put my code:
<p:tabView effect="fade" effectDuration="fast" prependId="false">
<p:ajax event="tabChange" update="#this"/>
<p:tab title="#{text['liquidacionForm.tabDatosLiq']}">
<ui:include src="/datosLiquidacion.xhtml"></ui:include>
</p:tab>
<p:tab title="#{text['liquidacionForm.tabEstanciasLiq']}">
<ui:include src="/estanciasLiquidadas.xhtml"></ui:include>
</p:tab>
</p:tabView>
I think, because of the full method name supplied in the EL(Expression Language) part, your second tab sorting is not called at all.
So, you need to remove actual method name with execulding the getter part i.e.
instead of {athleteListBean.getListSortOrderDesc() use {athleteListBean.listSortOrderDesc}
Use the bellow's code for the second tab.
<p:dataTable var="athlete" value="#{athleteListBean.objects}"
tableStyle="width:auto" sortBy="#{athlete.displayName}" sortFunction = "#{athleteListBean.sortAthleteDisplayName}" id="athletesTable"
sortOrder="#{athleteListBean.listSortOrderDesc}" lazy="true" paginator="true" rows="15" paginatorPosition="bottom"
paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}">
<p:column sortBy="#{athlete.displayName}" sortFunction = "#{athleteListBean.sortAthleteDisplayName}" id="athleteColumn">
how can I get row number in Primefaces (2.2) DataTable by clicking button in some row?
I need pass this number to javascript code with prompt() function.
1 solution
using WidgetVar.selection but in this case I use manually row selection and then click button -> bad scenario.
<p:column>
<p:commandButton id="someButton" value="Button"
actionListener="#{managedBean.someEvent}" onclick="return jsMethod(widgetVar.selection)" />
</p:column>
Thank You!
You can use UIData#getRowIndex() for this.
<p:dataTable binding="#{table}" ...>
<p:column>
<p:commandButton ... onclick="return jsMethod(#{table.rowIndex})" />
</p:column>
</p:dataTable>
Richfaces 3.3.3, Jsf 1.2:
I have a a4j:form that uses some simple validation, mainly required="true" to ensure the form does not get submitted without some necessary data.
I also have some complex data to add (optionally) to the form, so I thought the best way to do this is to have a a4j:commandButton that displays a rich:modalPanel where the user can create the complex data set.
The created data is also displayed in a h:selectManyListbox that is reRendered when the modalPanel is closed.
That's the plan, at least. I have the following problems:
reRender works, but only if I prevent validation via immediate="true" - which in turn seems to prevent the selected data from the modalPanel to be present in the backing Bean
if I remove the immediate tag, the data gets updated, but only if there are no validation errors
What is the best way to get this to work the way I want? Is there another, better way?
UPDATE:
The Validation that fails is in some different part of the form, not in the data entered via the modalPanel, which is displayed in the Listbox
CODE:
modalPanel:
<rich:modalPanel id="addTrimming" domElementAttachment="parent" width="150" height="130">
<f:facet name="header">
<h:panelGroup>
<h:outputText value="Define Filter" />
</h:panelGroup>
</f:facet>
<f:facet name="controls">
<h:panelGroup>
<h:graphicImage value="/images/close.gif" styleClass="hidelink" id="hidelinkAddTrimming"/>
<rich:componentControl for="addTrimming" attachTo="hidelinkAddTrimming" operation="hide" event="onclick"/>
</h:panelGroup>
</f:facet>
<h:panelGrid id="trimsettings" columns="3">
<h:outputText value="Target:" style="font-weight:bold"/>
<h:inputText id="target" label="XML Filename" required="true" value="#{xmlCreator.trimTarget}">
</h:inputText>
<h:outputText value=""/>
<h:outputText value="Mode:"/>
<h:selectOneMenu value="#{xmlCreator.trimMode}">
<f:selectItem itemLabel="Quality" itemValue="quality"/>
<f:selectItem itemLabel="after Primer" itemValue="afterPrimer"/>
<f:selectItem itemLabel="fixed" itemValue="fixed"/>
<f:selectItem itemLabel="Median length" itemValue="median"/>
<f:selectItem itemLabel="Motif" itemValue="motif"/>
</h:selectOneMenu>
<h:outputText value=""/>
</h:panelGrid>
<h:panelGroup>
<a4j:commandButton value="OK" action="#{xmlCreator.createTrimming}" onclick="from:submit()">
<a4j:support event="oncomplete" ajaxSingle="true" immediate="true" reRender="trimsPanel"/>
</a4j:commandButton>
</h:panelGroup>
</rich:modalPanel>
relevant form part:
<h:outputText value="Trimming:"/>
<a4j:outputPanel id="trimsPanel">
<h:selectManyListbox id="trims" value="#{xmlCreator.selectedTrimmings}">
<f:selectItems value="#{si:toSelectTrimmingList(xmlCreator.trimmings)}"/>
</h:selectManyListbox>
</a4j:outputPanel>
<a4j:commandButton id="addTrimButton" immediate="true" value=" + Trimming">
<rich:componentControl for="addTrimming" attachTo="addTrimButton" operation="show" event="onclick"/>
</a4j:commandButton>
If you do it in one form than you should separate it into two: one will be your main form and another will be form inside modal panel. Thus you'll be able to submit modal panel independently of main form and your submit button in modal panel will look like this:
<a4j:commandButton value="OK" action="#{xmlCreator.createTrimming}" reRender="trimsPanel"/>
you should use process with immediate to send modalpanel's data to bean when closing panel with a a:commandButton or a:commandLink.
for this, modal panel data has to be valid as expected, so you will get valid new data and add it to h:selectManyListBox 's bean value and reRender h:selectManyListBox.
this should work. if not please post your a:form and modalPanel code full to check.