0

I want to show progress.

I have progressBar on page:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html
        xmlns="http://www.w3.org/1999/xhtml"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:p="http://primefaces.org/ui">

<h:body>

    <h:form>
        <p:growl id="growl" life="2000" />

        <p:outputPanel id="statusPanel" widgetVar="statusPanel">
            <div class="ui-g">
                <div class="ui-g-12">
                    <p:progressBar widgetVar="pbAjax" ajax="true" value="#{myView.progress}" labelTemplate="{value}%" styleClass="animated" global="false">
                        <p:ajax event="complete" listener="#{myView.onComplete}" update="growl"/>
                    </p:progressBar>
                </div>
            </div>
        </p:outputPanel>

        <p:commandButton id="refresh" value="Refresh" action="#{myView.refresh}" update="@form, statusPanel" />

    </h:form>
</h:body>

</html>

MyView looks like:

package app;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Named;

@Named
public class MyView {

    Integer progress;

    int actualCount;
    int overallCount = 4;

    public void refresh() {
        try {
            for (int i = 0; i < overallCount; i++) {
                Thread.sleep(1000); // just to make it slower
                ++actualCount;
                progress = 100 * actualCount / overallCount;
                System.out.println("progress: " + progress);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public Integer getProgress() {
        System.out.println("getProgress(): " + progress + "%");
        return progress;
    }

    public void setProgress(Integer progress) {
        this.progress = progress;
    }

    public void onComplete() {
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Refresh completed"));
    }

}

but progress bar is updated only whe refresh() call ends.

I'd like to update in between...

I tried to call update

RequestContext.getCurrentInstance().update("pbAjax");

but that does not work.

edit:

I checked Progress bar primefaces on backend processing but it is just an description to showcase sample (not very helpful in my case)

Also I looked at Primefaces progressbar not updating? which looks closer to what I want to achieve, but it is not working for me:

package app;

import javax.faces.bean.ViewScoped;
import javax.inject.Named;
import java.util.Date;

@Named
@ViewScoped
public class BatchModel {

    Integer progress;

    public Integer getProgress() {
        System.out.println(new Date() + " get progress");
        return progress;
    }

    public void setProgress(Integer progress) {
        System.out.println(new Date() + " set progress: " + progress);
        this.progress = progress;
    }

}

I modified the view to:

package app;

import org.primefaces.context.RequestContext;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;

@Named
@ViewScoped
public class MyView {

    @Inject
    BatchModel batchModel;

    int actualCount;
    int overallCount = 4;

    public void refresh() {
        try {
            for (int i = 0; i < overallCount; i++) {
                Thread.sleep(1000);
                ++actualCount;
                batchModel.setProgress( 100 * actualCount / overallCount );
                RequestContext.getCurrentInstance().update("pbAjax");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void onComplete() {
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Refresh completed"));
    }

}

...added batchModel + @ViewScope

in xhtml I call the refresh() as actionListener:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html
        xmlns="http://www.w3.org/1999/xhtml"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:p="http://primefaces.org/ui">

<h:body>

    <h:form>
        <p:growl id="growl" life="2000" />

        <p:outputPanel>
            <div class="ui-g">
                <div class="ui-g-12">
                    <p:progressBar widgetVar="pbAjax" ajax="true" value="#{batchModel.progress}" labelTemplate="{value}%" styleClass="animated" global="false">
                        <p:ajax event="complete" listener="#{myView.onComplete}" update="growl"/>
                    </p:progressBar>
                </div>
            </div>
        </p:outputPanel>

        <p:commandButton id="refreshBt" value="Refresh" actionListener="#{myView.refresh}" onclick="PF('pbAjax').start()" />

    </h:form>
</h:body>

</html>

but log describes it the best:

Mon Dec 23 18:45:58 CET 2019 get progress
Mon Dec 23 18:45:58 CET 2019 get progress
Mon Dec 23 18:46:00 CET 2019 set progress: 25
Mon Dec 23 18:46:01 CET 2019 set progress: 50
Mon Dec 23 18:46:02 CET 2019 set progress: 75
Mon Dec 23 18:46:03 CET 2019 set progress: 100
Mon Dec 23 18:46:03 CET 2019 get progress
Mon Dec 23 18:46:03 CET 2019 get progress

so the get progress was called at the beginning and then at the end only...

Selaron
  • 6,105
  • 4
  • 31
  • 39
Betlista
  • 10,327
  • 13
  • 69
  • 110
  • Try the PrimeFaces showcase, it is all in there, really.... – Kukeltje Dec 23 '19 at 17:10
  • Does this answer your question? [Progress bar primefaces on backend processing](https://stackoverflow.com/questions/17657041/progress-bar-primefaces-on-backend-processing) – Kukeltje Dec 23 '19 at 17:12
  • If this is for file upload. The core functionality may exist in this answer here already - and be a better algorithm.. https://stackoverflow.com/a/22987941/495157 – JGFMK Dec 23 '19 at 17:12
  • oh and https://www.google.com/search?q=primefaces+progressbar+site:stackoverflow.com works great too – Kukeltje Dec 23 '19 at 17:13
  • @JGFMK: Strange comment, those are not PrimeFaces download progress related at all... – Kukeltje Dec 23 '19 at 17:14
  • Oh course I started with showcase, but there the progress is updated in getProgress(), which is something I cannot do (otherwise it will do all on one call without update in between). – Betlista Dec 23 '19 at 17:18
  • No, the progressbar does the calling itself each time... if it is started correctly. Check when the `onclick="PF('pbAjax').start()" ` is actually called. If that is before the actionhandler it should just work. – Kukeltje Dec 23 '19 at 17:52
  • If it is after the actionhandler, that would sort of surprise me. Can you please check that? And updating in a loop from an actionhandler will never work (due to the way JSF (and under it http) works. – Kukeltje Dec 23 '19 at 17:57
  • On the other hand, if the start is called correctly but you actually do not see an ajax call from the progressbar it might be queued. I searched for this and found https://stackoverflow.com/questions/22756945/jsf-primefaces-progressbar-update-value-while-action-method-is-running – Kukeltje Dec 23 '19 at 18:03
  • Thanks for hint I checked more properly, whether getProgress is called regularly and it was not... – Betlista Dec 23 '19 at 18:19

1 Answers1

1

The first step should be to check whether getProgress() is called regularly (even without setting the progress). The default interval is 3000ms.

In my case I had a problem with missing <head> in XHTML showing

PrimeFaces is not defined

in browser console.

Betlista
  • 10,327
  • 13
  • 69
  • 110
  • I now notice this too but then the commandbutton with ajax would not have worked either.. Nothing would have had the PrimeFaces look and feel and more would have been wrong – Kukeltje Dec 23 '19 at 18:31
  • @Kukeltje another approach for this its using ajaxStatus and calling onstart show dialog and oncomplete hide dialog no? that way is easier – BugsForBreakfast Dec 23 '19 at 19:36
  • Very weird, ajax needs PrimeFaces javascript which would be missing if the `h:head` is not there. What is your PF version? And was the xhtml code above really all there was??? Still find it hard to believe the commandbutton worked UNLESS it worked without ajax... But you could have seen that when debugging network traffic – Kukeltje Dec 23 '19 at 20:43