How to add confirmation check for a button which is calling a remoteCommand - jsf

I have a situation in primefaces, where I have a button which on click calls a remote command through java script as a callback, this remote command is responsible to perform save action. I want to add confirmation to the Save button based on some controller value. So the expected output is on click if that value is true I want to show the confirmation dialog else I just want to do the normal save.
I am really new to primefaces. Any help would be highly appreciated.
<p:remoteCommand name="save" actionListener="#{controller.save()}" oncomplete="PF('statusDialog').hide()"/>
<p:button value="Save" styleClass="btn-primary btn-save" onclick="PF('statusDialog').show(); Modeler.saveBpmnToForm(save)" />

Whenever you trigger the remote command you could redirect the action to show the actual confirm dialog, then from there you can associate the action with the "confirm" button. The following logic is meant to show the dialog only if your boolean variable is true, otherwise you perform the save action without showing any dialog.
<p:remoteCommand name="save" actionListener="#{controller.status ?
controller.showDialog : controller.save}" oncomplete="PF('statusDialog').hide()"/>
Whenever this remoteCommand is triggered you'll show the following dialog using the bean:
<p:dialog id="confirmDialog" >
<p:button value="Confirm" styleClass="btn-primary btn-save"
onclick="PF('statusDialog').show()" action="#{controller.save}"/>
<p:button value="Cancel" styleClass="btn-primary btn-cancel"
onclick="PF('confirmDialog').hide()"/>
</p:dialog>
The "confirm" button will perform the actual logic, the "cancel" should only close the dialog but this is up to you.

Related

Close dialog prior to navigate away from the page

PrimeFaces: 7.0
JSF: 2.2.13
JBoss: 7.1
Java: 1.8
Chrome: 83.0.4103.116
I have a simple confirmation dialog to go to another page, there a reason for the action should be provided as a text.
It boils down to the following lines of code:
<p:dialog id="dlg" widgetVar="dlg" modal="true">
<h:form id="dlgForm">
<p:inputText id="reason" required="true" value="#{bean.reason}"/>
<p:message for="reason"/>
<p:commandButton id="proceed" value="Proceed" update="dlgForm" action="#{bean.action}"/>
<p:commandButton id="cancel" value="Cancel" resetValues="true" onclick="PF('dlg').hide()">
<p:ajax update="dlgForm" resetValues="true"/>
</p:commandButton>
</h:form>
</p:dialog>
And the bean:
#ManagedBean(name = "bean")
#SessionScoped
class Bean {
public String processGrundFuerExportDlg() {
PrimeFaces.current().executeScript("PF('dlg').hide()");
return "other_page";
}
}
My requirements:
Dialog opens with the empty 'reason'-inputText.
If 'cancel' is pressed: dialog should close
If 'proceed' is pressed:
If reason is not empty: close dialog and navigate to the 'other_page'
If return is empty: show the error message and don't close the dialog
My problem with this code: the line
PrimeFaces.current().executeScript("PF('dlg').hide()");
seems to be executed AFTER the current page being left resulting in 'dlg' not being found (JavaScript error).
The not properly closed dialog produces a nasty side effect: After returning to my first page later on, the dialog overlay stays active and inputText elements can't be activated with the mouse (TAB works). Overlay logic in the event loop blocks mouse clicks to from being passed to the components on the page.
My question:
How this standard scenario should be properly implemented with JSF and PrimeFaces?
If Upgrade to other versions is required, are there some workaround for removing stale overlays without upgrading?
Disclaimer: I studied many related questions on StackOverflow and tried all proposed solutions without success. For example this one: Keep p:dialog open when a validation error occurs after submit
You won't be having this problem if you would redirect to the new page instead of triggering an Ajax update.
You can simply add ?faces-redirect=true to your returned string, so:
return "other_page?faces-redirect=true";
Or, if you are using faces-config, add <redirect/> to the <navigation-case>.
Then you can remove the script from your bean where you try to close the dialog.
See also:
How to navigate in JSF? How to make URL reflect current page (and not previous one)
If 'proceed' is pressed:
If reason is not empty: close dialog and navigate to the 'other_page'
If return is empty: show the error message and don't close the dialog.
All this above is handled with required true on reason inputText. If reason is empty action in proceed commandButton won't start.
You don' need to close your dialog before you are navigating to other page.

CommandButton not calling actionListener when I close confirmDialog

I have buttons Stop and Release which call a save method and within the save method a confirmDialog is shown. I can use the Stop button, press OK in the dialog and the method works, but then when I go to clock Release again the button doesn't call the actionListener. Similar for clicking Release, confirming then trying to Stop.
Here are the two command buttons, which sit inside modeControls.
<p:commandButton title="Stop" value="Stop"
rendered="#{unitSetVehicleStatusBean.crudMode == 'READ' and unitSetVehicleStatusBean.stopped =='false'}"
actionListener="#{unitSetVehicleStatusBean.stop}"
update="modeControls :mainForm"
process="#this :mainForm"/>
<p:commandButton title="Release" value="Release"
rendered="#{unitSetVehicleStatusBean.crudMode == 'READ' and unitSetVehicleStatusBean.stopped =='true'}"
actionListener="#{unitSetVehicleStatusBean.release}"
update="modeControls :mainForm"
process="#this :mainForm"/>
Here is the confirmDialog. The save method it calls is called from within the stop() and release() methods, then after some validation I use
RequestContext context = RequestContext
.getCurrentInstance();
context.execute("PF('saveNDTDialog').show();");
break;
and when the user selects OK in the confirmDialog it will rejoin this method part way through a switch statement and complete the save.
Here is the confirmDialog.
<p:confirmDialog id="saveNDTDialog" appendTo="#(body)"
widgetVar="saveNDTDialog" closeOnEscape="true"
closable="true"
message="#{message.stoppedValidationNDTWarning}">
<p:commandButton value="OK"
update="mainForm :modeControls"
actionListener="#{unitSetVehicleStatusBean.save('WARNING_NDT')}"
oncomplete="saveNDTDlg.hide();"/>
<p:commandButton value="Cancel"
onclick="saveNDTDlg.hide();" />
</p:confirmDialog>
I believe the issue is something to do with the appendTo or possibly onComplete, but aren't too sure what's going wrong.
Any suggestions welcome...
By pulling the dialog out of the main form and adding a form around the commandButtons in the dialogs, the dialogs began working as expected.

Call a JSF method

When user clicks the Testscript button, the method testscript should be called. But it calls a different method in my bean. Following is the sample code.
<h:form id="myform">
<h:commandButton id="testScript" actionListener="# {ScriptedPolicyBean.testScript"} />
<feat:Button onclick="document.getElementById("myForm:testScript")" />
</h:form>
Please help
Doing onclick="getElementById" does nothing but simply gets an id. As it is a button and you do not say "return false;" your form is submitted by the feat button (if it has the type submit on the rendered page). Of course in this case the actionlistener of the other button is not called at all (as it has nothing to do with the form submit).
You should call the click method on the testScript button like this: onclick="document.getElementById('myForm:testScript').click();".
It would be nice to have a simple <input type="button" /> instead of the feat:button to be sure the submit is not called by that element.

primefaces Cancel button not navigating to previous page

I have a p:commandButton, which when I click on, I want it to take me to the previous page. This is the code I have used -
<p:commandButton id="cancel" value=" Cancel" action="cancel" ajax="false" process="#this"/>
However, when I click on Cancel, nothing happens. Please let me know how I can get my button to navigate to the previous page.
You can use javascript in the oncomplete event of the button.
oncomplete = "window.history.back();"

Ignore validation on commandButton press

I have page in which I edit some entity. That page has two command buttons. One is "Back" and one is "Save" and also on that page I have form with input fields (idInputSubject). Some of them are required, some are not.
How can I ensure that we I press "Back" button (cancel editing and go back) validation will be ignored, which is not the case now. Now, when I press either "Back" or "Save" button validation's messages appear if I did't fill required filed with the correct values (idInputSubject).
Both "Back" and "Save" buttons are in the same form:
<h:form id="idFormMeasureDetail" styleClass="bodyForm" prependId="false">
...
<p:commandButton value="#{contentMB.msg.label_back.value}"
action="#{chooseMeasureControllerMB.aSearch}"
rendered="#{detailMeasureMB.navigation eq 0}" ajax="false"
icon="ui-icon-arrowreturnthick-1-w"/>
<p:commandButton value="#{contentMB.msg.button_save.value}" ajax="false"
icon="ui-icon-disk" actionListener="#{detailMeasureControllerMB.alApplyChanges}"
title="#{contentMB.msg.tip_Apply.value}" />
...
<p:inputTextarea id="idInputSubject" value="#{detailMeasureMB.measure.aufgabe}"
readonly="#{!userSessionMB.supervisor and !detailMeasureMB.isCreator}"
required="#{globalSessionMB.globalWebOptionsMap['MMRequiredSubject'].propvalue}"
title="#{contentMB.msg.tip_Betreff.value}"
autoResize="false" style="width:100%;" >
</p:inputTextarea>
<p:message id="inputSubjectMsg" for="idInputSubject" display="icon" />
...
</h:form>
ChooseMeasureControllerMB:
#ManagedBean(name = "chooseMeasureControllerMB")
#RequestScoped
public class ChooseMeasureControllerMB extends BaseMeasureControllerMB {
...
public String aSearch() {
...
// navigate to target-page
return "/pages/mm/showMeasuresList.xhtml?faces-redirect=true";
}
...
}
If you want prevent/skip validation on certain button click use
immediate="true" on that specific button
For a good explanation about the immediate="true" read the following BalusC answer
And here a nice diagram that shows how imemdiate="true works"
In short, when you're clicking the "back" button, you submit the form and the data is validated. To prevent this, place the button in another form or use Java-script for the navigation.
In general, when you want to cancel an operation you don't want to submit the data, since it is to be discarded. Use some client side action. I think you can also use a <p:commandButton> or a <p:button> for navigation. This way the form isn't submitted either.

Resources