How to use RequestContext in primefaces? - jsf-2

I'm new to primefaces. I trying some examples in primeface showcase
But;
After saveUser, on ajax method handleComplete(xhr, status, args) args don't have arguments that added in saveUser method.
EDIT : I just added #ManagedBean annotations because i'm using jsf 2.0
EDIT-2
in my pom;
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>2.2</version>
</dependency>
in my web.xml
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
in my .xhtml page
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.prime.com.tr/ui">
<h:head>
<script type="text/javascript">
function handleComplete(xhr, status, args) {
if(args.validationFailed) {
alert("Validation Failed");
} else {
alert("Save:" + args.saved);
alert("FirstName: " + args.user.firstname + ", Lastname: " + args.user.lastname);
}
}
</script>
</h:head>
<h:body>
<h:form>
<p:panel id="panel" header="New User">
<h:panelGrid columns="2">
<h:outputLabel for="firstname" value="Firstname: *" />
<p:inputText id="firstname" value="#{user.firstName}" required="true"/>
<h:outputLabel for="surname" value="Lastname: *" />
<p:inputText id="surname" value="#{user.surName}" required="true"/>
</h:panelGrid>
</p:panel>
<p:commandButton value="Save" actionListener="#{user.saveUser}" oncomplete="handleComplete(xhr, status, args)" />
</h:form>
</h:body>
</html>
in my bean;
#ManagedBean(name = "user")
public class User {
private String firstName = "";
private String surName = "";
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getFirstName() {
return firstName;
}
public void setSurName(String surName) {
this.surName = surName;
}
public String getSurName() {
return surName;
}
public void saveUser(ActionEvent actionEvent) {
// save user
RequestContext context = RequestContext.getCurrentInstance();
context.addCallbackParam("saved", true);
context.addCallbackParam("user", this);
}
}
EDIT -3
I can catch properties that carried with data in ajax response with this.PrimeFaces.ajax.RequestManager.requests[0].data it carries that data ;
"j_id2059540600_7ac21836=j_id2059540600_7ac21836&j_id2059540600_7ac21836%3Afirstname=qweq&j_id2059540600_7ac21836%3Asurname=asda&javax.faces.ViewState=8900392402396831372%3A-8139730777939772917&javax.faces.partial.ajax=true&javax.faces.source=j_id2059540600_7ac21836:j_id2059540600_7ac218a5&javax.faces.partial.execute=#all&j_id2059540600_7ac21836:j_id2059540600_7ac218a5=j_id2059540600_7ac21836:j_id2059540600_7ac218a5"
But i'm pretty sure there is another option. Just can't seet it.
Thanks for any help.

Solved! It was about scope problem of a form that contains a commandButton. Command buttons (i think..didnt read a formal document about it.) that in a form has a scope of its own form. Cant reach/update/modify elements in an form.

Related

Primefaces Push notify example does not work with wildfly 9.0.2

I tried to do the notify example of primefaces push in wildfly 9.0.2 but does not work, I searched the error but the answers I've found not helped me, here is my code:
and thanks for the advice
index:
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<p:growl widgetVar="growl" showDetail="true" />
<h:form>
<h:panelGrid columns="2">
<p:outputLabel for="summary" value="Summary: " />
<p:inputText id="summary" value="#{notifyView.summary}" required="true" />
<p:outputLabel for="detail" value="Detail: " />
<p:inputText id="detail" value="#{notifyView.detail}" required="true" />
</h:panelGrid>
<p:commandButton value="Send" actionListener="#{notifyView.send}" />
</h:form>
<p:socket onMessage="handleMessage" channel="/notify" />
<script type="text/javascript">
function handleMessage(facesmessage) {
facesmessage.severity = 'info';
PF('growl').show([facesmessage]);
}
</script>
</h:body>
NotifyView.java:
public class NotifyView {
private final static String CHANNEL = "/notify";
private String summary;
private String detail;
public String getSummary() {
return summary;
}
public void setSummary(String summary) {
this.summary = summary;
}
public String getDetail() {
return detail;
}
public void setDetail(String detail) {
this.detail = detail;
}
public void send() {
EventBus eventBus = EventBusFactory.getDefault().eventBus();
eventBus.publish(CHANNEL, new FacesMessage(StringEscapeUtils.escapeHtml3(summary), StringEscapeUtils.escapeHtml3(detail)));
}}
NotifyResource.java:
#PushEndpoint("/notify")
public class NotifyResource {
#OnMessage(encoders = {JSONEncoder.class})
public FacesMessage onMessage(FacesMessage message) {
return message;
}
}
And finally web.xml:
<servlet>
<servlet-name>Push Servlet</servlet-name>
<servlet-class>org.primefaces.push.PushServlet</servlet-class>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>Push Servlet</servlet-name>
<url-pattern>/primepush/*</url-pattern>
</servlet-mapping>
I use Wildfly 9.0.2, Primefaces 5.2, commons-lang3-3.4
and try with atmosphere-runtime versions: 2.1.7, 2.4.0-RC6 and 2.4.5
The log error:
14:31:29,771 ERROR [io.undertow.request] (default task-24) UT005023: Exception handling request to /Primefaces2_1/primepush/notify: java.lang.NoSuchMethodError: org.atmosphere.cpr.AtmosphereServlet.configureFramework(Ljavax/servlet/ServletConfig;Z)Lorg/atmosphere/cpr/AtmosphereServlet;
at org.primefaces.push.PushServlet.configureFramework(PushServlet.java:67)
at org.primefaces.push.PushServlet.configureFramework(PushServlet.java:36)
at org.atmosphere.cpr.AtmosphereServlet.init(AtmosphereServlet.java:80)...
Finally I found a solution:
Using atmosphere-runtime-native and jboss-as-websockets libraries works.
thanks for help to Xtreme Biker

Getting null values from jsf inputText in Manage bean

I am facing weird issue in jsf inputText. On browser it is showing the manage bean name and the variable name in input box (i.e. #{loginModel.userName}). the following is my jsf page code
<body>
<f:view>
<h:form>
<h:outputLabel value="Username"></h:outputLabel>
<h:inputText value="#{loginModel.userName}"></h:inputText>
<h:outputLabel value="Password"></h:outputLabel>
<h:inputSecret value="#{loginModel.password}"></h:inputSecret>
<h:commandButton value="Submit" action="#{loginModel.process}" ></h:commandButton>
</h:form>
</f:view>
</body>
My manage bean code is
public class LoginModel {
private String userName;
private String password;
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String process(){
System.out.println("Logged in user id is "+this.getUserName()+" and password to access is "+this.getPassword());
return "Submit";
}
}
and my faces-config.xml file
<managed-bean>
<managed-bean-name>loginModel</managed-bean-name>
<managed-bean-class>net.varun.dto.LoginModel</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
and following is my output on browser as well as i am getting null when i click on submit button
try the following code:
Change your h:commandButton for the primefaces process, partialSubmit and ajax
<body>
<f:view>
<h:form>
<h:outputLabel value="Username"></h:outputLabel>
<h:inputText value="#{loginModel.userName}"></h:inputText>
<h:outputLabel value="Password"></h:outputLabel>
<h:inputSecret value="#{loginModel.password}"></h:inputSecret>
<p:commandButton value="Submit" action="#{loginModel.process}" process="#form" partialSubmit="true" ajax="true" />
</h:form>
</f:view>
</body>
So you can put a breakpoint in your process method for see the update values.

How to use j_security_check jsf

I want to use j_security_check authentication in order to validate the user credentials.
Basically what I am trying to achieve is when the user press submit then in case he is using wrong credentials then a message (p:growl) will show and if it’s successful then the dialog will closed.
There are many examples in the web but unfortunately I still can’t understand how to complete this puzzle :(
In my project I am using primefaces 4.0 & weblogic 10.3.2.0 (JAVA EE 5).
some code example:
<p:dialog id="dialog" widgetVar="dlg" resizable="false">
<h:form id="fLogin" prependId="false"
onsubmit="document.getElementById('fLogin').action = 'j_security_check';">
<h:panelGrid columns="2" cellpadding="5">
<h:outputLabel for="j_username" value="Username:" />
<p:inputText value="#{expBean.username}"
id="j_username" label="username"/>
<h:outputLabel for="j_password" value="Password:" />
<h:inputSecret value="#{expBean.password}"
id="j_password" label="password"/>
<p:commandButton id="submitButton"
value="Submit"
actionListener="#{expBean.run}" />
</h:panelGrid>
</h:form>
</p:dialog>
web.xml
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<security-constraint>
<web-resource-collection>
<web-resource-name>main</web-resource-name>
<description/>
<url-pattern>main.jsf</url-pattern>
<http-method>POST</http-method>
</web-resource-collection>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>my-realm</realm-name>
</login-config>
<security-role>
<description/>
<role-name>MyRole</role-name>
</security-role>
exeBean:
public void run() {
FacesContext facesContext = FacesContext.getCurrentInstance();
}
Any guidelines and useful example will be much appreciated
Thanks
You were submitting the form by PrimeFaces ajax. That's why it fails. The j_security_check handler doesn't understand incoming JSF/PrimeFaces-flavored ajax requests and can't handle them appropriately by returning the desired XML response. It has to be a regular (synchronous) submit.
Turn off the ajax thing:
<p:commandButton ... ajax="false" />
By the way, your form declaration is clumsy. Just use <form> instead of <h:form>.
<form id="fLogin" action="j_security_check">
after experimenting some strategy, i choose not to use j_security_check and implement auth this way:
#ManagedBean
#ViewScoped
public class AuthBean implements Serializable
{
private static final long serialVersionUID = 1L;
private static final Logger logger = LoggerFactory.getLogger(AuthBean.class);
#EJB
private PersistenceService service;
#ManagedProperty("#{user}")
private UserBean userBean;
private String email;
private String password;
private String originalURL;
#PostConstruct
public void init()
{
logger.debug("called");
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
originalURL = (String) externalContext.getRequestMap().get(RequestDispatcher.FORWARD_REQUEST_URI);
if(originalURL == null)
{
originalURL = externalContext.getRequestContextPath();
}
else
{
String originalQuery = (String) externalContext.getRequestMap().get(RequestDispatcher.FORWARD_QUERY_STRING);
if(originalQuery != null)
{
originalURL += "?" + originalQuery;
}
}
logger.debug("originalURL: {}", originalURL);
}
public void login() throws IOException
{
logger.debug("called");
logger.debug("originalURL: {}", originalURL);
FacesContext context = FacesContext.getCurrentInstance();
ExternalContext externalContext = context.getExternalContext();
HttpServletRequest request = (HttpServletRequest) externalContext.getRequest();
try
{
request.login(email, password);
}
catch(ServletException e)
{
JsfUtils.addErrorMessage(e, "authentication failed");
return;
}
Person person = service.queryOne(Person.class, "SELECT x FROM Person x WHERE x.email = ?1", email);
if(person == null)
{
JsfUtils.addErrorMessage("authorization failed");
return;
}
userBean.setPerson(person);
externalContext.redirect(originalURL);
}
public void logout() throws IOException
{
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
externalContext.invalidateSession();
externalContext.redirect(externalContext.getRequestContextPath());
}
// getters/setters
}
using this form inside /login.xhtml:
<h:form>
<p:panel header="#{bundle.login}">
<h:panelGrid columns="3">
<h:outputLabel for="email" value="#{bundle.email}" />
<h:outputLabel for="password" value="#{bundle.password}" />
<h:panelGroup />
<p:inputText id="email" value="#{authBean.email}" label="#{bundle.email}" size="32" />
<p:password id="password" value="#{authBean.password}" label="#{bundle.password}" feedback="false" size="32" />
<p:commandButton value="#{bundle.login}" action="#{authBean.login}" icon="ui-icon ui-icon-check" />
</h:panelGrid>
</p:panel>
</h:form>
and this login-config:
<login-config>
<auth-method>FORM</auth-method>
<realm-name>some-realm-name</realm-name>
<form-login-config>
<form-login-page>/login.jsf</form-login-page>
<form-error-page>/login.jsf</form-error-page>
</form-login-config>
</login-config>

JSF Message on SUBMIT action

I begin with my case:
JSF 2.1
Tomcat 7.0.27
Netbeans as IDE
JSF and PRIMEFace (but optional)
Level JSF beginner
Level JAVA good and not god
I have done a simple JSF site to learn how to works with JSF. My question is based on Login example at this step the problem is not related about that login that is obviously insicure.
A bit of code:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
/**
*
* #author
*/
#ManagedBean
#SessionScoped
//#RequestScoped
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private final String userName = "User";
private final String userPassword = "12345";
private String name;
private String password;
private boolean isLogged=false;
public String getName() {
return name;
}
public void setName( String name ) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword( String password ) {
this.password = password;
}
public String login() {
if( !(userName==null || password==null)
&&
(userName.equals( name ) && userPassword.equals( password ))) {
isLogged=false;
return "main";
} else {
isLogged=true;
return "index";
}
}
public boolean getIsLogged(){
return isLogged;
}
}
The page index
<?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">
<h:head>
<title>TSAM 7.5 Login</title>
</h:head>
<h:body>
Login system
<br />
<!--<h:link outcome="welcomePrimefaces" value="Primefaces welcome page" />-->
<h:form>
User : <h:inputText value="#{user.name}" />
Password : <h:inputSecret value="#{user.password}" />
<h:commandButton action="#{user.login()}" value="Submit" />
<h:commandButton value="reset" type="reset" />
<h:commandButton value="otherpage" action="otherpage"></h:commandButton>
</h:form>
</h:body>
</html>
The main page
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<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:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<f:event type="preRenderView" listener="#{user.isLogged}"/>
<f:view contentType="text/html">
<h:head>
<f:facet name="first">
<meta content='text/html; charset=UTF-8' http-equiv="Content-Type"/>
<title>PrimeFaces</title>
</f:facet>
</h:head>
<h:body>
<p:layout fullPage="true">
<p:layoutUnit position="north" size="100" resizable="true" closable="true" collapsible="true">
Header
</p:layoutUnit>
<p:layoutUnit position="south" size="100" closable="true" collapsible="true">
Footer
</p:layoutUnit>
<p:layoutUnit position="west" size="175" header="Left" collapsible="true">
<p:menu>
<p:submenu label="Resources">
<p:menuitem value="Demo" url="http://www.primefaces.org/showcase-labs/ui/home.jsf" />
<p:menuitem value="Documentation" url="http://www.primefaces.org/documentation.html" />
<p:menuitem value="Forum" url="http://forum.primefaces.org/" />
<p:menuitem value="Themes" url="http://www.primefaces.org/themes.html" />
</p:submenu>
</p:menu>
</p:layoutUnit>
<p:layoutUnit position="center">
Welcome to PrimeFaces
</p:layoutUnit>
</p:layout>
</h:body>
</f:view>
</html>
First
I use action="#{user.login()}" to make navigation action is this correct or there is a better pattern?
But the real question is: How to show a message If I redirect?
I like to show a message I know the example by PrimeFace http://www.primefaces.org/showcase/ui/dialogLogin.jsf. but it doesn't redirect or show anything.
But if i use only "plain" JSW without PrimeFace, i like to put a
because it is similar to PrimeFaces so switch is simple.
I'd like to adopt a "pattern" so i can reuse it for eg when i do a serch an no data is present, or when i call "erease DB" and application say work in progress an then say OK all bank account are esreased (Only an example!! but interesting because there are 2 message).
Thanks
I try
public String login() {
if (!(userName == null || password == null)
&& (userName.equals( name ) && userPassword.equals( password ))) {
isLogged = true;
return "main";
} else {
isLogged = false;
FacesMessage facesMsg;
facesMsg = new FacesMessage( FacesMessage.SEVERITY_ERROR, "No login", "No login because username or passsword are incorrect etc" );
FacesContext fc = FacesContext.getCurrentInstance();
fc.addMessage( "loginError", facesMsg );
return "index";
}
}
And edited the page
<h:body>
Login system
<br />
<!--<h:link outcome="welcomePrimefaces" value="Primefaces welcome page" />-->
<h:form>
User : <h:inputText value="#{user.name}" />
Password : <h:inputSecret value="#{user.password}" />
<h:commandButton action="#{user.login()}" value="Submit" />
<h:commandButton value="reset" type="reset" />
<h:commandButton value="Cambio Password" action="changePassword"></h:commandButton>
</h:form>
<h:message for="" style="color:red;margin:8px;"/>
</h:body>
It works but it's not ok because it's not ok to put a string in the bean. And I need the multilanguage this string has to generated by the beans.... mmm this is not OK something i'm missing.
There's extremely a lot of noise in the question. I understand that your question ultimately boils down to:
How do I create a localized faces message in bean action method?
In that case, just get the message from the current resource bundle yourself.
As you're talking about localization, you should surely already have something like as
<resource-bundle>
<base-name>com.example.i18n.text</base-name>
<var>text</var>
</resource-bundle>
in your faces-config.xml. You could just get it in the bean as well with help of ResourceBundle which JSF itself is actually also using under the covers
Locale locale = FacesContext.getCurrentInstance().getViewRoot().getLocale();
ResourceBundle text = ResourceBundle.getBundle("com.example.i18n.text", locale);
This way you could compose your message as
String summary = text.getString("messages.no_login_summary");
String detail = text.getString("messages.no_login_detail");
new FacesMessage(FacesMessage.SEVERITY_ERROR, summary, detail);

JSF El expression retaining old value (JSF life cycle)

I have create a test project with JSF2.0 and richfaces. I am trying to plot chart. Now, I got value from database to bean and to datatable. Now when I wanted to pass this value to javascript varible and found this answer from The BalusC very userful. It works fine but the value that javascript variable gets after oncomplete="jsonDemo('#{kpilist.json}')". i.e. the value of #{kpilist.json} is not up-to-date it's last one.
I have printed the value of #{kpilist.json}. If it's printed afer datatabe the value is current. If it's printed before datatable it's last value. Any way since oncomplete attribute of a4j:ajax executes after eveything is completed why doesn't #{kpilist.json} show latest value? What is the order of execution of various listener and oncomplete attributes of richfaces and jsf component?
My Managed Bean:
#ManagedBean(name = "kpilist")
#ViewScoped
public class KPIListController implements Serializable {
private static final long serialVersionUID = 1L;
boolean state = true;
String selectedKPIType;
String selectKPITime = "D";
boolean renderDatatable;
String json;
public String getJson() {
return json;
}
public boolean isRenderDatatable() {
return renderDatatable;
}
public void setRenderDatatable(boolean renderDatatable) {
this.renderDatatable = renderDatatable;
}
public boolean isState() {
return state;
}
public List<String> showViewList() {
Logger.getLogger(KPIListController.class.getName()).warning("Show view List:");
KPIDAO kpiDAO = new KPIDAO();
try {
Logger.getLogger(KPIListController.class.getName()).info("Into show view List ---select One");
return kpiDAO.showViewList(selectKPITime);
} catch (SQLException ex) {
ex.printStackTrace();
Logger.getLogger(KPIListController.class.getName()).log(Level.SEVERE, null, ex);
return null;
}
}
public void setState(boolean state) {
this.state = state;
}
public String getSelectedKPIType() {
return selectedKPIType;
}
public void setSelectedKPIType(String selectedKPIType) {
this.selectedKPIType = selectedKPIType;
}
public String getSelectKPITime() {
return selectKPITime;
}
public void setSelectKPITime(String selectKPITime) {
this.selectKPITime = selectKPITime;
}
public List<KPI> getKPI() {
Logger.getLogger(KPIListController.class.getName()).warning("Get KPI Values:");
KPIDAO kpiDAO = new KPIDAO();
List<KPI> kpiList = new ArrayList<KPI>();
try {
kpiList = kpiDAO.getKPI(selectedKPIType);
Logger.getLogger(KPIListController.class.getName()).warning("KPI List:"+kpiList.size());
} catch (SQLException ex) {
ex.printStackTrace();
return null;
}
Gson gson = new Gson();
json= gson.toJson(kpiList);
return kpiList;
}
public void resetFormValues() {
Logger.getLogger(KPIListController.class.getName()).warning("Reset form:");
selectedKPIType = "--";
}
}
My View:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:rich="http://richfaces.org/rich"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jsp/jstl/core">
<h:head>
</h:head>
<h:body>
<ui:composition template="/contentTemplate.xhtml">
<ui:define name="windowTitle">KPI Index</ui:define>
<ui:define name="content" >
<h:outputScript name="js/graphics/jquery.js"/>
<h:outputStylesheet name="/css/jquery-ui-1.8.22.custom.css"/>
<h:outputScript name="js/graphics/jquery-ui-1.8.22.custom.min.js"/>
<h:outputScript name="js/OpenLayers/OpenLayers.js"/>
<h:outputScript name="js/graphics/raphael-min.js"/>
<h:outputScript name="js/graphics/canvg.js"/>
<h:outputScript name="js/graphics/paths.js"/>
<h:outputScript name="js/graphics/draw.js"/>
<h:form id="ins_sel_form">
<h:outputText value="KPI TIME FRAME"/>
<h:selectOneRadio value="#{kpilist.selectKPITime}" >
<f:selectItem itemLabel="DAILY" itemValue="D" />
<f:selectItem itemLabel="WEEKLY" itemValue="W" />
<f:selectItem itemLabel="LAST WEEK" itemValue="LW" />
<a4j:ajax event="change" render="ins_sel_form:selectOnemenu dataPnl" listener="#{kpilist.resetFormValues()}" />
</h:selectOneRadio>
<h:outputText value="Major KPI Type"/>
<h:selectOneMenu id="selectOnemenu" value="#{kpilist.selectedKPIType}" >
<f:selectItem itemValue="--" itemLabel="--"></f:selectItem>
<f:selectItems itemValue="#{item.toString()}" var="item" itemLabel="#{item.toString()}" value="#{kpilist.showViewList()}"/>
<a4j:ajax event="change" render="dataPnl" oncomplete="jsonDemo('#{kpilist.json}')" />
</h:selectOneMenu>
<h:outputText value="Show / Hide Map"/>
</h:form>
<rich:panel id ="dataPnl">
<rich:dataTable id="kpiValueTable" value="#{kpilist.KPI}" var="kpi" style="width:100%" rows="20" rendered="#{kpilist.selectedKPIType!=null and kpilist.selectedKPIType !='--' }" >
<rich:column>
<f:facet name="header" >
<h:outputText value ="Value"></h:outputText>
</f:facet>
<h:outputText value="#{kpi.KPIValue}"></h:outputText>
</rich:column>
</rich:dataTable>
JSON String : <h:outputText id="json" value ="#{kpilist.json}"/>
<center><rich:dataScroller for="kpiValueTable" rendered="#{kpilist.selectedKPIType!=null and kpilist.selectedKPIType!='--'}"/></center>
</rich:panel>
<rich:panel id="map" style="display: none;">
</rich:panel>
</ui:define>
</ui:composition>
</h:body>
</html>
Javascript:
function jsonDemo(jsonString){
console.log("Chart data already retrieved: " + jsonString);
var data = $.parseJSON(jsonString);
$.each(data,function(i,val){
console.log("The value of i: "+i+" The val: "+val.NCELLCLUSTER);
});
}
The EL expression in your oncomplete is evaluated at the moment the HTML/JS code is generated by JSF (thus, on the initial HTTP request). It's not evaluated at the moment the oncomplete is executed in JS as you seem to expect. It's not the webbrowser who evaluates EL expressions, it's the webserver. The oncomplete is by the way just executed after render. With a HTTP traffic debugger and a JS debugger (press F12 in Chrome/IE9/Firebug) you can easily track it.
There are several possibilities to solve this:
Just invoke a $.get() or $.getJSON() in jQuery and do the job in a normal servlet instead, or better, a JAX-RS webservice.
function jsonDemo() {
$.getJSON("servletURL", function(jsonData) {
// ...
});
}
Replace the oncomplete by some <h:outputScript> which you render/update by ajax.
<a4j:ajax ... render="json" />
...
<h:panelGroup id="json">
<h:outputScript rendered="#{not empty bean.json}">jsonDemo(#{bean.json});</h:outputScript>
</h:panelGroup>
Unrelated to the concrete problem, you've there by the way a conceptual mistake as to passing around JSON data. You're stringifying it while passing as argument like so jsonDemo('#{kpilist.json}') and then you're parsing the JSON afterwards using $.parseJSON(). This makes no sense. Remove those singlequotes around the argument like so jsonDemo(#{kpilist.json}) and then you don't need that $.parseJSON() line anymore. The data is then already in JSON format.
Try changing from a4j:ajax to f:ajax
not sure if a4j:ajax works with plain JSF components

Resources