Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Progress bar primefaces on backend processing

Tags:

jsf

primefaces

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.

like image 394
user1152660 Avatar asked Jul 15 '13 14:07

user1152660


1 Answers

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.

Progress Bar

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

like image 171
Andy Avatar answered Oct 21 '22 08:10

Andy