Button in dialog inside p:dialog is not calling controller method - jsf

I've got a problem as described in the title.
Small description of the problem is as following:
I have button which is used to open dialog. Then, inside that dialog, there is button which opens another dialog on top of the first one. After clicking second button I want method from controller to be called but nothing happens. Value in h:outputText is read properly, so I guess it is not a problem with connection controller->view.
I'm using:
Spring web 3.1.2.RELEASE
JSF 2.2.10
Primefaces 5.1
Code:
beans.xml
<bean id="testController" class="test.TestController" />
TestController.java
public class TestController implements Serializable
{
private static final long serialVersionUID = 7028608421091861830L;
private String test;
public TestController()
{
test = "abc";
}
public void testMethod()
{
test = "cba";
}
public String getTest()
{
return test;
}
}
test.xhtml
<h:panelGrid columns="1" cellpadding="5">
<p:commandButton value="Basic" type="button" onclick="PF('dlg1').show();" />
</h:panelGrid>
<p:dialog widgetVar="dlg1">
<h:outputText value="Resistance to PrimeFaces is futile!" />
<h:panelGrid columns="1" cellpadding="5">
<p:commandButton value="Basic" type="button" onclick="PF('dlg2').show();" />
</h:panelGrid>
<p:dialog widgetVar="dlg2">
<h:outputText value="#{testController.test}" />
<p:commandButton value="Call method" type="button" actionListener="#{testController.testMethod}" />
</p:dialog>
</p:dialog>
What I tried:
adding appendToBody="true" to each p:dialog
changing from p:commandButton to p:button
changing from actionListener to action
but nothing helps.
I would be grateful for any help or advice of what can be the reason of not calling given method.

There are 3 problems.
You're nesting <p:dialog> components. This doesn't make sense. Separate them.
A <p:dialog> must have its own <h:form>, particularly when you explicitly use appendToBody="true" or appendTo="#(body)", otherwise nothing can be submitted because JavaScript would relocate the dialog out of its position in the HTML DOM tree to the end of body, causing it to not be sitting in a form anymore.
A <p:commandButton type="button"> acts as a "click" button, not as a submit button. Remove that attribute from submit buttons.
All in all, this is how it should look like:
<h:form>
<h:panelGrid columns="1" cellpadding="5">
<p:commandButton value="Basic" type="button" onclick="PF('dlg1').show();" />
</h:panelGrid>
</h:form>
<p:dialog widgetVar="dlg1">
<h:form>
<h:outputText value="Resistance to PrimeFaces is futile!" />
<h:panelGrid columns="1" cellpadding="5">
<p:commandButton value="Basic" type="button" onclick="PF('dlg2').show();" />
</h:panelGrid>
</h:form>
</p:dialog>
<p:dialog widgetVar="dlg2">
<h:form>
<h:outputText value="#{testController.test}" />
<p:commandButton value="Call method" actionListener="#{testController.testMethod}" />
</h:form>
</p:dialog>

OK. I guess I found a way to fix this problem.
It seems that the problem was:
type="button"
I deleted it from the list of attributes of each button and now it works even without h:form. Thanks for help.

Related

P:CommandButton in popup dialog did not submit

I have encountered a strange situation.
I have a xhtml looks like this:
<h:form id="frmContent">
<p:dataTable id="tbl" ..>
</p:dataTable>
<p:contextMenu for="tbl">
<p:menuitem value="Delete" update="tbl" actionListener="#{VehicleBean.deleteVehicle}"/>
<p:menuitem value="Copy" update=":frmContent:vehicleDia:VehicleDialogContent" action="#{VehicleBean.copyVehicle}" oncomplete="PF('VehicleDialog').show();"/>
</p:contextMenu>
<p:dialog header="Vehicle Detail" widgetVar="VehicleDialog" modal="true" resizable="true" appendTo="#(body)">
<h:form id="vehicleDia">
<p:panelGrid id="VehicleDialogContent" columns="2" >
...
</p:panelGrid>
<p:commandButton id="SaveButton" type="button" value="Save" update="VehicleDialogContent" actionListener="#{VehicleBean.saveVehicle}" oncomplete="PF('VehicleDialog').hide();">
</h:form>
</p:dialog>
The problem is, I cannot make the VehicleBean.saveVehicle() method fired.
I have tried to remove the nested form "vehicleDia" but not work.
I have tried to changing actionListener to action but still not work.
I have tired using h:commandButton instead of p:commandButton still no lucky.
Right now, I dont have any clue.
PS: this is my bean:
#ManagedBean(name="VehicleBean")
#ViewScoped
public class VehicleBean {
...
public void saveVehicle() {
System.out.println("VehicleBean:saveVehcile is called");
}
}
I am new to JSF and primefaces, any help is much appreciated!!

Primefaces Confirm Message Updated Value

I'm trying to show an updated value in confirm dialog message but I keep getting the old value as in this scenario
<h:form>
<p:inputText value="#{bean.object.amount}"/>
<p:commandButton value="CALCULATE" update="cal" actionListener="#{bean.calculate()}"/>
<h:panelGroup id="cal">
<h:outputText value="#{bean.object.amount}"/>
<p:commandButton value="SUBMIT" actionListener="#{bean.submit()}">
<p:confirm header="Confirmation" message="Amount is : #{bean.object.amount} ?"/>
</p:commandButton>
<p:confirmDialog global="true">
<p:commandButton value="Yes" type="button" styleClass="ui-confirmdialog-yes" icon="ui-icon-check" />
<p:commandButton value="No" type="button" styleClass="ui-confirmdialog-no" icon="ui-icon-close" />
</p:confirmDialog>
</h:panelgGroup/>
</h:form>
Bean code:
#ManagedBean(name="bean")
#ViewScoped
public class Bean implements Serializable {
private SomeClass object;
#PostConstruct
public void init(){
this.object = new SomeClass();
}
public void calculate(){
//do some colculation (not related to amount field in object)
}
public void submit(){
//submit to database
}
//getter setter
}
When I enter a value in amount, lets say 50. and update the cal component I get the updated amount in the outputtext "50". However, in the confirm button message I get amount as 0 instead 50. How can I show the updated value in the confirm message?
PS:
Primefaces-4.0
Take a look at the user guide of primefaces in the confirm dialog section, in the Non-Global mode the document mentioned:
Message facet is
useful if you need to place custom content instead of simple text.
While in the Global mode, I can't find similar sentences like that, and I've tried using the facet in Global mode and it doesn't work.So,
Do you really use this confirm dialog multiple times?
If not:
I suggest you take away the global parameter and change your code like this:
<h:form>
<p:inputText value="#{bean.object.amount}"/>
<p:commandButton value="CALCULATE" update="cal" actionListener="#{bean.calculate()}"/>
<h:panelGroup id="cal">
<h:outputText value="#{bean.object.amount}"/>
<p:commandButton value="SUBMIT" actionListener="#{bean.submit()}" oncomplete="PF('confirmDlg').show()"/>
<p:confirmDialog header="Confirmation" widgetVar="confirmDlg">
<f:facet name="message">
<h:outputText value='Amount is : #{bean.object.amount} ?'/>
</f:facet>
<p:commandButton value="Yes" type="button" styleClass="ui-confirmdialog-yes" icon="ui-icon-check" />
<p:commandButton value="No" type="button" styleClass="ui-confirmdialog-no" icon="ui-icon-close" />
</p:confirmDialog>
</h:panelGroup>
</h:form>
.
If so:
(You do use the confirm dialog multiple times and tired of writing several dialogs with same form but different message.)
I suggest you write a dialog on your own,and you can also change the message in the dialog from backing bean like what you did:
<h:form id="myForm">
<p:inputText value="#{bean.object.amount}"/>
<p:commandButton value="CALCULATE" update="cal" actionListener="#{bean.calculate()}"/>
<h:panelGroup id="cal">
<h:outputText value="#{bean.object.amount}"/>
<ui:param name="message" value="Amount is :#{bean.object.amount}?" />
<p:commandButton value="SUBMIT" actionListener="#{bean.setMessage(message)}" action="#{bean.submit()}" update="myForm:myDialog" oncomplete="PF('myDlg').show()"/>
</h:panelGroup>
<p:dialog id='myDialog' widgetVar="myDlg" header="Confirmation" modal="true" resizable="false">
<h:panelGrid columns="3">
<h:panelGroup styleClass="ui-icon ui-icon-alert" style="float:right"/>
<h:outputText value="#{bean.message}"/>
<h:outputText/>
<h:outputText/>
<p:commandButton value="Yes" type="button" icon="ui-icon-check" oncomplete="PF('myDlg').hide()"/>
<p:commandButton value="No" type="button" icon="ui-icon-close" onclick="PF('myDlg').hide()"/>
</h:panelGrid>
</p:dialog>
</h:form>
p:confirm does not implement state saving, thus it loses its attributes' values after the first JSF lifecycle. It also evaluates EL only once at view build time.
I posted the solution in this answer.

use <p:commandbutton> in <p:datatable> to show a <p:dialog>

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.

Open <p:dialog> from bean by RequestContext#execute()

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)

How can I get my commandButton by Id?

I want to change my ActionListener of commandButton depending on the icon selected in advance:
<p:dialog id="dialog" header="Add Memo" widgetVar="dialogMemo" resizable="false" >
<h:form>
<h:panelGrid columns="2" cellpadding="5">
<h:outputLabel for="commentInput" value="Comment:" />
<p:inputTextarea id="commentInput" value="#{dashboardBean.getCurrentComment()}" rows="6" cols="25" label="commentInput"/>
<p:watermark for="commentInput" value="Enter your memo..."/>
<h:outputLabel for="selectShare" value="Share Memo: " />
<p:selectBooleanCheckbox id="selectShare" />
<h:outputLabel for="choosePriority" value="Priority:" />
<p:selectOneMenu id="choosePriority" value="#{dashboardBean.currentPriority}" label="choosePriority">
<f:selectItem itemLabel="Low Priority" itemValue="1" />
<f:selectItem itemLabel="Medium Priority" itemValue="2" />
<f:selectItem itemLabel="High Priority" itemValue="3" />
</p:selectOneMenu>
<p:commandButton id="submitDialog" icon="ui-icon-check" value="Confirm" ajax='false' type="submit" action="#{dashboardBean.getLastMemo()}"/>
<p:commandButton icon="ui-icon-close" onclick="dialogMemo.hide();" value="Cancel"/>
</h:panelGrid>
</h:form>
</p:dialog>
<p:layout fullPage="true">
<p:layoutUnit id="leftPanel" position="west" size="250" header="My Memos" resizable="false" closable="false" collapsible="false">
<h:form id="form">
<p:commandButton id="addMemo" icon="ui-icon-plus" onclick="dialogMemo.show();" type="submit" action="#{dashboardBean.getEditControl}"/>
<p:dashboard id="dashboardId" model="#{dashboardBean.model}" binding="#{dashboardBean.dashboard}">
</p:dashboard>
</h:form>
</p:layoutUnit>
</h:body>
When i click to command button (id="addMemo"), i want to change actionListener to commandButton(id="submitDialog").
I try that with:
public void getEditControl()
{
UIViewRoot view = _context.getViewRoot();
CommandButton button = (CommandButton) view.findComponent("submitDialog");
System.out.println("I am ID ==== [ " + button.getId() +" ]");
}
But 'button.getId()' does't work.
But 'button.getId()' does't work.
I gather that this is because the button is actually null and therefore the attempt to invoke the getId() method threw a NullPointerException? It's surprising that you stated the problem like that, "button.getId() doesn't work" instead of like "view.findComponent() returned null" (which has in turn the pretty obvious consequence that any attempt to access it would throw NullPointerException). If you had indeed no clue why it threw NullPointerException, then I strongly recommend to take a JSF pause and learn basic Java first.
Coming back to the concrete problem, the findComponent will return null when the client ID submitDialog doesn't exist in the component tree. Indeed, you have it inside a <h:form> which is a NamingContainer component. The button's client ID is more likely formId:submitDialog where formId is the ID of the button's parent form which you have to assign yet. An easy way to find out it is checking the ID of the generated HTML representation of the button.
See also this related question: How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar" Just substitute "ajax" in the answer with findComponent.
I am not sure that the way you do this is the right way.
If you want to get component instance better way to do this will be not get it by id but add
<p:commandButton id="submitDialog" icon="ui-icon-check"
value="Confirm" ajax='false' type="submit"
action="#{dashboardBean.getLastMemo()}" binding="#{dashboardBean.component}" />
and that way the property in the bean will always have the component instance that you need.
Note that the scope of bean where you put component binding should be view to avoid side affects.

Resources