This forum topic motivated me to develop a PrimeFaces 5.0 mobile xhtml page for the existing HTML_BASIC page in my app that displays charts.
Below, is the PrimeFaces 5.0 mobile xhtml pages. When the page is first rendered in the browser, it shows multiple charts.
main charts page
Code: Select all
<?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:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:pm="http://primefaces.org/mobile"
xmlns:pt="http://xmlns.jcp.org/jsf/passthrough"
xmlns:o="http://omnifaces.org/ui"
xmlns:of="http://omnifaces.org/functions">
<ui:composition>
<pm:page id="mainViewCharts">
<pm:header title="CHARTS">
<h:form id="viewChartsHeaderForm">
<ui:include src="/menuBtnForMobile.xhtml"/>
<p:commandButton styleClass="ui-btn-right ui-btn-inline"
icon="ui-btn ui-icon-forward"
value="Logout"
action="#{pf_usersController.logout(true)}"
ajax="false" immediate="true"
onclick="displayLoadingImage(true);"/>
</h:form>
</pm:header>
<pm:content>
<h:form id="viewChartsForm" >
<p:growl id="formMessages" life="30000"
showDetail="true" showSummary="true"
globalOnly="false" escape="false"/>
<p:commandButton icon="ui-icon-bullets"
value="Chart options"
action="pm:viewChartOptionsPage"
ajax="false" immediate="true"
onclick="displayLoadingImage(true);"/>
<h:outputText value="#{pf_ordersController.selectedPieChart}"
style="font-weight: bolder;"/>
<ul data-role="listview" data-inset="true">
<li data-role="list-divider">Pie Chart</li>
<li>
<p:pieChart value="#{orderChartBean.pieChartModel}"
fill="false" legendPosition="sw"
showDataLabels="true" sliceMargin="5" diameter="150"/>
</li>
<li data-role="list-divider">Bar Chart</li>
<li>
<p:barChart value="#{orderChartBean.cartesianChartModel}"
legendPosition="sw"
datatipFormat="#{orderChartBean.datatipFormat}"/>
</li>
<li data-role="list-divider">Line Chart</li>
<li>
<p:lineChart value="#{orderChartBean.cartesianChartModel}"
legendPosition="sw"
datatipFormat="#{orderChartBean.datatipFormat}"/>
</li>
</ul>
</h:form>
</pm:content>
<ui:include src="/menuForMobile.xhtml"/>
</pm:page>
<ui:include src="/orders/pf_ViewChartOptionsForMobile.xhtml"/>
</ui:composition>
</html>
chart options page
Code: Select all
<?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:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:pm="http://primefaces.org/mobile"
xmlns:pt="http://xmlns.jcp.org/jsf/passthrough"
xmlns:o="http://omnifaces.org/ui"
xmlns:of="http://omnifaces.org/functions">
<ui:composition>
<pm:page id="viewChartOptionsPage">
<pm:header title="CHART OPTIONS">
<h:form id="viewChartOptionsHeaderForm">
<p:commandButton styleClass="ui-btn-left ui-btn-inline"
icon="ui-icon-back"
value="Return"
action="pm:mainViewCharts"
ajax="false" immediate="true"
onclick="displayLoadingImage(true);"/>
<p:commandButton styleClass="ui-btn-right ui-btn-inline"
icon="ui-btn ui-icon-forward"
value="Logout"
action="#{pf_usersController.logout(true)}"
ajax="false" immediate="true"
onclick="displayLoadingImage(true);"/>
</h:form>
</pm:header>
<pm:content>
<h:form id="chartOptionsForm" >
<p:growl id="chartOptionsFormMessages" life="30000"
showDetail="true" showSummary="true"
globalOnly="false" escape="false"/>
<h:panelGroup layout="block"
rendered="#{!orderChartBean.isSelectedPieChart('Confirmed Trips: Total Revenue Per Year')}">
<pm:field>
<p:outputLabel value="Year:" for="filterYear"/>
<p:selectOneMenu id="filterYear" label="Year"
value="#{pf_ordersController.filterYear}">
<f:selectItems value="#{pf_ordersController.allYears}"/>
</p:selectOneMenu>
</pm:field>
</h:panelGroup>
<h:panelGroup layout="block"
rendered="#{orderChartBean.isSelectedPieChart('Confirmed Trips: Total Revenue Per Year')}">
<pm:field>
<p:outputLabel value="Year (FROM):" for="filterYear1"/>
<p:selectOneMenu id="filterYear1" label="Year (FROM)"
value="#{pf_ordersController.filterYear}">
<f:selectItems value="#{pf_ordersController.allYears}"/>
</p:selectOneMenu>
</pm:field>
<pm:field>
<p:outputLabel value="Year (TO):" for="filterYear2"/>
<p:selectOneMenu id="filterYear2" label="Year (TO)"
value="#{pf_ordersController.filterYear2}">
<f:selectItems value="#{pf_ordersController.allYears}"/>
</p:selectOneMenu>
</pm:field>
</h:panelGroup>
<p:menu id="viewChartOptionsMenu">
<p:menuitem value="Submit" icon="ui-icon-refresh" ajax="false"
onclick="displayLoadingImage(true)"
action="#{pf_ordersController.updateViewCharts()}"/>
<p:submenu label="Available Charts">
<p:menuitem value="Total Revenue"
ajax="false"
onclick="displayLoadingImage(true)"
action="#{pf_ordersController.prepareViewCharts('Confirmed Trips: Total Revenue')}"/>
<p:menuitem value="Total Revenue Per Driver"
ajax="false"
onclick="displayLoadingImage(true)"
action="#{pf_ordersController.prepareViewCharts('Confirmed Trips: Total Revenue Per Driver')}"/>
<p:menuitem value="Total Revenue Per Service"
ajax="false"
onclick="displayLoadingImage(true)"
action="#{pf_ordersController.prepareViewCharts('Confirmed Trips: Total Revenue Per Service')}"/>
<p:menuitem value="Total Revenue Per Year"
ajax="false"
onclick="displayLoadingImage(true)"
action="#{pf_ordersController.prepareViewCharts('Confirmed Trips: Total Revenue Per Year')}"/>
<p:menuitem value="Total Trips Per Driver"
ajax="false"
onclick="displayLoadingImage(true)"
action="#{pf_ordersController.prepareViewCharts('Confirmed Trips: Total Trips Per Driver')}"/>
<p:menuitem value="Confirmed Trips/Miles" ajax="false"
rendered="false"
onclick="displayLoadingImage(true)"
action="#{pf_ordersController.prepareViewCharts('Confirmed Trips: Miles')}"/>
</p:submenu>
</p:menu>
</h:form>
</pm:content>
</pm:page>
</ui:composition>
</html>
the error below occurs when I click 'Chart options' command button, which changes from main page to chart options page.
Code: Select all
Sep 02, 2014 3:18:59 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [Faces Servlet] in context with path [/mcmsweb] threw exception [null] with root cause
java.lang.NullPointerException
at org.primefaces.component.chart.pie.PieChartRenderer.encodeData(PieChartRenderer.java:68)
at org.primefaces.component.chart.pie.PieChartRenderer.encodeScript(PieChartRenderer.java:51)
at org.primefaces.component.chart.pie.PieChartRenderer.encodeEnd(PieChartRenderer.java:36)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:674)
at org.primefaces.renderkit.CoreRenderer.renderChild(CoreRenderer.java:85)
at org.primefaces.renderkit.CoreRenderer.renderChildren(CoreRenderer.java:68)
at org.primefaces.renderkit.CoreRenderer.renderChild(CoreRenderer.java:83)
at org.primefaces.renderkit.CoreRenderer.renderChildren(CoreRenderer.java:68)
at org.primefaces.renderkit.CoreRenderer.renderChild(CoreRenderer.java:83)
at org.primefaces.renderkit.CoreRenderer.renderChildren(CoreRenderer.java:68)
at org.primefaces.mobile.component.page.PageRenderer.encodeContent(PageRenderer.java:71)
at org.primefaces.mobile.component.page.PageRenderer.encodeEnd(PageRenderer.java:41)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:674)
at javax.faces.component.UIComponentBase.encodeAll(UIComponentBase.java:554)
at javax.faces.component.UIComponentBase.encodeAll(UIComponentBase.java:550)
at javax.faces.component.UIComponentBase.encodeAll(UIComponentBase.java:550)
at org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage.renderView(FaceletViewDeclarationLanguage.java:1891)
at org.apache.myfaces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:313)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:58)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:58)
at org.apache.myfaces.lifecycle.RenderResponseExecutor.execute(RenderResponseExecutor.java:116)
at org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:267)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:200)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:98)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.omnifaces.filter.GzipResponseFilter.doFilter(GzipResponseFilter.java:149)
at org.omnifaces.filter.HttpFilter.doFilter(HttpFilter.java:77)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at pf.LoginFilter.doFilter(LoginFilter.java:247)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.tomee.catalina.OpenEJBValve.invoke(OpenEJBValve.java:44)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1736)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1695)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
so, how would I fix (or 'avoid') this error? by doing something I did for another mobile xhtml page that I developed a few days ago. I will redesign this page to a single page instead of multiple page by using a bean attribute and ui:include.
remove the 2nd page (chart options page) from the same xhtml file that contains the main pm:page
Code: Select all
<ui:include src="/orders/pf_ViewChartOptionsForMobile.xhtml"/>
add bean attribute and methods that will be used by Chart options command button and Return button
Code: Select all
private Boolean viewChartOptions;
// initialized in PostConstruct
viewChartOptions = false;
public Boolean getViewChartOptions() {
return viewChartOptions;
}
public String prepareViewChartOptionsForMobile() {
viewChartOptions = true;
return "pm:viewChartOptionsPage";
}
public String returnFromViewChartOptionsForMobile() {
viewChartOptions = false;
/* to avoid the exception, below, that occurs when click Return button (F5 key in HTML_BASIC, too)
java.lang.NullPointerException
at org.primefaces.component.chart.pie.PieChartRenderer.encodeData(PieChartRenderer.java:68)
at org.primefaces.component.chart.pie.PieChartRenderer.encodeScript(PieChartRenderer.java:51)
at org.primefaces.component.chart.pie.PieChartRenderer.encodeEnd(PieChartRenderer.java:36)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:674)
at org.primefaces.renderkit.CoreRenderer.renderChild(CoreRenderer.java:85)
...
*/
orderChartBean.initPieChartModel(filterYear, filterYear2);
return "pm:mainViewCharts";
}
* the code above really has the fix for the exception *
Chart options command button (on main page): reference bean method
Code: Select all
<p:commandButton icon="ui-icon-bullets"
value="Chart options"
action="#{pf_ordersController.prepareViewChartOptionsForMobile()}"
ajax="false" immediate="true"
onclick="displayLoadingImage(true);"/>
Return button (on chart options page): reference bean method
Code: Select all
<p:commandButton styleClass="ui-btn-left ui-btn-inline"
icon="ui-icon-back"
value="Return"
action="#{pf_ordersController.returnFromViewChartOptionsForMobile()}"
ajax="false" immediate="true"
onclick="displayLoadingImage(true);"/>
and i have the following ui:include, which
conditionally references the non-mobile charts page, mobile charts options page, or mobile charts main page.
Code: Select all
<ui:include src="#{pf_usersController.primeFacesMobile ? (pf_ordersController.viewChartOptions ? '/orders/pf_ViewChartOptionsForMobile.xhtml' :'/orders/pf_ViewChartsForMobile.xhtml') : '/orders/pf_ViewChartsForNonMobile.xhtml'}"/>