How to invoke managed bean action in rich:popupPanel - jsf

I need to confirm with the user if he or she are sure about delete his or her account.
For this I think a popup screen would be cool. But most browser block the popup windows.
So I was trying to do that with popupPanel.
But I'm guessing that would not be possible because I have a commandLink inside of it, here's what I'm doind so far :
<rich:popupPanel id="popup_delete_profile" modal="true" onmaskclick="#{rich:component('popup_delete_profile')}.hide()">
        <f:facet name="header">
            <h:outputText value="Aviso" />
        </f:facet>
        <f:facet name="controls">
            <h:outputLink value="#" onclick="#{rich:component('popup_delete_profile')}.hide(); return false;">
Close
            </h:outputLink>
        </f:facet>
        <p>Are you sure ?</p>
<h:commandLink value="Yes" action="#{userc.deleteUser}"></h:commandLink>
<h:outputLink value="#" onclick="#{rich:component('popup_delete_profile')}.hide(); return false;">
No
     </h:outputLink>
    </rich:popupPanel>
This is my manageBean:
public void deleteUser(){
try {
eaoUser.delete(userb.getUser());
// here I would like to refresh the popupPanel saying that was deleted with success and then logout
} catch (Exception e) {
view.errorMessage("ocorreu um erro, por favor tente novamente");
e.printStackTrace();
}
}
EDIT:
public String deleteUser() {
FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
return "/index.xhtml?faces-redirect=true";
}
Any idea how to do that ?

There are two samples for your problem in the richFaces live demo
RichFaces 3.3
RichFaces 4.0
In the RF 4 live demo, they include a sample of the Managed Bean.
Hope it helps.

How to invoke managed bean action in rich:popupPanel
Add this code in your popUp.xhtml page
Note:replace rich:popuppanal and use rich:modalPanel
<a4j:commandLink styleClass="no-decor" execute="#this" render="#none"
oncomplete="#{rich:component('confirmPane')}.show()">
<h:graphicImage value="/images/icon-delete.gif" />
</a4j:commandLink>
<rich:modalPanel id="confirmPane" width="282" height="70">
Are you sure you want to delete the row?
<button id="cancel" onclick="#{rich:component('confirmPane')}.hide();" >
<h:outputText value="cancel" escape="false" />
</button>
<button id="delete" onclick="#{rich:component('confirmPane')}.hide(); clickHiddenButton('officeForm:yesSubmit');return true;">
<h:outputText value="yes" escape="false" />
</button>
<h:commandButton id="yesSubmit" style="visibility:hidden;"
onclick="#{rich:component('confirmPane')}.hide()" action="deleteRecord" />
</rich:modalPanel>

Related

Unable to download the zip file after clicking confirmDialog ok button

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>

Error Message in modal JSF doesn´t work

I have one xhtm in jsf and one modal within.
In this modal I have one field that I´m trying to validate and return an error.
my code:
Modal:
<rich:popupPanel id="cancelssi" modal="true" width="500" height="280" zindex="2" domElementAttachment="form" show="#{demandasMB.showCancelar}" showWhenRendered="#{demandasMB.showCancelar}" >
...
<h:panelGroup layout="block" class="area-input-100" id="idmotivocancelamentopanel">
<h:panelGroup class="label-campo">Justificativa de cancelamento:</h:panelGroup>
<h:inputTextarea styleClass="textarea-form-2-linhas" id="idmotivocancelamento" value="#{demandasMB.demandas.cnmmotivocancelamento}" maxlength="255"/>
<h:message for="idmotivocancelamento" />
</h:panelGroup>
<h:panelGroup layout="block" class="clear"/>
<h:panelGroup layout="block" styleClass="alinhaBotao">
<h:commandButton value="Cancelar">
<f:ajax render="idmotivocancelamento idmotivocancelamentopanel"
event="click"
listener="#{demandasMB.preCancelar()}"
execute="#form"
/>
</h:commandButton>
<h:commandButton value="Fechar"/>
</h:panelGroup>
</rich:popupPanel>
in my MB I have:
public void preCancelar(){
if(StringUtils.isBlank(demandas.getCnmmotivocancelamento())){
FacesMessage fm = new FacesMessage("Favor preencher");
FacesContext.getCurrentInstance().addMessage("idmotivocancelamento",fm);
}else{
showConfirmacaoCancelar = true;
showCancelar = false;
}
}
I´m building FacesMessage but doesn´t appear in my modal.
What I´m doing wrong ?
thanks
You need to ajax-update idmotivocancelamentopanel to reflect the FacesMessages you're adding.
An alternative is to use the <rich:message/>. Using the ajaxRendered="true" attribute will allow the message component be automatically updated on ajax-requests. So you'll instead have:
<rich:message for="idmotivocancelamento" ajaxRendered="true"/>

Is it possible to submit a <h:commandlink> action without closing a modalpanel?

I have the following inside a richfaces modalpanel:
<ui:repeat id="al11" var="albumslistvalue1" value="#{AlbumDetailBean.getAlbumImagesList()}"
varStatus="albumslistvalue1Index">
<rich:modalPanel id="panel#{albumslistvalue1Index}" width="850" height="560">
<f:facet name="header">
<h:panelGroup>
<h:outputText value="Fotos"/>
</h:panelGroup>
</f:facet>
<f:facet name="controls">
<h:panelGroup>
<h:graphicImage value="/img/modal/close.png" styleClass="hidelink" id="hidelink"/>
<rich:componentControl for="panel" attachTo="hidelink" operation="hide"
event="onclick" />
</h:panelGroup>
</f:facet>
<!-- content-->
<center>
<h:graphicImage value="img/cart/prior16.png" />
<h:graphicImage value="albums/#{albumslistvalue1.albumImageId}/med_#{albumslistvalue1.albumimagename}"/>
<h:graphicImage value="img/cart/next16.png" />
<h:commandLink id="comp" action="#{AlbumDetailBean.getCartAlbums()}">
<div>
<h:outputText value="Comprar" />
<f:param name="albumproductid" value="#{albumslistvalue1.id}" />
</div>
</h:commandLink>
</center>
</rich:modalPanel>
<h:outputLink value="#" id="link">
<!-- Show Modal Panel -->
<h:graphicImage id="image" url="albums/#{albumslistvalue1.albumImageId}/mini_#{albumslistvalue1.albumimagename}"
width="100px" height="auto" />
<rich:componentControl for="panel#{albumslistvalue1Index}" attachTo="link"
operation="show" event="onclick" />
</h:outputLink>
</ui:repeat>
and getCartAlbums() method:
public List getCartAlbums() {
boolean status = false;
AlbumImpl bean1 = new AlbumImpl();
String productidval = ((HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest()).getParameter("albumproductid");
AlbumDetailBean albums = (AlbumDetailBean) bean1.bo_getAlbumImageDetails(productidval);
if(albums != null) {
cartAlbumDetails.add(albums);
setId(albums.getId());
setAlbumname(albums.getAlbumname());
setSchoolId(albums.getSchoolId());
setAlbumImageId(albums.getAlbumImageId());
setAlbumimagename(albums.getAlbumimagename());
// setAlbumimage(albums.getAlbumimage());
setListPrice(albums.getListPrice());
setAvailableQty(albums.getAvailableQty());
setTotalAmount(albums.getTotalAmount());
setProductcode(albums.getProductcode());
setListpricevalue(albums.getListpricevalue());
setProductsize(albums.getProductsize());
setQtyvalue(albums.getQtyvalue());
setTotalpricevalue(albums.getTotalpricevalue());
setProductid(albums.getProductid());
setShipPrice(albums.getShipPrice());
}
return cartAlbumDetails;
}
I'm using someone else's code, so i didn't write the getCartAlbums() method, but it basically add the select image to the cart, it's working, the images are added to the cart correctly, but the modalpanel still closes
I think you're using JSF 1/RF3? getCartAlbums() is returning a list, is this right? My JSF 1 knowledge is from the distant past but it doesn't look right.
However, the problem is that the h:commandLink is doing a full page submit, a POST request which reloads the page with the results of the postback (the response to the POST request). So after the button is pushed you see the screen redraw and what you're seeing is the page in the same state (albeit with updated values) as it was in when you first loaded it, which is without a modalPanel.
To remedy the problem you want to use a4j:commandLink to perform an ajax partial submit. I'm not sure if RF3 has execute= and render= attributes on the a4j:commandLink component or whether you have to use a4j:support as a child component, but I'm sure you can find out. You use execute= to specify which components values are submitted in the body of the ajax POST request, and render= to specify which components are updated after the postback is received.

Show progress image while executing JSF managed bean action

My question kind of applies to Prime Faces progress bar but any vanilla jsf implementations(using jquery) would be helpful. My problem is when I start the long mysql query I also render the progress bar. The problem is it starts it's progress after the data query is complete. I'm guessing because the render phase isn't applied until the back end stuff is complete. Would I need to start the progress bar in another thread?
The progress bar doesn't necessarily have to show where the query is at(if that is even possible). I really just want to show the application "thinking". Maybe with some text or an animated gif. Thanks for any help.
EDIT
This is what I have.
<p:ajaxStatus>
<f:facet name="start">
<h:graphicImage value="/resources/images/ajax-loader-bar.gif" />
</f:facet>
<f:facet name="complete">
<h:graphicImage value="/resources/images/ajax-loader-bar-still.gif" />
</f:facet>
<f:facet name="default">
<h:graphicImage value="/resources/images/ajax-loader-bar-still.gif" />
</f:facet>
</p:ajaxStatus>
The request is not ajax.
<p:commandButton value="Yes" update="growl" onclick="confirmation.hide()"
action="#{viewLines.downloadFile}" ajax="false" />
The method behind it is.
public void downloadFile() {
if (selectedPkgLine != null) {
ExcelSheet excelSheet = new ExcelSheet();
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
String pkgLineName = StringUtils.removeSpaces(StringUtils.stripGarbage(selectedPkgLine.getShortname()));
StringBuilder builder = new StringBuilder();
builder.append(pkgLineName);
builder.append(".xls");
externalContext.setResponseContentType("application/vnd.ms-excel");
externalContext.setResponseHeader("Content-Disposition", "attachment; filename=" + builder.toString());
try {
excelSheet.writeExcelSheet(this, externalContext.getResponseOutputStream());
} catch (WriteException ex) {
FacesUtils.addFatalMessage(ex.getMessage());
} catch (IOException ex) {
FacesUtils.addErrorMessage(ex.getMessage());
} catch (ServletException ex) {
FacesUtils.addErrorMessage(ex.getMessage());
}
facesContext.responseComplete();
} else {
submitDisabled = true;
FacesUtils.addErrorMessage("No packaging line was selected");
}
}
Grab some animated icon from http://ajaxload.info, include it in your page with CSS display: none; and use JavaScript to make it display: block; during onclick:
<h:commandButton onclick="document.getElementById('progress').style.display='block'" />
<img id="progress" src="progress.gif" style="display:none" />
Or if you prefer jQuery (which is already part of PrimeFaces):
<h:commandButton onclick="$('#progress').show()" />
<img id="progress" src="progress.gif" style="display:none" />
This however only works fine with synchronous requests. Since you're using PrimeFaces, I'd suggest to use p:ajaxStatus instead since it will take asynchronous (ajax) requests into account. Just put this piece of code anywhere in the template, you need only one of it. It will work for every <p:commandButton> and <p:commandLink> without ajax="false" and the <p:ajax>.
<img id="progress" src="progress.gif" style="display:none" />
<p:ajaxStatus>
<f:facet name="start"><h:graphicImage value="progress.gif" /></f:facet>
<f:facet name="success"><h:outputText value="" /></f:facet>
<f:facet name="error">An error has occurred!</f:facet>
</p:ajaxStatus>
If you want to intercept on the standard JSF <f:ajax>, then use <f:ajax onevent> instead.
<h:commandButton>
<f:ajax onevent="progressListener" />
</h:commandButton>
<img id="progress" src="progress.gif" style="display:none" />
With this JavaScript function:
function progressListener(data) {
document.getElementById("progress").style.display = (status == "begin") ? "block" : "none";
}

Passing action in <rich:modalPanel>

There is some way to pass action in <rich:modalPanel>. I want to write simple popup with "Yes" and "No" button, and I want to reuse this popup in different pages, that's why I need that different action was invoked when "Yes" button pressed. There is a way to pass some value in <rich:modalPanel> with <a4j:actionparam>:
<a4j:commandButton value="See details…" id="det"
reRender="popup_dataIdField, …">
<rich:componentControl for="popup"
operation="show" event="onclick" />
<a4j:actionparam name="message" assignTo="#{popupBean.message}"
value="#{myBean.message}" />
</a4j:commandButton>
But is some way to pass action ?
As you're using Facelets then look at Rick Hightower's article and the section "Passing Actions". It's the same basic method to what you've used, but also passing in the method on the bean.
Eg:
<ui:include src="./WEB-INF/popup/popup.xhtml">
<ui:param name="yesAction" value="save"/>
<ui:param name="cancelAction" value="cancel"/>
<ui:param name="backingBean" value="#{thisPageBean}"/>
</ui:include>
And then in the popup:
<a4j:commandButton id="yesButton" value="#{msgs.yesButton}"
action="#{backingBean[yesAction]}"/>
Note that you use the #.
I find the answer by myself :). Maybe it will be helpful for somebody.
I've done this using Facelets. When I'm include popup to my page I pass parametr to it:
<ui:include src="./WEB-INF/popup/popup.xhtml">
<ui:param name="yesAction" value="${thisPageBean}" />
</ui:include>
Where thisPageBean - is bean from what popup invoked.
Then in my popup I wrote:
<a4j:commandButton id="yesButton" value="#{msgs.yesButton}"
action="#{yesAction.someAtion}"
</a4j:commandButton>
And with this I invoke thisPageBean.someAtion. All magic is ${thisPageBean}, it's is necessary to us $ but no #.
Yes I dont see any problems with doing this. You can use my code if you want:
<rich:modalPanel id="popup" width="261" height="386" autosized="true"left="180" top="200" keepVisualState="true">
<h:panelGrid id="panelGrid">
<h:outputText value="#{PopupBean.output}" id="popupMessage"/>
<a4j:commandLink action="#">
<h:outputText value="Close" />
<rich:componentControl for="popup" operation="hide" event="onclick"/>
</a4j:commandLink>
</h:panelGrid>
</rich:modalPanel>
<h:panelGrid columns="2">
<a4j:commandLink action="#" reRender="panelGrid">
<h:outputText value="Yes" />
<rich:componentControl for="popup" operation="show" event="onclick"/>
<a4j:actionparam name="message" assignTo="#{PopupBean.output}" value="#{TestBean.input1}"/>
</a4j:commandLink>
<a4j:commandLink action="#" reRender="panelGrid">
<h:outputText value="No" />
<rich:componentControl for="popup" operation="show" event="onclick"/>
<a4j:actionparam name="message2" assignTo="#{PopupBean.output}" value="#{TestBean.input2}"/>
</a4j:commandLink>
</h:panelGrid>
Basicly the output in the modal panel will contain the values in the TestBean
Edit (the misunderstanding):
I believe you will have to define your modal panel like this:
<rich:modalPanel id="popup" width="261" height="386" autosized="true"left="180" top="200" keepVisualState="true"
binding="#{PopupBean.popupPanel}">
</rich:modalPanel>
And in your managed bean you will have to addChildren to your modal panel dynamically with java like this:
public String action_PoppingThePanel() {
HtmlCommandButton button = new HtmlCommandButton();
button.setValue("Yes");
String action = "#{TestBean.action_yes}";
MethodExpression methodExpression =
FacesContext.getCurrentInstance().getApplication().getExpressionFactory().
createMethodExpression(FacesContext.getCurrentInstance().getELContext(), action, null,
new Class<?>[0]);
button.setActionExpression(methodExpression);
getPopupPanel().getChildren().add(button);
button = new HtmlCommandButton();
button.setValue("No");
String action = "#{TestBean.action_no}";
methodExpression =
FacesContext.getCurrentInstance().getApplication().getExpressionFactory().
createMethodExpression(FacesContext.getCurrentInstance().getELContext(), action, null,
new Class<?>[0]);
button.setActionExpression(methodExpression);
getPopupPanel().getChildren().add(button);
getPopupPanel().setRendered(true);
getPopupPanel().setShowWhenRendered(true);
return null;
}

Resources