Progress bar primefaces on backend processing
jsf, primefaces
Solution
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`
Problem
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.