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";
}
Related
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"/>
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.
I'm a newbie with JSF so it's really possible that my question is stupid ;-)
I must create a rich:toolTip with "mode=ajax" and I need to send a parameter to my Bean to be able to find the data displayed in the tooltip.
I have tried to do that with but it's not working.
This is my code:
<h:outputText value="#{resultPrestationBean.mainPanelViewOne.data}" id="anId">
<rich:tooltip mode="ajax" showDelay="250">
<a4j:actionparam id="test2" value="MyValue" assignTo="#{resultPrestationBean.test2}"/>
<f:facet name="defaultContent">
<f:verbatim>Loading...</f:verbatim>
</f:facet>
<h:outputText value="info #{resultPrestationBean.test}" />
</rich:tooltip>
</h:outputText>
And this is the code in my ResultPrestationBean
public String getTest() {
return "Blabla " + this.test2;
}
public void setTest2(String test2) {
this.test2 = test2;
}
public void test2(String test2) {
this.test2 = test2;
}
And the result in my tooltip is always "info Blabla null"
If I use the Net panel in Firebug, I see the parameter in the POST...
Could you explain me?
I don't believe you can send an actionparam without an action. I tried this out and was able to get it working by creating a a4j:jsFunction and putting the parameter inside it. This jsFunction would then be called on the onshow event of the tooltip. BTW, I'm using richfaces 4.
<rich:tooltip id="tool1" mode="ajax" showDelay="500" layout="block" followMouse="false" onshow="send();">
<h:outputText id="tool" value="New Entry #{timesheetHome.rowNum}" />
</rich:tooltip>
<a:jsFunction name="send" render="tool">
<a:param name="x" value="5" assignTo="#{timesheetHome.rowNum}"></a:param>
</a:jsFunction>
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>
I have request scope backing bean for login page( I am using Spring Security ). When authentication error occurs Spring put it to context and I am trying add error message to my page.
public void doLogin() throws IOException {
final FacesContext context = FacesContext.getCurrentInstance();
ExternalContext externalContext = context.getExternalContext();
externalContext.dispatch("/j_spring_security_check");
if (externalContext.getRemoteUser() == null) {
Exception loginError = (Exception) externalContext.getSessionMap().get(
AbstractProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY);
if (loginError instanceof BadCredentialsException) {
externalContext.getSessionMap().put(
AbstractProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY, null);
context.addMessage("loginBtn", new FacesMessage(FacesMessage.SEVERITY_ERROR, "Invalid credentials!", null));
context.responseComplete();
}
}
context.renderResponse();
}
my page:
<a4j:form prependId="false">
<h:panelGrid columns="2" cellpadding="5" >
<h:outputText value="#{msgs.login_username}"/>
<h:inputText id="j_username"/>
<h:outputText value="#{msgs.login_password}"/>
<h:inputSecret id="j_password"/>
<h:outputText value=" "/>
<f:facet name="footer">
<h:panelGroup>
<h:commandButton type="submit" id="loginBtn" action="#{guest.doLogin}" value="#{msgs.login}" />
<rich:spacer width="5" height="1"/>
<rich:message id="errorForLogin" for="loginBtn">
<f:facet name="errorMarker">
<h:graphicImage value="./resources/forbidden.gif"/>
</f:facet>
</rich:message>
</h:panelGroup>
</f:facet>
</h:panelGrid>
<br/><br/>
</a4j:form>
But it's don't works. I am trying put error displaying code to #PostConstruct method but this didn't help. This work only if I implement my PhaseListener but I think this is bad idea because it invokes on every request. What my mistake, there are some ways add error message from method, maybe in #PostConstruct method?
You can approach this from other side. As you use SpringSecurity, you can subclass AuthenticationProcessingFilter and override onUnsuccessfulAuthentication method. There you can put the code for desired behaviour. Then you just specify your custom authentication processing filter class instead of AuthenticationProcessingFilter in correspondent bean definition for Spring Security.