JSF2, PrimeFaces, and Highcharts - Ajax - jsf-2

Has anybody used JSF2, PrimeFaces, and Highcharts together?
I am really confused on how I should put all these together, specially regarding the ajax request to get the data from the server to feed into Highcharts on the view to update the chart.
What I have right now is a servlet that handles the Ajax request, which is sent using JQuery.ajax() method and use JQuery to update the chart with the new data received as JSON object. And I am using GSon.toJSon to convert Java object into JSON object.
What I am trying to achieve here is that I want to replace that servlet with the JSF2. Instead of using a different servlet, I want to use JSF and have some backing bean to prepare and send the JSON object to the client.
Anybody?

In the example below the the p:commandButton starts the ajax request. The JSON object you want to use can be stored in the h:inputHidden field. When the p:commandButton completes the javascript function is called to update the chart. The javascript function will be able to access the JSON object from the h:inputHidden field.
xhtml
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.prime.com.tr/ui">
<h:head>
<script type="text/javascript">
function dosomething() {
var value = jQuery("#beanvalue").attr('value');
alert(value);
}
</script>
</h:head>
<h:body>
<h:form prependId="false" >
<p:commandButton value="update" action="#{testBean.update}" update="beanvalue" oncomplete="dosomething();" />
<h:inputHidden value="#{testBean.output}" id="beanvalue" />
</h:form>
</h:body>
</html>
Bean
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#ManagedBean
#ViewScoped
public class TestBean {
private String output;
public TestBean() {
output = "1";
}
public void update() {
output += "1";
}
public String getOutput() {
return output;
}
public void setOutput(String output) {
this.output = output;
}
}

Related

JSF updating h:graphicImage

I'm using poll from primefaces to update an image every n seconds. I'm flipping between two images right now just to make sure it's working. Now what I'm trying to do is display images that aren't stored on the server. I wrote a class that snaps a photo every n seconds. I don't want to save it to disk to reduce IO. So I'd like to do something like the following flow
#ManagedBean
#ViewScoped
public class myClass implements Serializable {
public Object getImage() {
Object newImage = MyClass.takePhoto();
return newImage;
}
public void increment() {
}
}
XHTML:
<?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:head></h:head>
<h:body>
<h:form>
<h:graphicImage value="#{myClass.image}" id="img" cache="false"/>
<p:poll interval="1" listener="#{myClass.increment}" update="img" />
</h:form>
</h:body>
</h:html>
So my question is, is it possible to return an Image object to h:graphicImage in a similar way to the pseudo-code above?
Yes, try using the Primefaces StreamedContent class to provide a stream to graphicImage, rather than an object.
Something like:
public StreamedContent getImageStream() {
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(myBufferedImage, "png", os);
InputStream is = new ByteArrayInputStream(os.toByteArray());
return new DefaultStreamedContent(is, "image/png");
}
Then in your JSF page:
<p:graphicImage value="#{myController.imageStream}" cache="false"/>
Note that this uses p:graphicImage, rather than h:graphicImage.

Unable to access GET parameters in JSF backing bean

I am unable to access GET parameters in a backing bean. The example.xhtml file:
<!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://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<f:metadata>
<f:viewParam name="id" value="#{myBackingBean.unitId}" />
<f:viewAction action="#{myBackingBean.findUnits}" />
</f:metadata>
<head>
<title>Example Title</title>
</head>
<body>
I found #{myBackingBean.units.size()} units.
</body>
</html>
My understanding is that when I GET example.jsf?id=3 then JSF calls myBackingBean.setUnitId(3). Correct?
Here is MyBackingBean:
#Model
public class MyBackingBean {
private static Logger logger = Logger.getLogger(MyBackingBean.class
.getName());
//#ManagedProperty("#{param.id}")
private Long unitId;
#Inject
private IExampleEJB myExampleEjb;
private List<Unit> units;
#PostConstruct
public void postConstruct() {
Map<String, String> mymap = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
for (String k:mymap.keySet()) {
logger.info(String.format("%s %s", k,mymap.get(k)));
}
}
public void findUnits() {
logger.info(String.format("MyBackingBean findUnits %d", unitId));
units = myExampleEjb.findUnits();
}
public List<Unit> getUnits() {
return units;
}
public void setUnits(List<Unit> units) {
this.units = units;
}
public Long getUnitId() {
return unitId;
}
public void setUnitId(Long unitId) {
this.unitId = unitId;
}
}
The id parameter is in the parameter request map in postConstruct().
In my case, setUnitId() is never called, nor is findUnits().
In a different but related question, the #ManagedProperty (currently commented out) does not work either.
Given the xmlns.jcp.org namespace, you're using JSF 2.2. The early Mojarra 2.2.0 and 2.2.1 versions have a known bug which causes the <f:viewParam> to not work.
As per the comments you're using GlassFish 4.0. If you didn't upgrade its bundled JSF implementation and thus are using the early Mojarra version 2.2.0, then you're definitely facing this bug and you need to upgrade.
You can get the JAR from http://javaserverfaces.java.net. All you need to do is to replace javax.faces.jar file in GlassFish's /modules folder with the newer version.
See also
f:viewParam doesn't pass required parameter when new xmlns.jcp.org namespace is used

Making valueChangeListener on h:inputHidden fire a ManagedBean method

My JavaScript:
function setJson(value) {
document.getElementById("json").value = value;
}
My XHTML:
<h:inputHidden id="json" value="#{indexManaged.json}" valueChangeListener="#{indexManaged.goTo('datatable')}" />
My ManagedBean:
#ManagedBean
#ViewScoped
public class IndexManaged implements Serializable {
private String json;
public String getJson() { return json; }
public void setJson(String json) { this.json = json; }
public String goTo(String page) {
Flash flash = FacesContext.getCurrentInstance().getExternalContext().getFlash();
flash.put("json", json);
return page + "?faces-redirect=true";
}
}
The scenario:
I have a Java Applet that fires the function setJson(value). But when the applet sets a new value to my inputHidden, isn't the valueChangeListener suposed to fire my ManagedBean method? What am I doing wrong?
The valueChangeListener isn't a client side listener. It's a server side listener which runs when the form is submitted. So, you need to submit the form as well.
Wrap it in a form
<h:form id="form">
and submit it as follows
document.getElementById("form").submit();
Don't forget to fix the client ID of the hidden input accordingly:
document.getElementById("form:json").value = value;
See also:
When to use valueChangeListener or f:ajax listener?
Unrelated to the concrete problem, there are cleaner ways to achieve this. Have a look at PrimeFaces <p:remoteCommand> and OmniFaces <o:commandScript>.
Not sure about the <h:inputHidden
But you can use the following thing:
<h:inputText id="json" value="#{indexManaged.json}" style="display:none">
<f:ajax listener="#{myBean.myListener}"/>
</h:inputText>
and trigger it with jquery like this:
$("#json").change();// instead of `json` you might be needed to provide
//full id like this, $("#myform\\:json").change()

JSF2.0 backing bean setter not invoked when using dataTable

I have a screen in which am using
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:body>
<h:form>
<f:event listener="#{pageload.getPageLoad}" type="preRenderView" />
<h:dataTable value="#{pageload.fieldConfig}" var="field"
columnClasses="lblFirstCol,lblSecondCol,lblThirdCol,lblFourthCol" id="table1" styleClass="tblSecond" >
<h:column >
<h:outputText value="#{field.label_name}" />
</h:column>
<h:column>
<h:inputText value="#{searchdevice.device.terminal_name}" />
</h:column>
</h:dataTable>
<h:commandButton value="Submit" action="#{searchdevice.searchButtonAction}"/>
</h:form>
</h:body>
And my backing bean
#ManagedBean(name="pageload")
#RequestScoped
public class PageLoadBean {
private List<FieldConfigVO> fieldconfig;
//getters and setters
// method to populate the ArrayList
public void getPageLoad(){
//getting populated from Database
fieldconfig = common.getFieldConfig("001");
}
}
The other input bean
#ManagedBean(name="searchdevice")
#RequestScoped
public class SearchDeviceBean {
private DeviceVO device;
public SearchDeviceBean() {
device = new DeviceVO();
}
public DeviceVO getDevice() {
return device;
}
public void setDevice(DeviceVO device) {
this.device = device;
}
public String searchButtonAction(){
System.out.println(device.getTerminal_name()+"****TERMINAL NAME******");
FacesContext context = FacesContext.getCurrentInstance();
if (context.getMessageList().size() > 0) {
return(null);
}else {
return("success");
}
}
}
My Device Object has the terminal_name property.I have a command button which invokes method in SearchDeviceBean and on submitting the form whatever value I enter doesn't get populated
Any help appreciated
You're performing data initialization logic in preRenderView event. This is the wrong place for code which needs to prepare the model for the postback. When JSF needs to update the model values during form submit, it is encountering a completely empty fieldConfig and therefore JSF can't set the submitted/converted/validated values in there. The fieldConfig is in your case only prepared during a later phase, the render response phase, which is thus too late.
You need to initialize it in #PostConstruct instead. It's invoked immediately after bean's construction and dependency in jection. Get rid of the whole <f:event> altogether and put a #PostConstruct annotation on the getPageLoad() method. I'd by the way also rename that method to init() or loadFieldConfig() as it isn't a getter method at all and therefore a very confusing name to other people reading/maintaining your code.
See also:
When to use f:viewAction / preRenderView versus PostConstruct?

Question about Struts2 return type

I have the following scenario:
Struts.xml
<action name="user_initNews" method="initNews" class="it.sba.bcc.sbarima.user.web.action.UserAction">
<result type="dispatcher">
<param name="location">pages/elementicomuni/elencoNews.jsp</param>
</result>
</action>
User Action
public class UserAction extends BaseAction
{
private NewsService newsService = null;
private User utente;
private List<News> news;
public String initNews()
{
return SUCCESS;
}
public void elencoNews()
{
try
{
newsService = UserServiceFactory.getNewsService();
this.news = newsService.getNews(getAbiUserProfile(), getMatricolaUserProfile());
}
catch (ServiceException e)
{
e.printStackTrace();
}
}
public List<News> getNews()
{
return news;
}
}
elencoNews.jsp
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<?xml version="1.0" encoding="utf-8"?>
<%# taglib uri="/struts-tags" prefix="s" %>
<html>
<body>
<s:action name="user_elencoNews!elencoNews"></s:action>
<s:iterator value="news" var="n">
<label><s:property value="descrizione"/></label>
</s:iterator>
</body>
</html>
Whene the elencoNews.jsp is rendered, I would like to call from the JSP page an action thath return a set of POJO to iterate.
The elencoNews.action is correctly called, but I do not know how to treat data on the elencoNews.jap
How can I do that?
I'm afraid you are misunderstanding the whole Struts2 typical workflow. You dont (typically) want to call another action from the JSP, in the typical workflow the JSP renders after your action has processed your request, and it just displays data (typically from your Action instance, which is found in the value stack).
Eg read here
In your example, you'd should code in your JPS:
<s:iterator value="news" var="n">
<s:property value="descrizione"/>
</s:iterator>
If you have this concepts clear (and you have coded the most basic-typical struts2 cases), the disregard this and be more explicit about what are you trying to accomplish - why you have two actions involved for a single request and jsp.
If you want a dynamic jsp page, you can look into using the Struts2-jQuery plugin which will allow you to call another action in your JSP and load the results. See examples at http://www.weinfreund.de/struts2-jquery-showcase/index.action under Ajax Link or Ajax Div sections.

Resources