I would appreciate it if someone can give me some hints about progress bar and ajax back-end processing.
To clarify what I need following are details:
I have a command button to do some processing at the back-end. I would like to show a progress bar that reach the 100% when the backing bean finishes processing back-end instructions. I looked over many threads but no luck. Most of them did not show a concrete sample how to do that. Below is a snippet of my code:
</h:panelGrid>
<p:commandButton id="btn" value="DoSomeAction"
styleClass="ui-priority-primary" update="panel"
onclick="PF('pbAjax').start();PF('startButton1').disable();"
widgetVar="startButton1"
actionListener="#{actionBean.DoSomeAction}" />
<p:progressBar widgetVar="pbAjax" ajax="true"
value="#{progressBean.progress}" labelTemplate="{value}%"
styleClass="animated">
<p:ajax event="complete" listener="#{progressBean.onComplete}"
update="growl" oncomplete="startButton2.enable()" />
</p:progressBar>
</p:panel>
This is the code for the Progress Brean:
@ManagedBean(name="progressBean")
public class ProgressBean implements Serializable {
private Integer progress;
public Integer getProgress() {
if(progress == null)
progress = 0;
else {
progress = progress + (int)(Math.random() * 35);
if(progress > 100)
progress = 100;
}
return progress;
}
public void setProgress(Integer progress) {
this.progress = progress;
}
public void onComplete() {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Progress Completed", "Progress Completed"));
}
public void cancel() {
progress = null;
}
}
The result of this code is just an empty progress bar and nothing happen when I click on my button. Thanks in advance.
It'll be easier if I simply walk you through my sample code since you have two beans and I don't know the interaction between them. You can use it to apply it to yours.
<p:commandButton>
<p:commandButton value="Start" type="button" onclick="pbAjax.start();startButton1.disable();" widgetVar="startButton1" />
Nothing impressive here. You have a commandButton
with widgetVar="startButton1"
. When you click on it, onclick
comes in and disables the commandButton
. It also signals <p:progressBar>
to start via pbAjax.start()
(<p:progressBar>
has widgetVar = "pbAjax.start()"
).
<p:progressBar>
<p:progressBar widgetVar="pbAjax" value="#{progressBean.progress}" ajax="true" labelTemplate="{value}%">
<p:ajax event="complete" listener="#{progressBean.onComplete}"
update="growl" oncomplete="startButton1.enable()"/>
</p:progressBar>
<p:progressBar>
will simply keep calling #{progressBean.progress}
to update the progress. When the progress reaches 100%
<p:ajax>
kicks in and calls #{progressBean.onComplete}
. <p:commandButton>
get re-enabled and <p:growl>
gets updated. Notice how I'm not using PF(...)
. To be honest, I'm not sure if it makes a difference, I did not test.
Note
In your <p:progressBar>
you have oncomplete="startButton2.enable()
. It should be startButton1.enable()
since your widgetVar
value for your <p:commandButton>
is startButton1
.
Also, notice that I did not use styleClass="animated"
. With this, you'll just get the bland looking blue bar. If you want to use it then you need to take some extra steps. Looking at your code, it seems you're taking it straight from the PrimeFaces showcase so I'll also use their assets.
Using styleClass="animated"
First, you're going to create a folder called resources
in your webapp
folder (Web Pages
for Netbeans). Then create a folder called css
and add in a stylesheet called style.css
. The directory structure will be like this: resources/css/style.css
. In style.css
you're going to have to define this rule. (Don't worry if this is confusing, I'll have the whole code below).
.animated .ui-progressbar-value {
background-image: url("#{resource['images/pbar-ani.gif']}");
}
Then you're going to create an images
folder under resources
and place the image
pbar-ani.gif
in that folder (resources/images/pbar-ani.gif
). Image below.
Make sure you have <h:outputStylesheet name='css/style.css' />
in <h:head>
and add styleClass="animated"
in <p:progressBar>
.
Important!
If you are using PrimeFaces 3.5 like I am the image will just not display (including when you're not using styleClass
). If you look closely at Firebug you will see the following error
Uncaught TypeError: Object #<Object> has no method 'easeInOutCirc'
One workaround I found for this is to simply use dummy <p:dialog>
.
That's it.
You can get more information about the progressBar
through the developer's guide.
In case you're wondering how I knew where to get the image you'll have to download the showcase. You can read this article to find out how to download the showcase. In my opinion, when you really want to use the showcase code, it's better if you simply download the demo. Often time I'm either not seeing the complete picture or the code in the showcase has some mistakes
Anyway here's the sample code as promised. I'm using the same ProgressBean
from the showcase (same as yours). Keep in mind that you will have to come up with the logic with how your object interacts with ProgressBean
to update the progress bar.
Summary
<h:head>
<h:outputStylesheet name='css/style.css' />
</h:head>
<h:body>
<h:form >
<p:growl id="growl" />
<h3>Advanced Ajax ProgressBar</h3>
<p:commandButton value="Start" type="button" onclick="pbAjax.start();
startButton1.disable();" widgetVar="startButton1" />
<br /><br />
<p:progressBar widgetVar="pbAjax" value="#{progressBean.progress}" ajax="true" labelTemplate="{value}%" styleClass="animated">
<p:ajax event="complete" listener="#{progressBean.onComplete}"
update="growl" oncomplete="startButton1.enable()"/>
</p:progressBar>
<p:dialog></p:dialog><!-- For PrimeFaces 3.5 -->
</h:form>
</h:body>
and remember your directories
resources/css/style.css
resources/images/pbar-ani.gif
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With