Question :
I’m developing a web page with canvas in HTML 5, it will be displayed in dashboards in real time, so I use ManagedBean to return their values, I have a component developed in JavaScript
with its variable declared as global, and every 3 seconds should be updated its values through pool
of the Primefaces, however this does not happen, the code is executed once only after rendering the page, as can be seen below in the generated code:
<script id="j_idt2:j_idt3_s" type="text/javascript">
$(function() {
PrimeFaces.cw("Poll", "widget_j_idt2_j_idt3", {
id: "j_idt2:j_idt3",
widgetVar: "widget_j_idt2_j_idt3",
frequency: 2,
autoStart: true,
fn: function() {
PrimeFaces.ab({
s: 'j_idt2:j_idt3',
f: 'j_idt2',
u: 'j_idt2',
d: 3,
onco: function(xhr, status, args) {
radial1.setValueAnimated(36.16220080628247);
}
});
}
});
});
</script>
How do I set the value of my object by calling a JavaScript method with a time interval in JavaScript by calling a ManageBean method?
<body onload="init()">
<h:outputScript library="primefaces" name="jquery/jquery.js" />
<h:form>
<p:poll oncomplete = "radial1.setValueAnimated(#{mBeanTesteIsolado.teste})" listener="#{mBeanTesteIsolado.teste}"
autoStart = "true"
delay = "3"
update = "@form"
/>
<table>
<tr>
<td width="100%">
<canvas id="canvasRadial1" width="200" height="200">
No canvas in your browser...sorry...
</canvas>
</td>
</tr>
</table>
</h:form>
</body>
<script type="text/javascript">
var radial1;
function init()
{
// Define some sections
var sections = Array(steelseries.Section(0, 25, 'rgba(0, 0, 220, 0.3)'),
steelseries.Section(25, 50, 'rgba(0, 220, 0, 0.3)'),
steelseries.Section(50, 75, 'rgba(220, 220, 0, 0.3)'));
// Define one area
var areas = Array(steelseries.Section(75, 100, 'rgba(220, 0, 0, 0.3)'));
// Initialzing gauge
radial1 = new steelseries.Radial('canvasRadial1', {
gaugeType: steelseries.GaugeType.TYPE1,
section: sections,
area: areas,
titleString: 'Title',
unitString: 'Unit',
threshold: 50,
lcdVisible: true
});
// O método abaixo deve ser executado eternamente, como sugerido usando pool, mas o fato de estar em uma função JavaScript
// aparentemente não é possível
gauge.setValueAnimated(#{mBeanTesteIsolado.teste});
}
</script>
Answer :
The solution was:
Use p:poll
of primefaces or a p:remoteCommand
to invoke a action
of Backing Bean.
<p:poll autoStart="true" listener="#{mBeanTesteIsolado.teste}"
oncomplete="handleComplete(xhr, status, args)" interval="3" />
Or with p:remoteCommand
:
<p:remoteCommand name="atualizarUI" actionListener="#{mBeanTesteIsolado.teste}" oncomplete="handleComplete(xhr, status, args)" />
In the case of p:remoteCommand
, using a setInterval to call at regular intervals:
setInterval(function() { atualizarUI(); }, 3000);
Given the function assigned to oncomplete
, in relation to your signature, you should accept 3 arguments ( xhr, status, args
)
In the Backing Bean, use RequestContext.addCallbackParam
to return data to the JavaScript function used in oncomplete
, both p:poll
and p:remoteCommand
.
Setting the return of the Backing Bean to the Javascript function:
Managed Bean
public void teste() {
// Processamento necessário
RequestContext context = RequestContext.getInstance();
// Adiciona as variáveis para o JS (variável args da assinatura)
context.addCallbackParam("nomeDoAtributo", "valor");
}
Addressing the return in JavaScript:
JS
function handleComplete(xhr, status, args) {
var nomeDoAtributo = args.nomeDoAtributo;
// Atualizar UI
gauge.setValueAnimated(nomeDoAtributo);
}