Reputation: 772
I use a JSF 2.2, a Primefaces 6.0 and a CDI. One of my page includes a script which has got two javascript functions (one of them create a chart, second of them supply new data to the chart) and a simple form which works as a filter. I've cut my code (look at below) to show you the most important part of my code.
I would like to achieve something like this:
How you see, the above mechanism is based on passing some values from the CDI bean to the javascript by means of the RequestContext
. To achieve this I based on the primefaces documentation (chapter 11.1). So far, I've:
init()
method (which has the @PostConstruct
annotation) of the CDI bean;oncomplete
attribute to the <p:commandButton>
component which calls second of the function with args
parameter. The values which I want to pass to the second function are prepared in actionFilterButton()
method which I call in action
attribute of the button.At the moment my page works like this:
How you see, the problem is the first stage. The first javascript function isn't executed when I open my page.
How can I call the first javascript function?
What did I try?
requestContext.execute("firstFunction(args)");
in the init()
method in hope it'll be worked but it isn't work and it breaks my form when I use the form. I'm not sure if I can put args
as I did it on the server side (indeed I'm not sure if it is interpreted correctly). firstFunction()
at the end of my script (how you see below), but it isn't work as well.My xhtml page:
<!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:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:pt="http://xmlns.jcp.org/jsf/passthrough"
xmlns:pe="http://primefaces.org/ui/extensions">
<h:head>
<!-- loading css -->
</h:head>
<h:body>
<div id="container" style="height: 750px; width: 100%; margin: 0 auto;"/>
<script type="text/javascript">
//<![CDATA[
//Declaration of variables
var chart;
var data1;
var data2;
var data3;
function firstFunction(args) {
$(function() {
data1 = JSON.parse(args.data1);
data2 = JSON.parse(args.data2);
data3 = JSON.parse(args.data3);
//Other operations
});
}
function secondFunction(args) {
$(function() {
data1 = JSON.parse(args.data1);
data2 = JSON.parse(args.data2);
data3 = JSON.parse(args.data3);
//Other different operations
});
}
firstFunction(args);
//]]>
</script>
<br/>
<h:form id="filterForm">
<p:selectManyCheckbox id="filter" value="#{chart2Controller.selectedKindOfNetwork}" layout="responsive" columns="4">
<p:ajax update="filterButton" />
<f:selectItems value="#{chart2Controller.kindOfNetwork}" var="kindOfNetwork" itemLabel="#{kindOfNetwork}" itemValue="#{kindOfNetwork}" />
</p:selectManyCheckbox>
<br/>
<p:commandButton id="filterButton" value="Filter" action="#{chart2Controller.actionFilterButton()}"
disabled="#{!chart2Controller.visibilityFilterButton}"
update="filterForm"
oncomplete="secondFunction(args);"/>
</h:form>
</h:body>
</html>
Part of my CDI bean:
@Named
@ViewScoped
public class Chart2Controller implements Serializable {
/**
* Start method.
*/
@PostConstruct
public void init() {
initData();
//This isn't work.
//requestContext.execute("firstFunction(args)");
}
/**
* Downloading the data from the database.
*/
private void initData(){
/*
* Sending the query to the database including the filter options of the form,
* saving the result and preparing the data basing on the result.
*/
//Preparing the callback parameters.
requestContext = RequestContext.getCurrentInstance();
requestContext.addCallbackParam("data1", data1);
requestContext.addCallbackParam("data2", data2);
requestContext.addCallbackParam("data3", data3);
}
/**
* Action for the filter button.
*/
public void actionFilterButton(){
initData();
}
/**
* Visibility for filter button.
*/
public boolean getVisibilityFilterButton(){
//return true or false.
}
//Getter and Setter
private static final long serialVersionUID = -8128862377479499815L;
@Inject
private VisualizationService visualizationService;
private RequestContext requestContext;
private List<ChartModel2> data;
private List<String> kindOfNetwork;
private List<String> selectedKindOfNetwork;
private String data1;
private String data2;
private String data3;
}
Upvotes: 1
Views: 4128
Reputation: 772
I've just found the soultion. Indeed two solutions: on the server side (which I recommend) and on the client side. My problem was this javascript line: firstFunction(args);
. The args
parameter wasn't properly interpreted.
First of all I've changed the parameters of my javascript functions. Instead of args
parameter I've used three parameters (one for each variable). At the moment, the script should look like this:
<script type="text/javascript">
//<![CDATA[
//Declaration of variables
var chart;
var data1;
var data2;
var data3;
function firstFunction(data1p, data2p, data3p) {
$(function() {
data1 = JSON.parse(data1p);
data2 = JSON.parse(data2p);
data3 = JSON.parse(data3p);
//Other operations
});
}
function secondFunction(data1p, data2p, data3p) {
$(function() {
data1 = JSON.parse(data1p);
data2 = JSON.parse(data2p);
data3 = JSON.parse(data3p);
//Other different operations
});
}
//]]>
</script>
I've changed the value of the oncomplete
attribute of the <p:commandButton>
as well: oncomplete="createChart(args.data1, args.data2, args.data3);"/>
.
Note that, if you want, you can keep the old version of the second javascript function (with one args
parameter) and keep the old version of the oncomplete
attribute. The most imporatant is the first javascript function which will be called on the server side.
Finally, I've called requestcontext.execute()
method in the init()
method of the CDI bean, so I'm sure that the data which will be downloaded are ready.
/**
* Start method.
*/
@PostConstruct
public void init() {
initData();
requestContext.execute(String.format("createChart('%s', '%s', '%s')", getProtos(),getData(),getColors()));
}
The execute
method calls the first javascript method and passes the three required values.
Note that, I've used ''
characters to achieve the correct representation on the javascript side.
In this case, I've change only first javascript function. Instead of the args
parameter, I've used three parameters (one for each varables) such as in the previous example. I've kept the second function with the args
parameter, but if you want, you can change this in the same way like in the previous example.
Finally, I've called the first function at the end of the script. Look at the code below. I've used the EL to pass the values from the CDI bean. I've also deleted JSON.parse()
method because the ELs were written directly into the javascript code and the browser correctly interpreted the data in my case.
<script type="text/javascript">
//<![CDATA[
//Declaration of variables
var chart;
var data1;
var data2;
var data3;
function firstFunction(data1p, data2p, data3p) {
$(function() {
data1 = data1p;
data2 = data2p;
data3 = data3p;
//Other operations
});
}
function secondFunction(args) {
$(function() {
data1 = JSON.parse(args.data1);
data2 = JSON.parse(args.data2);
data3 = JSON.parse(args.data3);
//Other different operations
});
}
firstFunction(#{chart2Controller.data1}, #{chart2Controller.data2}, #{chart2Controller.data3});
//]]>
</script>
Upvotes: 0
Reputation: 169
I believe wrapping it as a IIFE would do the trick. if you're loading too quickly and need the dom, try something like on load
.
(function firstFunction(args) {
$(function() {
data1 = JSON.parse(args.data1);
data2 = JSON.parse(args.data2);
data3 = JSON.parse(args.data3);
//Other operations
});
})();
Upvotes: 1