Displaying ConfirmDialog depends on result of method - jsf

here is my commandButton:
<p:commandButton value="Foo" update="panel1,panel2"
action="#{fooBean.add()}" />
method fooBean.add() is checking if object i want to add is not already in database - it return true - if it is already in base, false if it is not.
what i want to do is display a success message if fooBean.add() will return false after click on button.
It would be nice if that message would be like ConfirmDialog with OK option to close poped out window. Something like this:
http://www.primefaces.org/showcase/ui/confirmDialog.jsf
Any ideas how to help me?

If I understand you correctly you just want to display a dialog, so that the user acknowledges that the action succeeded. You could simply use a growl, but here is a solution using your approach.
.xhtml
<p:commandButton value="Foo" action="#{fooBean.add()}" />
<p:dialog widgetVar="dialog" modal="true">
<p:commandButton value="Ok" icon="ui-icon-close" oncomplete="dialog.hide()" />
</p:dialog>
fooBean
public void add() {
// do stuff
if(isInDB)
RequestContext.getCurrentInstance().execute("dialog.show()");
}
This opens the dialog after your item has already been found in the database. Nevertheless it may be more convenient for the user if he'd get a more subtle notification, without extra clicks.

Related

p:commandButton is reloading the page to open dialog

So I have this code:
<h:form id="serviceCustomFormForm">
<p:dialog id="parameterGroupAddDialog" widgetVar="parameterGroupAddDialog" header="#{messages.addParameterGroup}" modal="true" resizable="false">
<p:inputText value="#{serviceCustomFormBean.serviceParameterGroup.name}" styleClass="Wid90" />
<br />
<br />
<p:commandButton value="#{messages.save}" styleClass="Fright BlueButton" update="serviceCustomFormForm" actionListener="#{serviceCustomFormBean.addServiceParameterGroup}" oncomplete="PF('parameterGroupAddDialog').hide()" />
<p:commandButton value="#{messages.cancel}" styleClass="Fright RedButton" oncomplete="PF('parameterGroupAddDialog').hide()"/>
</p:dialog>
<div class="Container100">
<div class="ContainerIndent">
<p:commandButton value="#{messages.addParameterGroup}" icon="fa fa-plus-circle" styleClass="Fright CyanButton FloatNoneOnMobile" oncomplete="PF('parameterGroupAddDialog').show()" />
<div class="EmptyBox10 ShowOnMobile"></div>
</div>
</div>
</h:form>
When the page is first loaded the #PostConstruct method is called.
When I click the commandButton to open the dialog it's called again. And when I press the Cancel button inside the dialog it's called again.
This behavior does not occur in other parts of the application, and I can't see what I am missing here.
Update: As requested, the Bean code is here:
#ManagedBean
#ViewScoped
public final class ServiceCustomFormBean implements Serializable {
private ServiceParameterGroup serviceParameterGroup = new ServiceParameterGroup();
// Other attributes
#PostConstruct
private void init() {
// Reads attributes sent from previous page
}
public void addServiceParameterGroup() {
// Saves the serviceParameterGroup to database
}
// Getters and Setters
}
It's because the Commandbutton submits the form. You can
change to this:
<p:commandButton type="button" ...onclick="PF('parameterGroupAddDialog').hide()"
Type button tells primefaces not to submit the form. If the form isn't submitted oncomplete is never called. So it's onclick.
Try setting the following attributes to your 'Add Service' and 'Cancel' commandButton elements: partialSubmit="true" process="#this".
Code like this:
<commandButton value="#{messages.addParameterGroup}" ... partialSubmit="true" process="#this" ... />
By default, pf commandButtons try to submit the whole form, while in those two cases you just want to call the invoked method without doing a submit. With this, you are saying to primefaces that you don't want to submit it all (partialSubmit=true), and that you just want to process the invocation of the button itself (process=#this). Maybe that is your problem.
As an additional comment, i don't think getting the label values for the buttons from the bean is a good idea (unless you want to intentionally change the labels dynamically), because you will end up doing excessive requests to the bean. Better try using a messages properties file, as described in here http://www.mkyong.com/jsf2/jsf-2-0-and-resource-bundles-example/.
If I remember correctly, you should put your Dialog outside your main form, at the end of your body or use the appendTo="#(body)" param, and then, have another form inside the dialog.
After a long time dealing with this problem, I finally found the reason.
The annotation ViewScoped that I was importing in the backing bean was from the package javax.faces.view.
The correct one is javax.faces.bean.
Thanks for everyone that spend some time trying to help.

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.

Primefaces process attribute in reseting form inputs

I have a form inside a modal dialog and after closing (hiding in fact) one I wanted to reset all inputs that user might have changed. I though about something like as follow:
<p:dialog widgetVar="myDialog">
<h:form id="formId">
<!-- ... -->
<p:commandButton value="Cancel" onclick="myDialog.hide();"
update="formId">
<p:resetInput target="formId" />
</p:commandButton>
</h:form>
</p:dialog>
But the result was not that I expected. After a while of searching I found a solution that was to add process="#this" attribute to the <p:commandButton>. And my question is why it is necessary? What is really happening in backgroud that this process is desired. I don't really get the idea of process attribute at all.
I have done some work with dialog boxes and the way I did to make the form null is, when clicking the button to open dialog box, I ran a method in backing bean which cleared my pojo so my form had empty values.
In your case it could be something like this:
<h:form id="form-button">
<p:commandButton id="AddButton" value="open dialog box"
update=":form" action="#{myBean.myMethodToSetPojoNull}" immediate="true"
oncomplete="PF('myDialog').show()" />
</h:form>
When clicking this button, the called method will set to null all the fields and your dialog box will be empty. Getting back to your question of why process=#this is neccessary much better explained answer is here
What is the function of #this exactly?
You can also reset input after submitting through this method:
<p:commandButton value="Reset Non-Ajax"
actionListener="#{pprBean.reset}" immediate="true" ajax="false">
<p:resetInput target="panel" />
</p:commandButton>
If you don't add process="#this" then by default attribute value will be set to process="#form" which means all the elements in the form are processed. In command buttons process="#this" is mandatory to execute the corresponding actions associated with that button.
You can directly refer the answer from Balusc in this link
What is the function of #this exactly?

Why does p:resetInput require properties of a managed bean to be set to null first after the form is submitted?

In a view scoped managed bean, I'm using <p:resetInput> to clear the values held by the properties in the corresponding manged bean like,
<p:commandButton value="Reset" update="panel" process="#this">
<p:resetInput target="panel" />
</p:commandButton>
This works fine.
I have a submit button <p:commandButton> which when pressed causes the submitted values to be inserted into the database, if validation succeeds.
<p:remoteCommand name="updateTable" update="dataTable"/>
<p:panel id="panel" header="New">
<p:outputLabel for="property1" value="property1"/>
<p:inputText id="property1" value="#{bean.property1}" required="true">
<f:validateLength minimum="2" maximum="100"/>
</p:inputText>
<p:message for="property1" showSummary="false"/>
<p:commandButton id="btnSubmit"
update="panel messages"
oncomplete="if(!args.validationFailed) {updateTable();}"
actionListener="#{bean.insert}"
value="Save"/>
<p:commandButton value="Reset" update="panel" process="#this">
<p:resetInput target="panel" />
</p:commandButton>
</p:panel>
The command button invokes the insert() method in the managed bean which is defined as follows.
public void insert() {
if (service.insert(property1)) {
//...Popup a success message.
reset(); //Invoke the following private method.
} else {
//...Show the cause of the failure.
}
}
private void reset() {
property1 = null; //Set this property of type String to null.
}
If this reset() method is omitted, then <p:inputText> will not be cleared as obvious but then if I press the reset button as shown in XHTML, <p:inputText> should be cleared but it doesn't.
The showcase example demonstrates exactly the same thing. Therefore, this behaviour appears to be documented but I don't understand why doesn't <p:resetInut> clear the value of property1, if the reset() method is omitted, in this case?
The <p:resetInput> does not clear the model values as you incorrectly seemed to expect. It just clears the input component's state which may be dirty after a validation error.
The concrete problem it is trying to solve is in detail described in this answer: How can I populate a text field using PrimeFaces AJAX after validation errors occur?
This is the best understood by the following use case:
You have a single view with a single datatable and a single dialog which displays the currently selected record for editing.
You open the dialog and submits its form with invalid values. The input components are marked invalid and highlighted red.
You close the dialog without fixing the errors.
Then you select same or another row for editing. The dialog shows up, but the input components are still marked invalid and highlighted red and show the old submitted value -if any- because it's still the same view state you're working with.
Putting <p:resetInput> with target on dialog's form in the "open dialog" button fixes it.
I'm not sure if your particular case is the right use case for which <p:resetInput> is the right solution. Your code is not complete and you didn't state the concrete functional requirement behind this code anywhere, but as far as I see, there are no multiple inputs/forms which need to update each other. I believe that your case would still work even if you remove <p:resetInput>. So it would be totally superflous in your context and you could just get away with clearing the model (or.. just with refreshing the page by a synchronous GET button which implicitly recreates the view).
See also:
PrimeFaces CommandButton that Doesn't Process Data
Escape a primefaces/jsf page that has required fields

dialog will not close primefaces

I have a dialog on one of my pages. It opens fine. It works fine if you use the button on the page, it closes. However, if you try and "x" out of the dialog it will not close. I believe it is related to the fact that I have an input field on the dialog, but I am not sure. I apologize if this is a dupe, I could not find a similar post.
<p:commandButton action="#{phoneListBean.debugger}"
value="Merge Unqiue" onclick="mdlg.show();"
update=":pmsg, :createNewPanel, :listform" />
<p:dialog id="mdialog" header="Merge Unqiue" widgetVar="mdlg"
appendToBody="true">
<h:form id="mform">
<h:panelGrid columns="2" cellpadding="5" id="m">
<h:outputLabel for="listName" value="Enter the List Name:" />
<p:inputText value="#{phoneListBean.mergeList.name}" id="listName" />
<p:commandButton action="#{phoneListBean.mergeUnique}"
value="Merge Unqiue" update=":pmsg, :listform"
onclick="mdlg.hide();" />
</h:panelGrid>
</h:form>
</p:dialog>
Thanks in advance for the help.
Your problem is that you don't want to use the onclick attribute with Primefaces buttons for displaying and hiding the dialogs. The click event may not get invoked before the postback because these buttons are not Ajax enabled.
Instead you should use oncomplete attribute. This will notify the Javascript event to execute only after the server postback has occurred, meaning that show() will display already updated dialog contents, and hide() will occur only after the server side execution has finished.

Resources