I have this form with a panel grid and a dialog:
<h:form id="regiForm">
<p:panelGrid>
<p:row style="height:30%">
<p:column>
<h:outputText/>
</p:column>
<p:column>
<p:commandButton style="width:350px" type="submit" actionListener="#
{regiBean.showDialog}" id="ajax" value="#{msg['regi_button']}" update="regiForm" process="#this"/>
</p:column>
<p:column>
</p:column>
</p:row>
</p:panelGrid>
<p:dialog id="dialog" header="#{msg['regi_dialog_header']}" widgetVar="myDialog" position="center center" >
<h:outputText value="#{msg['regi_dialog']}" />
</p:dialog>
</h:form>
I would like to open the dialog from inside the action listener:
public void showDialog() {
RequestContext.getCurrentInstance().execute("dialog.show()");
RequestContext.getCurrentInstance().execute("myDialog.show()");
}
However, the dialog is not shown. How is this caused and how can I solve it?
I'm using JSF 2.1 and PrimeFaces 3.5.
The first statement with the command
RequestContext.getCurrentInstance().execute("dialog.show()");
won't work because dialog refers to the XHTML ID of the p:dialog component. This will cause an javascript error. And that could be the reason why the second command
RequestContext.getCurrentInstance().execute("myDialog.show()");
won't get executed.
Also I would add ; to the end of each Javascript command (but this is just my personal style)
Related
I have a problem with primefaces datatables. I have one datatable with some entries and a column with a button inside. If the button is pressed a popup is opened with another datatable. The entries in the second datatable are depending on the row in which the button is pressed.
<!-- first datatable -->
<h:form id="list">
<p:dataTable id="list1" var="item" value="#{bean1.itemlist}"
rowKey="#{item.id}" selection="#{bean1.selectedItem}"
selectionMode="single">
<p:column headerText="ID">
<h:outputText value="#{item.id}" />
</p:column>
...
<p:column headerText="Edit Entries">
<p:commandButton value="Edit Entries"
actionListener="#{bean2.updateEntries(item)}" ajax="true"
oncomplete="PF('edit_entries').show()" />
</p:column>
</p:dataTable>
<!-- Second datatable in the popup -->
<p:dialog header="Edit Entries" widgetVar="edit_entries" modal="true"
resizable="false">
<p:dataTable id="list2" var="entry"
value="#{bean2.entriesList}" rowKey="#{entry.id}"
selection="#{bean2.selectedEntry}" selectionMode="single">
<p:column headerText="Entry Number">
<h:outputText value="#{entry.number}" />
</p:column>
</p:dataTable>
<f:facet name="footer">
<p:commandButton value="Save" oncomplete="PF('edit_entries').hide()" />
</f:facet>
</p:dialog>
</form>
Bean2
public void updateEntries(Item selectedItem) {
this.entriesList = this.entriesQuery.getAllEntriesByItemID(selectedItem.getId());//db query could take some time
System.out.println("entrieslist size: " + this.entriesList.size()); //prints the correct size
}
The problem is that there are no entries listed in the popup datatable although there are some in the list after the db query.
Any ideas how to fix this bug?
Thanks in advance!
UPDATE 1:
<!-- first datatable -->
<h:form id="list">
<p:dataTable id="list1" var="item" value="#{bean1.itemlist}"
rowKey="#{item.id}" selection="#{bean1.selectedItem}"
selectionMode="single">
<p:column headerText="ID">
<h:outputText value="#{item.id}" />
</p:column>
...
<p:column headerText="Edit Entries">
<p:commandButton value="Edit Entries" update=":dialogUpdateEntries"
actionListener="#{bean2.updateEntries(item)}" ajax="true"
oncomplete="PF('edit_entries').show()" />
</p:column>
</p:dataTable>
</h:form>
<!-- Second datatable in the popup -->
<p:dialog header="Edit Enries" id="dialogUpdateEntries" widgetVar="edit_entries" modal="true"
resizable="false">
<h:form id="formEntriesList">
<p:dataTable id="list2" var="entry"
value="#{bean2.entriesList}" rowKey="#{entry.id}"
selection="#{bean2.selectedEntry}" selectionMode="single">
<p:column headerText="Entry Number">
<h:outputText value="#{entry.number}" />
</p:column>
</p:dataTable>
<f:facet name="footer">
<p:commandButton value="Save" oncomplete="PF('edit_entries').hide()" />
</f:facet>
</form>
</p:dialog>
You're indeed not updating the data table in the dialog. JSF doesn't automatically update the view on change of the model, you have to explicitly tell the view to do so. You can use the ajax action component's update attribute for this. This takes a JSF client ID which can be found by rules as outlined in this related answer: How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar".
Given the markup as shown in the question, that'll be
<p:commandButton ... update=":list:list2" />
However, there's another potential problem. You're using <p:dialog modal="true"> inside a form instead of giving the dialog its own form. This way the dialog may not be available in the HTML DOM tree as JavaScript (the one responsible for dealing with ajax stuff) would expect to find it. Giving the dialog its own form should fix this matter. It'll also fix the potential future problems with invoking actions from inside the dialog as handled in this related question: <p:commandbutton> action doesn't work inside <p:dialog>.
<h:form id="viewForm">
...
<p:commandButton ... update=":editDialog" />
...
</h:form>
<p:dialog id="editDialog" modal="true">
<h:form id="editForm">
...
</h:form>
</p:dialog>
Try adding update="list2" to Edit Entries command button (even update="#widgetVar(edit_entries)" should work).
If, because of page layout and structure, you can't target the second datatable using above suggestions, then add styleClass="tList2" to second table, and update it with update="#(.tList2)" on edit button.
Hello I am trying to implement some primefaces commandbuttons in a p:datatable. My need is almost identical to this post:
f:setPropertyActionListener not invoked
Basically I need to have a column of buttons in a , click on one button will pass the object of the current row to the bean, and a dialog will pop out, showing some information of the chosen object.
The following is the relevant code:
<f:view>
<body>
<h:form id="theForm">
<p:dataTable id="testFailures" value="#{testDetails.report.failures}" var="failure"
styleClass="baseTable">
<p:column id="requestColumn">
<f:facet name="header">
<h:outputText value="Request" id="requestHeaderText" />
</f:facet>
<p:commandButton value="Detail" update="requestDialog"
oncomplete="PF('dlg1').show();" type="button">
<f:setPropertyActionListener
target="#{testDetails.selectedFailure}" value="#{failure}" />
</p:commandButton>
<h:message for="requestDialog" />
<p:dialog id="requestDialog" header="Request Dialog"
widgetVar="dlg1" dynamic="true">
<h:outputText value="#{selectedFailure.request}" />
</p:dialog>
</p:column>
</p:dataTable>
</h:form>
<h:message for="theForm" />
<h:message for="responseDialog" />
<p:dialog id="responseDialog" header="Request Dialog"
widgetVar="dlg2" dynamic="true">
<h:form>
<h:outputText value="#{selectedFailure.request}" />
</h:form>
</p:dialog>
</body>
</f:view>
I tried to put the dialog in different positions (see my "dlg1" and "dlg2"). But neither works. No dialog showing. does not show anything either. And I don't see any error message in the browser's console window. (I think there is a exclamation warning).
I have tried debug mode, and set method for the property "selectedFailure" is not called.
Try to remove type="button" from your commandButton and it should work. Also dialogs should not be placed inside dataTables so the position of "dlg2" is more correct.
My dataTable is populated by an ajax call, my commandLink (in the datataable) is not pointing to the correct location and always render the same page.and show me in the console :
HtmlLabelRend W Attribute 'for' of label component with id j_id1471051656_3ffdbef6:j_id1471051656_3ffdbfc6 is not defined
But when I put the commandlink outside the datatable the action method works fine.
This problem is rare!, How Can I solve it?
Thanks in advance.
My Jsf Page:
<h:form>
<p:panel header="Busqueda">
<p:panelGrid style="width:100%;">
<p:row>
-----------------------------------(inputs)---------------------------------------
<p:column>
<p:commandButton value="Buscar" update="grilla"
action="#{devolucionAdminController.buscarSD()}">´
</p:commandButton>
</p:column>
</p:row>
</p:panelGrid>
<p:messages closable="true" redisplay="true" id="msj"></p:messages>
</p:panel>
<p:dataTable id="grilla" var="r"
value="#{devolucionAdminController.listado}"
emptyMessage="No se han encontrado solicitudes de devolución">
<p:column headerText="Sec">
<h:outputText value="#{r.idSoliDevo}" />
</p:column>
<p:column headerText="Cuenta">
<h:outputText value="#{r.cuentaId}" />
</p:column>
<p:column headerText="Ver Detalle Sol. Dev ">
<p:commandLink
action="#{bajaController.mostrarSolicitudBaja(r.cuentaId,r.idSoliDevo)}" ajax="false">
<p:commandButton icon="ui-icon-search" title="Ver Detalle" />
</p:commandLink>
</p:column>
</p:dataTable>
<!--works fine -->
<p:commandLink action="#{bajaController.mostrarSolicitudBaja(80003,340)}"
ajax="false">
<p:commandButton icon="ui-icon-search" title="Ver Detalle" />
</p:commandLink>
</h:form>
My first Managed Bean:
#ManagedBean
#RequestScoped
public class DevolucionAdminController {
List<TaSoliDevo> listado;
//getters and setters
........................
public void buscarSD() {
.............................
}
My second Managed Bean:
#ManagedBean
#RequestScoped
public class BajaController {
public String mostrarSolicitudBaja(long cuentaId, long solicDevId) {
.........................
return "goResult";
}}
Use process="#this" and use actionListener instead of action
<p:commandLink process="#this" actionListener="#{bajaController.mostrarSolicitudBaja(80003,340)}"></p:commandLink>
I had the same problem and I was struggling to find a solution but nothing worked for me. Here is how I finally solved the problem :
I removed the ajax attribute
I added process="#this"
Here is what my commandLink looks like after the changes :
<p:commandLink process="#this" action="#{projsSummaryBacking.redirectProjTasks(proj)}" >
<h:outputText value="#{proj.title}" />
</p:commandLink>
I hope that this can help someone. /m\
remove the ajax="false" tag, its work for me
replace your commandLink with
<p:commandButton icon="ui-icon-search" title="Ver Detalle"
action="#{bajaController.mostrarSolicitudBaja(r.cuentaId,r.idSoliDevo)}" ajax="false"/>
Really no need to put a command button inside a command Link, just to put an icon
I have to implement the search the functionality in primefaces dialog. After submitiing the search commandbutton the table beside the search needs to get updated. But everytime i am hitting the search button the popup gets closed. Please guide.Below is my code snippet for reference:
......
<p:commandButton id="search" value="Search" actionListener="#{createTicketBaseBean.searchUserFromList}" update="#form" onclick="dlg.show()"></p:commandButton>
</h:panelGrid>
</h:panelGroup>
<h:panelGroup style="float:right" >
<p:dataTable id="table" var="user" value="#{createTicketBaseBean.userList}" selection="#{createTicketBaseBean.selectedUser}" selectionMode="single" rowKey="#{user.email}" >
<p:column headerText="Name" >
<p:commandLink id="nameselect" value="#{user.name}" onclick="dlg.hide()"/>
</p:column>
<p:column headerText="Email">
<h:outputText value="#{user.email}" />
</p:column>
<p:column headerText="Department">
<h:outputText value="#{user.department}" />
</p:column>
</p:dataTable>
Replace onclick in your p:commandbutton with oncomplete. onclick event is happening immediate when button is clicked. As this is AJAX button (in Primefaces this is default) there will be race conditioning between AJAX request and dialog opening. When using oncomplete it will be called after AJAX request is completed.
I am trying to move a p:dialog out of a h:form, because I have read that this is the preferred way (however I'd like to understand the reason, because my p:dialog inside a form works well in my application).
The only difficulty is that the dialog title needs to be updated dynamically. The dialog is shown when a button in a p:dataTable is clicked.
Here is my old xhtml (before the changes), that's working fine:
<p:dataTable var="event" value="#{eventBean.lazyModel}" selection="#{eventBean.selectedEvent}" />
...
<p:column headerText="#{msgs.Persons}">
<p:commandButton value="#{msgs.ViewPersons}" update=":viewPersonsForm" oncomplete="viewPersonsDlg.show()">
<f:setPropertyActionListener value="#{event}" target="#{eventBean.selectedEvent}" />
</p:commandButton>
</p:column>
</p:dataTable>
<h:form id="viewPersonsForm">
<p:dialog modal="true" widgetVar="viewPersonsDlg" dynamic="true" header="#{eventBean.selectedEvent.name}" >
...
</p:dialog>
</h:form>
And here is the new xhtml, with eventBean#setSelectedEvent() that is not invoked.
<p:dataTable var="event" value="#{eventBean.lazyModel}" selection="#{eventBean.selectedEvent}" />
...
<p:column headerText="#{msgs.Persons}">
<p:commandButton value="#{msgs.ViewPersons}" update=":viewPersonsDlgId" oncomplete="jQuery('#viewPersonsDlgId .ui-dialog-title').text('#{eventBean.selectedEvent.name}');viewPersonsDlg.show()">
<f:setPropertyActionListener value="#{event}" target="#{eventBean.selectedEvent}" />
</p:commandButton>
</p:column>
</p:dataTable>
<p:dialog modal="true" id="viewPersonsDlgId" widgetVar="viewPersonsDlg" dynamic="true" >
...
</p:dialog>
So, again, why in the second scenario eventBean#setSelectedEvent() is not invoked? And, if possible, why the first scenario is not optimal?
It is not restricted to use p:dialog inside a h:form since it can work in some cases, but most of the time you will find yourself struggling with some unexpected behaviour with that, here are some explanations :
Why not to place p:dialog inside h:form 1
Why not to place p:dialog inside h:form 2
The problem in your case is that jQuery method in oncomplete is called before the value is set with f:setPropertyActionListener. To avoid this use the same solution as you used in your first case. So :
<p:dataTable var="event" value="#{eventBean.lazyModel}" selection="#{eventBean.selectedEvent}" />
...
<p:column headerText="#{msgs.Persons}">
<p:commandButton value="#{msgs.ViewPersons}" update=":viewPersonsDlgId" oncomplete="viewPersonsDlg.show()">
<f:setPropertyActionListener value="#{event}" target="#{eventBean.selectedEvent}" />
</p:commandButton>
</p:column>
</p:dataTable>
<p:dialog modal="true" id="viewPersonsDlgId" widgetVar="viewPersonsDlg" dynamic="true" header="#{eventBean.selectedEvent.name}" >
...
</p:dialog>
No need to use jQuery here.
I had the same problem (pf 3.5):
<p:tabView id="cashFlowTabContainer" style="width:100%" activeIndex="0"
widgetVar="cashFlowTabContainerVar">
<p:tab title="#{labels['cashflow_incoming']}">
<p:outputPanel id="incomingPanel">
<p:dataTable value="#{cashFlowController.incomingCashFlows}"
var="cashFlow">
<p:column headerText="#{labels.cashflow_actions}">
<p:commandButton value="Edit"
action="# {cashFlowController.editIncoming}" update="#form" oncomplete="editInputVar.show();">
<f:setPropertyActionListener value="#{cashFlow}"
target="#{cashFlowController.selectedIncoming}" />
</p:commandButton>
</p:column>
and this was my dialog:
<p:dialog id="editInput" header="Dynamic Dialog"
widgetVar="editInputVar" resizable="false" draggable="false"
modal="true">
<p:panel>
<h:panelGrid columns="2" cellpadding="5">
...
<h:outputText value="#{labels.cashflow_description}:" />
<h:inputText
value="#{cashFlowController.selectedIncoming.description}" />
So... This way the setter was NEVER called. Then I noticed that if I emptied the dialog the setter was called.
So I solved it by putting a "rendered" statement on the panel:
<p:dialog id="editInput" header="Dynamic Dialog"
widgetVar="editInputVar" resizable="false" draggable="false"
modal="true">
<p:panel **rendered="#{cashFlowController.selectedIncoming != null}"**>
<h:panelGrid columns="2" cellpadding="5">
I guess there's a null pointer that is not logged anywhere... anyway this way it works :)