I have many panelGrid's, I want to open a dialog when I click on panelGrid.
The problem is always selected the last panelGrid.
index.xhtml
<p:dataGrid var="object" value="#{vc.objects}"
layout="grid" id="dataGridObject">
<h:panelGrid columns="1" onclick="rc()">
<h:outputText value="#{object.name} " />
<p:remoteCommand name="rc" update="formX"
oncomplete="PF('dlgDetails').show()" action="#{vc.updateSelectObject(object)}"/>
</h:panelGrid>
</p:dataGrid>
ViewController.java
private Object selectObject;
public void updateSelectObject(Object object){
setSelectObject(object);
}
public Object getSelectObject() {
return selectObject;
}
public void setSelectObject(Object selectObject) {
this.selectObject = selectObject;
}
Why don't you try another approach. In this case with dataGrid you can replace outputText and remoteCommand with commandButton and you can style your button to look just like a panel.
<p:dataGrid var="object" value="#{vc.objects}"
layout="grid" id="dataGridObject" columns="1">
<p:commandButton value="#{object.name}"
actionListener="#{vc.updateSelectObject(object)}" process="#this"
update="formX" oncomplete="PF('dlgDetails').show()" />
</p:dataGrid>
Related
I'm using STS (Spring tool suite) with spring boot, primefaces and hibernate.
I have an page with a p:datatable. In the last column, have a p:commandbutton for edit data of the table (p:dialog).
When I open the dialog, all data load correct. If I close de dialog without save and open other line of the table data load correct again, but, if I save the data and open a new dialog of other line of the table, the field p:selectOneMenu is loaded with wrong data. Your value is the same value of the last dialog saved. All dialog data has correct, less the combobox (p:selectOneMenu). In debug, the value returned in backing bean is correct.
Some things I've tried:
Changed p:commandbutton to p:commandlink;
In button "save" of dialog, "update" field with the p:panel of table, the h:form, h:datable;
Change onComplete to onClick;
Use h:selectOneMenu instead of p:selectOneMenu;
Downgrade primefaces (currently 6.1) and myfaces (currently 2.2.12).
All no sucess.
ps: Datatable is filtered and paginated.
xhtml:
<p:panel id="pnlData" header="My Table">
<h:form id="frmTable">
<p:dataTable var="item" value="#{RSDMBean.myData}"
id="tblTicketsID" widgetVar="tabelaTickets" some things of pagination and filters here...>
<p:column />
<p:column /> ...
<p:column headerText="Edit">
<p:commandButton value="Edit"
actionListener="#{RSDMBean.editTicketLoad(item.idTicket)}"
update=":formPnl:pnlTkct" oncomplete="PF('dlgtkt').show();">
</p:commandButton>
</p:column>
</p:datatable>
</h:form
</p:panel>
<p:dialog id="dlgtktID" header="Edit ticket" widgetVar="dlgtkt"
modal="true">
<h:form id="formPnl">
<h:panelGrid id="pnlTkct" columns="2" cellpadding="10"
cellspacing="1" style="absolute">
<h:outputText style="font-weight:bold" value="Id Ticket: " />
<h:outputText value="#{RSDMBean.ticketEdited.id}" />
Others fields here...
<h:outputText style="font-weight:bold" value="County: " />
<p:selectOneMenu style="min-width: 162px;" required="true">
<f:selectItem itemLabel="#{RSDMBean.ticketEdited.county.name}"
itemValue="#{RSDMBean.ticketEdited.county.id}" />
<f:selectItems
value="#{RSDMBean.countyItensedit.entrySet()}" var="entry"
itemValue="#{entry.key}" itemLabel="#{entry.value}" />
</p:selectOneMenu>
<p:commandButton value="Save" action="#{RSDMBean.saveEdit}"
update=":frmTable:tblTicketsID" oncomplete="PF('dlgtkt').hide();" />
end tags here...
Bean:
import javax.annotation.PostConstruct;
import javax.faces.bean.RequestScoped;
import org.springframework.beans.factory.annotation.Autowired;
.
.
.
#Controller("RSDMBean")
#RequestScoped
public class MyMBean implements Serializable {
#Autowired
private ResiduoService residuoService;
#Autowired
private ResiduoRepository residuoRepository;
#Autowired
private CountyRepository countyRepository;
private Residuo ticketEdited;
private List<County> county;
private Map<Long, String> countyItensEdit = new HashMap<Long, String>();
public void editTicketLoad(String param) {
long idTicket = Long.parseLong(param);
ticketEdited = residuoRepository.findOne(idTicket);
county = countyRepository.findAll();
}
#PostConstruct
public void construct() {
//some loads database here...
county = countyRepository.findAll();
if (countyItensEdit.isEmpty()) {
for (Municipio c : countyItensEdit) {
countyItensEdit.put(c.getId(), c.getNome());
}
}
}
In p:selectOneMenu was missing value tag:
<p:selectOneMenu style="min-width: 162px;" required="true"
value="#{RSDMBean.ticketEdited.county.id}">
I am attempting to create a dialog that will serve the purpose of both creating objects and updating them. So if I happen to click the 'new' button I will be presented a dialog containing empty fields to be filled or if I click on an edit button for an entry, that entry's data will presented in the dialog for update.
Following the example in the primefaces showcase for version 5.2, I can present the data in a read only outputText form, however when I change it to an inputText, the field remains empty. The following code is an example of what I have:
<h:form id="form">
<p:dataGrid id="guestList" var="guest" value="${guestList.guests}" columns="3" paginator="true" rows="20">
<f:facet name="header">
Guest List
</f:facet>
<p:panel>
<h:outputText value="${guest.name}" />
<br />
<h:outputText value="${guest.street}" />
<br />
<h:outputText rendered="#{guest.street2.length() gt 0}"
value="${guest.street2}" />
<h:panelGroup rendered="#{guest.street2.length() gt 0}">
<br />
</h:panelGroup>
<h:outputText value="${guest.city}, " />
<h:outputText value="${guest.state} " />
<h:outputText value="${guest.zipCode}" />
<p:commandButton update="#form:newGuestDetail" oncomplete="PF('newGuestDialog').show()" icon="ui-icon-edit" styleClass="ui-btn-inline">
<h:outputText styleClass="ui-icon ui-icon-edit" style="margin:0 auto;" />
<f:setPropertyActionListener value="#{guest}" target="#{guestList.selectedGuest}" />
</p:commandButton>
</p:panel>
</p:dataGrid>
<p:dialog header="#{guestList.hasSelected() ? 'Edit Guest' : 'New Guest'}" widgetVar="newGuestDialog" modal="true" showEffect="fade" hideEffect="fade">
<p:outputPanel id="newGuestDetail">
<h:outputText value="'#{guestList.selectedGuest.name}'"/>
<p:inputText id="guestName" value="#{guestList.hasSelected() ? '' : guestList.selectedGuest.name}" pt:placeholder="Name"/>
<p:commandButton value="#{guestList.selectedGuest == null ? 'Create Guest' : 'Update Guest'}"/>
</p:outputPanel>
</p:dialog>
</h:form>
The hasSelected() method evaluates whether the selected guest is null or not, returning true if not null. The selectedGuest should be set when the commandButton is clicked so that an object is available for retrieval by the dialog, however, with tracers in the get/set for selectedGuest, I am not seeing the setter called with the above snippet. If I remove the inputText, then even though the hasSelected is still returning false, and thus the 'New Guest' is heading the dialog, the outputText is filled with a value.
I found this great post talking about the order of execution with respect to the action, action listener, etc., but don't think this quite my issue: Differences between action and actionListener.
So the ultimate question is why will my setter get called with the command button when I only have an outputText, but with an inputText, I never see it called in the log?
I appreciate the time and help anyone can provide.
Even if we fix your problem, this construct
<p:inputText value="#{guestList.hasSelected() ? '' : guestList.selectedGuest.name}">
is not ever going to work. It needs to reference a model property, not an empty string.
You'd best just reuse the edit form and let the create button precreate an empty entity. This would simplify a lot in the view side. It'd be more easy if the entity has an #Id property which is only present when it's persisted in the database.
Here's a kickoff example:
<h:form id="entitiesForm">
<p:dataTable id="entitiesTable" value="#{bean.entities}" var="entity">
<p:column>#{entity.foo}</p:column>
<p:column>#{entity.bar}</p:column>
<p:column>
<p:commandButton id="edit" value="Edit"
process="#this" action="#{bean.edit(entity)}"
update=":entityDialog" oncomplete="PF('entityDialog').show()" />
<p:commandButton id="delete" value="Delete"
process="#this" action="#{bean.delete(entity)}"
update=":entitiesForm:entitiesTable" />
</p:column>
</p:dataTable>
<p:commandButton id="add" value="Add"
process="#this" action="#{bean.add}"
update=":entityDialog" oncomplete="PF('entityDialog').show()" />
</h:form>
<p:dialog id="entityDialog" widgetVar="entityDialog"
header="#{empty bean.entity.id ? 'New' : 'Edit'} entity">
<h:form id="entityForm">
<p:inputText id="foo" value="#{bean.entity.foo}" />
<p:inputText id="bar" value="#{bean.entity.bar}" />
<p:commandButton id="save" value="#{empty bean.entity.id ? 'Create' : 'Update'} entity"
process="#form" action="#{bean.save}"
update=":entitiesForm:entitiesTable" oncomplete="PF('entityDialog').hide()" />
</h:form>
</p:dialog>
With this #ViewScoped bean:
private List<Entity> entities; // +getter
private Entity entity; // +getter
#EJB
private EntityService entityService;
#PostConstruct
public void load() {
entities = entityService.list();
entity = null;
}
public void add() {
entity = new Entity();
}
public void edit(Entity entity) {
this.entity = entity;
}
public void save() {
entityService.save(entity); // if (id==null) em.persist() else em.merge()
load();
}
public void delete(Entity entity) {
entityService.delete(entity); // em.remove(em.find(type, id))
load();
}
See also:
Creating master-detail pages for entities, how to link them and which bean scope to choose
Keep p:dialog open when a validation error occurs after submit
Someone can explain how to update an certain component in a view (example: dataScroller, dataList etc) using an autocomplete component ? I'm trying something with the ajax event "itemSelect" but with no success on how to proceed, any example, explanation, light will be a good help.
Some code (xhtml page)
<h:form id="frmPesquisarModalidade">
<p:autoComplete id="autoModalidade" multiple="true" value="#{matriculaBean.modalidadesSelecionadas}" completeMethod="#{matriculaBean.completeModalidade}"
var="modalidade" itemLabel="#{modalidade.nome}" itemValue="#{modalidade}" forceSelection="true">
<f:converter binding="#{modalidadeConverter}"/>
<f:ajax listener="#{matriculaBean.onItemSelect}" event="itemSelect" render="test"/>
<p:column style="width:10%">
<h:outputText value="#{modalidade.nome}"/>
</p:column>
</p:autoComplete>
<p:dataScroller id="dataScrollModalidadesSelecionadas" value="#{matriculaBean.modalidadesSelecionadas}" var="modalidade" chunkSize="6">
<h:panelGrid columns="2" cellpadding="5" id="test">
<h:outputText value="#{modalidade.nome}"/>
</h:panelGrid>
</p:dataScroller>
</h:form>
backing bean
#Named
#ViewScoped
public class MatriculaBean {
private List<Modalidade> modalidadesDisponiveis;
private List<Modalidade> modalidadesSelecionadas;
#Autowired
private ServicoModalidade servicoModalidade;
#PostConstruct
private void init(){
modalidadesDisponiveis = servicoModalidade.listar();
}
public List<Modalidade> completeModalidade(String busca) {
List<Modalidade> filtrados = new ArrayList<Modalidade>();
for (Modalidade mod : modalidadesDisponiveis) {
if (mod.getNome().contains(busca)) {filtrados.add(mod);}
}
return filtrados;
}
public void onItemSelect(SelectEvent event){
//????????
}
What you need to do in onItemSelect method is update the value of the target component, based on the selected item.
If you want to update dataScrollModalidadesSelecionadas:
public void onItemSelect(SelectEvent event){
//Get the selected item value
Modalidade m = new Modalidade();
m = event.getObject();
//Create/use a List method which can search the DB based on the selected item
modalidadesDisponiveis = servicoModalidade.listarPorModalidade(m);
}
And in the JSF, you just have to update the target component:
<p:autoComplete ...... >
<p:ajax listener="#{matriculaBean.onItemSelect}" event="itemSelect" update="dataScrollModalidadesSelecionadas"/>
</p:autoComplete>
I'm not sure if those options and properties you defined gonna work as expected, but the example above is the basics to update a component based on ItemSelect.
Also, I prefer using <p:ajax> rather than <f:ajax>
<h:form id="frmPesquisarModalidade">
<p:autoComplete id="autoModalidade" multiple="true" value="#{matriculaBean.modalidadesSelecionadas}" completeMethod="#{matriculaBean.completeModalidade}"
var="modalidade" itemLabel="#{modalidade.nome}" itemValue="#{modalidade}" forceSelection="true">
<f:converter binding="#{modalidadeConverter}"/>
<p:ajax event="itemSelect" update="dataScrollModalidadesSelecionadas"/>
<p:column style="width:10%">
<h:outputText value="#{modalidade.nome}"/>
</p:column>
</p:autoComplete>
<p:dataScroller id="dataScrollModalidadesSelecionadas" value="#{matriculaBean.modalidadesSelecionadas}" var="modalidade" chunkSize="6">
<h:panelGrid columns="2" cellpadding="5">
<h:outputText value="#{modalidade.nome}"/>
</h:panelGrid>
</p:dataScroller>
</h:form>
solved!!! to resolve my issue i'd discovered theres no need to apply an backing bean logic withe the itemSelect event... just create an ajax event in the xhtml page and use the update attribute with the respective id! Thanks for help
I have a datatable with custom delete button when I try to send the id of the selected row to the backing bean, but i always get the same value, this is my code:
<p:dataTable id="result" var="service" value="#{bean.services}" editable="true">
<!-- ajax -->
<p:ajax event="rowEdit" listener="#{bean.onEdit}" update=":form:msg" />
<p:ajax event="rowEditCancel" listener="#{bean.onCancel}" update=":form:msg" />
.....
<p:column headerText="delete" style="width:100px;">
<p:confirmDialog id="confirmation" message="are u sure?" header="delete item" widgetVar="confirmation" showEffect="fade" hideEffect="explode">
<p:commandButton value="Yes" onclick="PF('confirmation').hide()" actionListener="#{bean.onDeleteRow}">
<f:setPropertyActionListener target="#{bean.cve}" value="#{service.id.cve}" />
</p:commandButton>
<p:commandButton value="No" onclick="PF('confirmation').hide()" type="button" />
</p:confirmDialog>
<p:commandLink id="deleteLink" onclick="PF('confirmation').show()" styleClass="ui-icon ui-icon-trash"/>
</p:column>
</p:dataTable>
here is the baking bean code:
#ManagedBean
#ViewScoped
#SuppressWarnings("serial")
public class Bean implements Serializable{
private String cve;
...
public void setcve(String cve) {
this.cve = cve;
}
....
public void onDeleteRow(){
try {
System.out.println("delete-->" + this.cve );
} catch (Exception e) {
e.printStackTrace();
}
}
}
In the tag you can see the value that I'm sending as a parameter but I always leave the last value of datatable ...
What am I doing wrong?
Thank you very much for the support
Also there is another problem in your code, you have and Dialog for each row in the datatable, its a bad idea... you should keep the button on the row and set the entity that you want to delete when click at this button and latter just show the dialog, which is just one... something like this: also, change the propertyAcionListener to your delete link
<p:commandLink id="delete_link" oncomplete="deleteDlg.show();">
Delete
<f:setPropertyActionListener value="#{service.id.cve}" target="#{bean.cve}" />
</p:commandLink>
Where is the selection for datatable?
your xhtml
<p:dataTable id="result" var="service" value="#{bean.services}" editable="true">
must be xhtml
<p:dataTable id="result" var="service" value="#{bean.services}" selection="#{bean.selected}" editable="true">
you can find datatable selection example here
I have a data table with with two columns- Title and Action
Title is populated from a list in a managed bean and for each title in the list the datatable has a button called Confirm under Action column.
When the user clicks on the Confirm button, a dialog is displayed with additional information and another button called Submit.
If the user hits the Submit button inside that dialog a variable confirmDate is set in the backing bean, of the confirmDate is not null, I need to disable the particular Confirm button under the Action column in the main data table. Right now if I disable it, all the Confirm button is getting disabled. How do I disable only the selected confirm button. Really appreciate your help on this.
main data table
<h:panelGrid id="notificationList" width="100%">
<h:panelGroup >
<p:dataTable var="dt" value="#
{myBean.listAll}" id="titles" rowKey="#{dt.id}">
<f:facet name="header">
<h:outputText value = "Title List"/>
</f:facet>
<p:column headerText ="Title">
<h:outputText value="#{dt.title}"/>
</p:column>
<p:column headerText="Action">
<p:commandButton id="nID"
value="Confirm"
oncomplete="myDialog.show();"
process="#this"
disabled= "#{not empty dt.confirmDate}
update="#form">
<f:setPropertyActionListener value="#{dt}" target="#
{myBean.selectedTitle}"/>
</p:commandButton>
</p:column>
</p:dataTable>
</h:panelGroup>
</h:panelGrid>
Hard to say with your code, maybe all your dt objects which you retrieve via listAll are identical objects. How do you set up the list?
Anyhow this should work (simplified):
<p:dialog widgetVar="dlg">
<p:commandButton value="Submit" action="#{myBean.updateNotificationConfirmDate}" oncomplete="dlg.hide()"
update="notificationList" />
</p:dialog>
<p:dataTable id="notificationList" var="dt" value="#{myBean.tableData}">
<p:column>
<p:commandButton value="Confirm" process="#this" disabled="#{!empty dt.confirmDate}" update="#form"
oncomplete="dlg.show();">
<f:setPropertyActionListener value="#{dt}" target="#{myBean.selectedTitle}" />
</p:commandButton>
</p:column>
</p:dataTable>
And the backing bean (whatever your DT is :)):
#ManagedBean
#ViewScoped
public class MyBean {
private List<DT> tableData = new ArrayList<DT>();
private DT selectedTitle;
public MyBean() {
tableData.add(new DT(1L, "title1", null));
tableData.add(new DT(2L, "title2", null));
tableData.add(new DT(3L, "title3", null));
tableData.add(new DT(4L, "title4", null));
}
public DT getSelectedTitle() {
return selectedTitle;
}
public void setSelectedTitle(DT selectedTitle) {
this.selectedTitle = selectedTitle;
}
public List<DT> getTableData() {
return tableData;
}
public void updateNotificationConfirmDate() {
selectedTitle.setConfirmDate(Calendar.getInstance());
}
}