You can achieve this with a combination of [PrimePush][1] and [p:progressBar][2]. You can use [p:blockUI][3] in addition to block the UI. See this [entry in the Q&A][4] for how to install PrimePush.
<h:head>
<script>
function handleProgress(progressJson) {
var progressData = eval("(" + progressJson + ")");
progressBar.setValue(progressData.progress);
$("#msg").text(progressData.msg);
}
</script>
</h:head>
<h:body>
<h:form>
<p:panel id="panel" header="Realtime ProgressBar">
<p:commandButton id="btn" value="Start" actionListener="#{logic.startLongRunningProcess}"></p:commandButton>
</p:panel>
<p:blockUI block="panel" trigger="btn">
<p:progressBar widgetVar="progressBar" style="width:300px" labelTemplate="{value}%"></p:progressBar>
<span id="msg"></span>
</p:blockUI>
</h:form>
<p:socket channel="#{data.channel}" onMessage="handleProgress"></p:socket>
</h:body>
On lines 15 to 18 we define the progress bar and a label within a `p:blockUI` element. It is important to define the `widgetVar` variable because we will access it in the JavaScript function `handleProgress` to set the current value for the progress bar.
The aforementioned JavaScript function `handleProgress` receives a JSON string as input. It then transforms this JSON into a object (line 4) with the attributes `progress` and `msg`. We will use `progress` for the progress in percentage and `msg` for the label to display.
So, big question? From where we will call `handleProgress`? Well, the answer is on line 20. With `p:socket` a connection from the server to the client is opened with which the server can send messages directly to a client. And as soon as a message is send, then the JavaScript function defined in the `onMessage` attribute will be called.
The `channel` attribute of `p:socket` defines the topic on which the connection is listening. In our case we use a process data member `channel`. For a progress bar, you must ensure that every dialog has its own channel. So, e.g. in the startup of the dialog you can set something like `in.channel
<br><br>
` in.channel = "/realtime/" + java.util.UUID.randomUUID().toString();`.
Now, to send an update to the progress bar use the PrimePush API, e.g. 'PushContextFactory.getDefault().getPushContext().push(in.channel,
<br><br>
` PushContextFactory.getDefault().getPushContext().push(in.channel, "{ 'progress' : 10, 'msg' : 'Extract data'}");'.data'}");`.
![real time progress bar][5]
Please try as well the [example project][6].
<br>
<br>
Note: This question and answer was [originally posted][7] by Heinrich Spreiter on his [Xpert.ivy Hacker blog][8]. Henry, many thanks to you for your enthusiastic work.
[1]: http://www.primefaces.org/showcase/push/index.jsf
[2]: http://www.primefaces.org/showcase/ui/progressBar.jsf
[3]: http://www.primefaces.org/showcase/ui/blockUI.jsf
[4]: http://answers.xpertivy.ch/questions/10/can-i-use-primepush-in-xpert-ivy
[5]: /upfiles/realtimeprogressbar.png
[6]: http://xpert-ivy-hacker-source-code.googlecode.com/svn/trunk/PrimePush
[7]: http://blog.xpertivyhacker.ch/2012/11/xpertivy-code-rezept-realtime-progressbar.html
[8]: http://blog.xpertivyhacker.ch/