You can achieve this with a combination of PrimePush and p:progressBar. You can use p:blockUI in addition to block the UI. See this entry in the Q&A 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 = "/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, "{ 'progress' : 10, 'msg' : 'Extract data'}");
.
Please try as well the example project.
Note: This question and answer was originally posted by Heinrich Spreiter on his Xpert.ivy Hacker blog. Henry, many thanks to you for your enthusiastic work.
answered
07.10.2013 at 17:21
SupportIvyTeam ♦♦
1.4k●102●118●122
accept rate:
77%