I need your help in showing an error message in the dialog. By clicking on the commandButton, no message is shown in the dialog.
Even though I tried to show the message in a dialog, but nothing is shown without any error.
So how can I produce messages in a dialog and not in the main form
Here is the JSF page code:
<h:form id="Requests">
<p:messages id="messages" showDetail="true" autoUpdate="true" closable="true"/>
<p:dialog id="c1" header="C1" widgetVar="c1">
<p:message id="messagePDFSTAR"
for=":Requests:DownloadPDFSTAR"
showDetail="true" />
<p:commandButton id="DownloadPDFSTAR"
value="Download"
ajax="false"
actionListener="#{hrd.PDFSTAR}"
update=":Requests:messagePDFSTAR" >
<p:fileDownload value="#{hrd.fileSTAR}" />
</p:commandButton>
</p:dialog>
</h:form>
Here is the java bean code:
public void PDFSTAR() {
try {
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Ref is Null", "Ref is Null");
RequestContext.getCurrentInstance().showMessageInDialog(message);
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_FATAL, "Fatal!", "System Error"));
} catch (Exception e) {
e.printStackTrace();
}
}
It's because you have ajax=false at the commandButton, so, the attribute update::Requests:messagePDFSTAR isn't going to work.
You can't combine ajax=false and update="...", update attribute is only for ajax actions.
I understand you need the ajax=false because the p:fileDownload works with that, but maybe you can try another way to display the message you want.
I deal with that situation once and use a workaround, in p:dialog you can use a p:messages and autoUpdate=true.
<h:form id="Requests">
<p:messages id="messages" showDetail="true" autoUpdate="true" closable="true"/>
<p:dialog id="c1" header="C1" widgetVar="c1">
<p:messages id="messagesPDFSTAR"
autoUpdate="true"
showDetail="true" />
<p:commandButton id="DownloadPDFSTAR"
value="Download"
ajax="false"
actionListener="#{hrd.PDFSTAR}" >
<p:fileDownload value="#{hrd.fileSTAR}" />
</p:commandButton>
</p:dialog>
</h:form>
I hope that will help you.
Edit:
RequestContext.getCurrentInstance().showMessageInDialog(message);
It shows the message in a new dialog, but i think it's not what you want. You want to show the message in the same dialog of the commandButton and the fileDownLoad.
Ajax and update not working correctly
To update components as p:growl or p:messages after a download, or even at the start just use a p:remoteCommand and the PrimeFaces.monitorDownload(start, stop); as in the example provided here PrimeFaces File Download example
here is how I'd do it:
<script type="text/javascript">
function start() {
PF('statusDialog').show();
//maybe some other blah blah..
updateMyMessages();
}
function stop() {
PF('statusDialog').hide();
//maybe some other blah blah..
updateMyMessages();
}
</script>
<div class="card">
<p:dialog modal="true" widgetVar="statusDialog" header="Status" draggable="false" closable="false"
resizable="false">
<i class="pi pi-spinner pi-spin" style="font-size:3rem"></i>
</p:dialog>
<h:form>
<p:messages id="messagesPDFSTAR"/>
<p:remoteCommand name="updateMyMessages" update="messagesPDFSTAR" action="#{hrd.PDFSTAR}"/>
<p:commandButton value="Download" ajax="false" onclick="PrimeFaces.monitorDownload(start, stop);"
icon="pi pi-arrow-down" styleClass="p-mr-2">
<p:fileDownload value="#{fileDownloadView.file}"/>
</p:commandButton>
</div>
Please note that I called the remote command twice so you get two updates to your messages, also this will execute your action #{hrd.PDFSTAR} twice, once on download start and the other on download finish, so modify as you see fit.
You can always upgrade to PrimeFaces 10+ and use ajax="true" (the default) on the download command button.
Related
I am unable to download the zip file.
After clicking ok button in confirmDialog I am unable to download a zip file.
If I am not using confirmDialog I can able to download the file.
Could any one help me on this,
Here I added the code for the reference.
<h:form>
<p:panelGrid rendered="true">
<p:commandButton style="HEIGHT: 24px; WIDTH: 300px" id="AjaxFalse"
value="AjaxFalse"
action="#{testDownload.getZipFile}"
title="AjaxFalse" rendered="true">
<p:confirm message="Are you sure?"
header="Confirmation"
icon="ui-icon-alert" />
</p:commandButton>
</p:panelGrid>
<p:confirmDialog global="true" showEffect="fade" hideEffect="fade" width="500">
<h:panelGroup layout="block" style="text-align: center">
<p:commandButton value="Ok" type="submit" styleClass="ui-confirmdialog-yes" style="width:70px;"/>
<p:commandButton value="Cancel" type="button" styleClass="ui-confirmdialog-no" style="width:70px;"/>
</h:panelGroup>
</p:confirmDialog>
</h:form>
My backingbean is
public class TestDownload
{
//some code here
//Downloading the zip file in jsf2.x
public String getZipFile()
{
try{
//enter code here
FacesContext fc = FacesContext.getCurrentInstance();
ExternalContext ec = fc.getExternalContext();
ec.setResponseHeader("Content-Disposition", "attachment;filename=\"" + Test + ".zip\"");
ec.setResponseCharacterEncoding("UTF-8");
ec.setResponseContentType("application/zip");
//This method will generate the required file.
new BulkloadImporter().generateIntegrationXSDs(getId(), ec.getResponseOutputStream());
fc.responseComplete();
return "Save";
}
catch(Exception e)
{
//Handling exception
}
}
//some code here
}
This issue is not 'download' related. Up to now (PrimeFaces 5.3/5.3.2) using a <p:confirm...> global dialog in combination with ajax="false" does not work. The server side action in general will not be called.
There are two possible solutions:
Don't use global mode and do the download on the button in the confirmDialog
Use the workaround mentioned in the issue (not tested this myself)
An example of non-global usage can be found in the PrimeFaces Documentation (adapted to this case):
Getting started with ConfirmDialog ConfirmDialog has two modes; global and non-global. Non-Global mode is almost same as the dialog
component used with a simple client side api, show() and hide().
<h:form>
<p:commandButton type="button" onclick="PF('cd').show()" />
<p:confirmDialog message="Are you sure about downloading this file?"
header="Initiating download" severity="alert"
widgetVar="cd">
<p:commandButton value="Yes Sure" action="#{testDownload.getZipFile}" ajax="false"
update="messages" oncomplete="PF('cd').hide()"/>
<p:commandButton value="Not Yet" onclick="PF('cd').hide();" type="button" />
</p:confirmDialog>
</h:form>
I have jsf page with TabView... Together 3 tabs. Tabs calls dialogs with some forms for creating elements. Dialogs are placed in external .xhtml page.
First tab is on "main" page (code placed below) and growl message called from validation bean shows well on the page. Second tab is calling growl message but from button placed on form from external file with dialogs... No errors occurs but the growl message didn't show at all.
My "main" view:
<ui:composition>
<p:growl id="growl" showDetail="true" life="4000" />
<h:form id="systemSettingsForm">
<p:tabView id="ticketSettingsTab" rendered="true" widgetVar="tabViewVar">
<p:tab id="tab0">
...
</p:tab>
<p:tab id="tab1">
<ui:include src="/WEB-INF/tags/dialogs.xhtml" />
<p:commandButton value="Add" oncomplete="PF('addDialog').show()" update=":systemSettingsForm:ticketSettingsTab:addingDlg" />
...
</p:tab>
</p:tabView>
</h:form>
</ui:composition>
</h:body>
Dialogs view looks like (nothing special as I think...):
<p:dialog id="addPositionDlg" header="Add position" widgetVar="addDialog">
<h:panelGrid id="addingDlg" columns="3" >
<p:outputLabel value="Position name :"/>
<p:selectOneMenu id="selectType" value="#{positionsTableView.positionType}" >
<f:selectItem itemLabel="Select one option" itemValue="" />
<f:selectItems value="#{positionsTableView.types}" />
</p:selectOneMenu>
<p:outputLabel style="width:1px;"/>
<p:outputLabel value="Prefix :" />
<p:inputText id="addPrefix" value="#{positionsTableView.newPosition.prefix}" />
<pe:tooltip for="addPrefix" showEvent="focus" hideEvent="blur">...</pe:tooltip>
//few simillar inputs, not even validated
<center>
<p:commandButton value="Add" actionListener="#{positionsTableView.addByPrefix}" ajax="true"
update=":systemSettingsForm:ticketSettingsTab:mappingTable" oncomplete="PF('addDialog').hide();"/>
</center>
</h:panelGrid>
</p:dialog>
Growl message is added in actionListener invoked by command button in dialog form (#{positionsTableView.addByPrefix}) and this bean is in the same package as previous one (this working) and message is added in the same manner, which is:
public static void addMessage(String title, String message) {
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(null, new FacesMessage(title, message));
}
Both beans calling messages are session-scoped.
I have searched here and tried to google solutions but none was successful...
Please help.
MY SOLUTION:
At command button which invokes the message to be displayed on growl element I have updated whole tabView menu and it works.Maybe it's not the best solution, but updating growl id causes an error (it was not visible from dialog file).
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.
I have a field that has a required attribute. When I press the Accept button to save some data without entering any value in the field, an error message is displayed. So far so good.
But, if right after that I decide to click on the Cancel button, that error message overrides the confirmation message that is supposed to be displayed inside a <p:dialog/> element.
NOTE: If instead I use the <p:confirmDialog/> component, there seems to be no problem because, I guess, it uses a message="" attribute, no the <p:messages/> tag.
XHTML
<p:dialog>
<p:outputPanel>
<h:form>
<h:outputText value="Field:"/>
<p:inputText id="field" value="" type="text" required="true" requiredMessage="You must complete the field" />
<p:growl id="messages" showDetail="true"/>
<p:commandButton id="dialogCancel" value="Cancel" oncomplete="confirmCancelDialog.show();" actionListener="#{controller.addCloseWarn}" />
</h:form>
</p:outputPanel>
</p:dialog>
<h:form>
<p:dialog id="confirmCancelDialog" header="Warning!" widgetVar="confirmCancelDialog" modal="true" >
<p:messages id="closeMessage" showDetail="true" autoUpdate="true" />
<p:commandButton id="confirm" value="Accept" onclick="..." />
<p:commandButton id="decline" value="Cancel" onclick="..." />
</p:dialog>
</h:form>
Bean controller
public void addCloseWarn(ActionEvent actionEvent) {
FacesContext.getCurrentInstance().addMessage("closeMessage", new FacesMessage(FacesMessage.SEVERITY_WARN, null,
"Are you sure you want to leave the page?"));
}
Problem with Cancel button is that your form is submitted and validation is executed. You can add process="#this" attribute to commandButton, so other parts of form will not be processed and your addCloseWarn method will be executed.
I would also add that this is probably not standard use of message tag. It is used to show errors, warning and successful messages, not confirmation questions. So use confirmDialog or use standard dialog with just ordinary text and OK - Cancel buttons.
I have read similar questions on SA and the Primefaces forum but it did not help. Here is the xhtml:
<h:form id="form2" prependId="false">
<p:remoteCommand name="sendNameClicked" actionListener="#{reportBean.passName}"/>
<p:remoteCommand name="updateDialog" update=":form3:dialogBox"/>
<p:commandButton style="display: none" id="displayDialog" type="button" onclick="cd.show(); return false;"/>
</h:form>
<h:form id="form3">
<p:confirmDialog id ="dialogBox" message= "#{reportBean.getClickedAuthorLaius()}"
header="#{reportBean.nameClicked}#{reportBean.authorClicked.mostRecentAffiliation}"
widgetVar="cd"
severity="info"
>
<h:outputText styleClass="ui-widget" value="" escape="false" />
<p:commandButton value="Draw the ring of #{reportBean.obtainFullName()}?" actionListener ="#{controllerBean.prepareNewSearch()}" action ="index?faces-redirect=true" oncomplete="cd.hide();"/>
<p:commandButton value="No, stay on this page" onclick="cd.hide();" type="button" />
</p:confirmDialog>
</h:form>
Any help very much appreciated!
The onclick is fired before the form submit request is sent. The update is performed after form submit response is arrived. So, the confirm dialog is updated after it's been opened and thus get its default appearance again.
You need to open it after the update. Use the oncomplete attribute instead of onclick.
<p:commandButton ... oncomplete="cd.show()"/>