In my WebApp I created a managed Bean that allows me to change the Locale from French to english and vice versa using Event Change Listener.
package beans;
import java.util.Locale;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
#ManagedBean
#SessionScoped
public class LocaleBean {
private Locale locale = FacesContext.getCurrentInstance().getViewRoot().getLocale();
public Locale getLocale() {
return locale;
}
public String getLanguage() {
return locale.getLanguage();
}
public void setLanguage(String language) {
locale = new Locale(language);
FacesContext.getCurrentInstance().getViewRoot().setLocale(locale);
}
}
and in my template.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 lang="#{localeBean.language}"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.prime.com.tr/ui"
xmlns:f="http://java.sun.com/jsf/core">
<f:view contentType="text/html" locale="#{localeBean.locale}" id="mescoca">
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title><ui:insert name="title"></ui:insert></title>
<h:outputStylesheet name="css/jsfcrud.css"/>
<!--<f:loadBundle var="bundle" basename="/Bundle"/> -->
</h:head>
<h:body style="font-size: small; font-family: Ubuntu,verdana;">
<h:form>
<p:panel closable="false" style="float: right;height: 50px;font-size: smaller" >
<h:panelGrid columns="2" style="text-align: center">
<h:outputText value="#{bundle.Language}"/>
<h:selectOneMenu value="#{localeBean.language}" onchange="submit()">
<f:selectItem itemValue="fr" itemLabel="Français" />
<f:selectItem itemValue="en" itemLabel="English" />
<f:selectItem itemValue="fr_FR" itemLabel="France"/>
<f:selectItem itemValue="en_US" itemLabel="US" />
</h:selectOneMenu>
</h:panelGrid>
</p:panel>
The others pages:
<?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">
<ui:composition template="/template.xhtml">
<ui:define name="title">
<h:outputText value="#{bundle.EditHistoryTitle}"></h:outputText>
</ui:define>
<ui:define name="body" >
<h:panelGroup id="messagePanel" layout="block">
<h:messages errorStyle="color: red" infoStyle="color: green" layout="table"/>
</h:panelGroup>
<h:form>.....
It is working, but the problem is that the language gets back to its first value once I navigate to another page. Otherwise, When I change the language, it only affects the current page and once I move to another page, the localization bundle gets its default value in faces-config.xml
What I need is to make the language persistent through the whole session.
Does anyone have a clue plz?
You need to wrap your master template in a
<f:view locale="#{LanguageBean.localeCode}">
See also:
Localization in JSF, how to remember selected locale per session instead of per request/view - contains complete bean/view code example
The problem is that when you are setting your Locale in the valueChangeListener you are setting it on the ViewRoot which lives and dies with the current view, and not the session.
You are storing your LocaleCode in the SessionScoped managed bean so you can set the Locale in the ViewRoot for every page and this should fix your problem.
Related
This question already has answers here:
How to choose the right bean scope?
(2 answers)
Closed 4 years ago.
I have an application with a p:selectOneMenu component. This component is used to determine what category of file is being uploaded so I can do some work to it when the file is uploaded.
I implemented the answer from this post and it seems to call my setter methods correctly for fileType. But once the file is submitted and the handleFileUpload method is called, the fileType getter method returns null.
For example, if I select Foo then I get the output
File type changed to: Foo
But when I hit the upload button I get the output
The file type selected is null
When I expect
The file type selected is Foo
What is causing the get method to return two different results and is there a way to fix this?
main.xhtml
<!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">
<meta http-equiv="refresh"
content="#{session.maxInactiveInterval};url=index.xhtml" />
<f:view contentType="text/html">
<h:head>
<title>File Upload</title>
</h:head>
<p:layout fullPage="true">
<p:layoutUnit position="center">
<ui:insert name="pagebody" />
</p:layoutUnit>
</p:layout>
</f:view>
</html>
index.xhtml
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<ui:composition 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" template="/templates/main.xhtml">
<ui:define name="pagebody">
<h:body>
<h:form id="uploadform" enctype="multipart/form-data">
<h:panelGrid columns="2" style="margin-bottom:10px" cellpadding="5">
<h:outputText value="File Type:" />
<p:selectOneMenu value="#{uploadBean.fileType}">
<f:selectItem itemLabel="Foo" itemValue="Foo"/>
<f:selectItem itemLabel="Bar" itemValue="Bar"/>
<f:ajax listener="#{uploadBean.changeFileType}" />
</p:selectOneMenu>
</h:panelGrid>
<br />
<p:fileUpload fileUploadListener="#{uploadBean.handleFileUpload}" mode="advanced"/>
</h:form>
</h:body>
</ui:define>
</ui:composition>
UploadBean.java
#RequestScoped
#ManagedBean(name = "uploadBean")
public class UploadBean implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private String fileType = null;
#PostConstruct
public void init() {
}
public void handleFileUpload(FileUploadEvent event){
System.out.println("The file type selected is " + this.getFileType());
}
public String getFileType() {
return fileType;
}
public void setFileType(String fileType) {
this.fileType = fileType;
}
public void changeFileType() {
System.out.println("File type changed to: " + this.getFileType());
}
}
As pointed out by #Kukeltje the issue was that my bean was not properly scoped. Switching from RequestScoped to ViewScoped fixed the issue I was having.
If I pass an expression to a composite component like
<My:myButton action="#{bean.myaction()" value="#{bean.buttText()}"
and try to use it in
<cc:implementation>
<h:commandButton actionListener="#{cc.attrs.action} value="#{cc.attrs.value}...
I get the exception "Target Unreachable, identifier 'bean' resolved to null".
But only if bean is a <ui:param name="bean" value="#{myRealBean}"/> inside a template. The error only occours with actionListener. The button text, resolved from the same bean in the same way will be shown.
This old question seems to have the same problem but no answer.
If I split the parameter to
<My:myButton bean="#{bean}" method="myaction" value="#{bean.buttText()}"
and use
<cc:implementation>
<h:commandButton actionListener="#{cc.attrs.bean[cc.attrs.method]()} ...
no error occours and everything works fine.
How can I use a function-expression in an actionListener inside a composite component, where the bean is a <ui:param?
Glassfish 4.1.1, Mojarra 2.2.12
And now, the MCVE
a bean:
package beans;
import java.io.Serializable;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
#Named
#ViewScoped
public class Testbean implements Serializable {
public String getButtText() { return "Submit"; }
public void doAction() { System.out.println("Ajax was here."); }
}
a 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://xmlns.jcp.org/jsf/facelets" xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ST="http://java.sun.com/jsf/composite/softeam" >
<h:head>
</h:head>
<h:body>
<h:form id="testform">
<h:panelGrid columns="1">
<ui:include src="testtemplate.xhtml">
<ui:param name="bean" value="#{testbean}"/>
</ui:include>
<ST:testButt text="#{testbean.buttText}" action="#{testbean.doAction()}"/>
<h:commandButton value="#{testbean.buttText}" actionListener="#{testbean.doAction()}"/>
</h:panelGrid>
</h:form>
</h:body>
</html>
and a template
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:ST="http://java.sun.com/jsf/composite/softeam">
<ST:testButt text="#{bean.buttText}" action="#{bean.doAction()}"/>
<h:commandButton value="#{bean.buttText}" action="#{bean.doAction()}" />
</ui:composition>
and the component
<!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:S="http://xmlns.jcp.org/jsf/composite" >
<S:interface>
<S:attribute name="action" method-signature="void action()"/>
<S:attribute name="text" type="java.lang.String"/>
</S:interface>
<S:implementation>
<h:commandButton style="display:inline-block"
value="#{cc.attrs.text}"
actionListener="#{cc.attrs.action}"
/>
</S:implementation>
</html>
All buttons will be shown (with the bean.buttText()) but only the second, third and fourth will call the action. The first button throws an exception when clicked.
Edit: Example reduced to JSF, no PrimeFaces components.
I'm trying to understand why a viewscoped view is recreating on every ajax call.
I have a test case, and it's working fine without composition templating.
I find questions that seem similar to my problem but the solutions don't work for me, like setting javax.faces.PARTIAL_STATE_SAVING to false or javax.faces.STATE_SAVING_METHOD to client.
Here's a sample:
page.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:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets"
>
<h:body>
<h:form id="pageForm">
<p:commandButton
value="Choose an option..."
actionListener="#{pageController.handleOptionChoose}"
update="selectedOption"
/>
<br/>
<h:panelGrid columns="2" cellpadding="3">
<p:outputLabel for="selectedOption" value="Selected option: "/>
<p:outputLabel id="selectedOption" value="#{pageController.selectedOption}"/>
</h:panelGrid>
<br/><br/>
<p:commandButton
value="Edit option"
actionListener="#{pageController.doAnythingWithTheOption}"
update="editedOption"
/>
<br/>
<h:panelGrid columns="2" cellpadding="3">
<p:outputLabel for="editedOption" value="Edited option: "/>
<p:outputLabel id="editedOption" value="#{pageController.editedOption}"/>
</h:panelGrid>
</h:form>
<p:dialog
id="dialogOption_Dialog"
header="Choose an option"
widgetVar="dialogOption_Widget"
modal="true"
appendTo="#(body)"
>
<h:form id="dialogOption_Form">
<h:panelGrid columns="1">
<p:selectOneButton id="dialogOptionChoose" value="#{pageController.selectedOption}" >
<f:selectItem itemLabel="Option 1" itemValue="Option 1" />
<f:selectItem itemLabel="Option 2" itemValue="Option 2" />
<f:selectItem itemLabel="Option 3" itemValue="Option 3" />
</p:selectOneButton>
<p:spacer width="0" height="20" />
<p:commandButton
value="Done"
action="#{pageController.showOption}"
update=":pageForm:selectedOption"
oncomplete="dialogOption_Widget.hide();"
/>
</h:panelGrid>
</h:form>
</p:dialog>
</h:body>
</html>
content.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:c="http://java.sun.com/jstl/core"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:mj="http://mojarra.dev.java.net/mojarra_ext"
xmlns:o="http://omnifaces.org/ui"
xmlns:of="http://omnifaces.org/functions">
<h:body>
<ui:composition template="/layout.xhtml">
<ui:define name="content">
<ui:include src="page.xhtml" />
</ui:define>
</ui:composition>
</h:body>
</html>
layout.xhtml
<!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"
xmlns:o="http://omnifaces.org/ui"
xmlns:of="http://omnifaces.org/functions">
<f:view contentType="text/html" transient="true">
<h:head>
<h:outputStylesheet name="theme.css" library="css" />
<f:facet name="first">
<f:metadata>
<meta http-equiv="X-UA-Compatible" content="IE=8" />
</f:metadata>
<title>Teste</title>
<link rel="icon" type="image/png" href="resources/css/icons/favicon.ico" />
</f:facet>
</h:head>
<h:body>
<p:layout fullPage="true" >
<p:layoutUnit id="top" position="north" size="50" style="border: 2px solid Black !important;">
<!-- <ui:insert name="menubar" /> -->
</p:layoutUnit>
<p:layoutUnit id="center" position="center" style="border: 2px solid Black !important;">
<ui:insert name="content" />
</p:layoutUnit>
<p:layoutUnit id="bottom" position="south" size="60" resizable="true" collapsible="true" style="border: 2px solid Black !important;">
<!-- <ui:insert name="footer" /> -->
</p:layoutUnit>
</p:layout>
</h:body>
</f:view>
</html>
PageController.java
package com.ericsantanna.grendel.mBeans;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import org.primefaces.context.RequestContext;
/**
* #author Eric Sant'Anna
*
*/
#ManagedBean
#ViewScoped
public class PageController {
private String selectedOption;
private String editedOption;
public PageController() {
System.out.println("RECREATING VIEW");
}
public void showOption() {
System.out.println("Selected option number: " + selectedOption.substring(7));
}
public void doAnythingWithTheOption() {
System.out.print("Trying to a substring in the selected option: ");
editedOption = selectedOption.substring(7);
System.out.println(editedOption);
}
public void handleOptionChoose() {
RequestContext.getCurrentInstance().execute("dialogOption_Widget.show();");
}
public String getSelectedOption() {
return selectedOption;
}
public void setSelectedOption(String selectedOption) {
this.selectedOption = selectedOption;
}
public String getEditedOption() {
return editedOption;
}
public void setEditedOption(String editedOption) {
this.editedOption = editedOption;
}
}
JBoss log (setup):
17:45:29,494 INFO [org.jboss.ejb.client] (MSC service thread 1-7) JBoss EJB Client version 1.0.5.Final
17:45:29,550 INFO [javax.enterprise.resource.webcontainer.jsf.config] (MSC service thread 1-8) Inicializando Mojarra 2.2.4 ( 20131003-1354 https://svn.java.net/svn/mojarra~svn/tags/2.2.4#12574) para o contexto '/JobSchedulerWeb'
17:45:30,344 INFO [org.hibernate.validator.util.Version] (MSC service thread 1-8) Hibernate Validator 4.2.0.Final
17:45:30,367 INFO [org.primefaces.webapp.PostConstructApplicationEventListener] (MSC service thread 1-8) Running on PrimeFaces 4.0
17:45:30,368 INFO [org.omnifaces.eventlistener.VersionLoggerEventListener] (MSC service thread 1-8) Using OmniFaces version 1.5
To reproduce this code, simply choose an option and click "Edit option" to do a substring in the backing bean, only to get a NullPointerException when using facelets templating. (Look at the console in each step)
Anyone can help?
This,
<f:view ... transient="true">
turns off JSF state saving for the current view. Essentially, this JSF view is stateless. As there's no view state, there's no means of a view scope and the logical consequence is that the view scoped bean instance can't be saved anywhere. It'll disappear in nowhere by end of the request and thus behave like a request scoped bean.
The observed symptoms are thus fully expected. If that wasn't your intent, then you need to remove the transient="true" attribute. It defaults to false.
This has completely nothing to do with templating. The <ui:composition> plays no significant role here. You'd have had exactly the same problem when merging the templates into a single template without <ui:composition>, <ui:define>, etc while keeping the same markup.
See also:
Why JSF saves the state of UI components on server?
javax.faces.application.ViewExpiredException: View could not be restored
I was trying to see exactly how property injection works with ViewScoped beans.
I inject the List from One to Two without problem. When I try to inject the same List from Two to Three nothing is injected but I think that's the intended behavior (I might be wrong though).
However when I try to inject the selected value from the SelectOneMenu of Two into Three nothing is being injected.
Is there something I am missing or is that the normal behaviour? If so, how can I retrieve that value in Three?
One.java
#ManagedBean
#ViewScoped
public class One implements Serializable {
private List<String> oneList;
#PostConstruct
void init() {
setOneList(new ArrayList<String>());
getOneList().add("aaa");
getOneList().add("bbb");
getOneList().add("ccc");
getOneList().add("ddd");
}
//Getters + setters...
}
one.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition template="/WEB-INF/template.xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<ui:define name="header">
<h:outputText value="ONE" />
</ui:define>
<ui:define name="content">
<h:form>
<p:commandButton value="two" action="two" ajax="false" />
</h:form>
</ui:define>
</ui:composition>
Two.java
#ManagedBean
#ViewScoped
public class Two implements Serializable {
#ManagedProperty("#{one.oneList}")
private List<String> oneList;
private String twoChoice;
//Getter + setters...
}
two.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition template="/WEB-INF/template.xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<ui:define name="header">
<h:outputText value="TWO" />
</ui:define>
<ui:define name="content">
<h:form>
<p:selectOneMenu id="test" value="#{two.twoChoice}">
<f:selectItems value="#{two.oneList}" />
</p:selectOneMenu>
<p:commandButton value="three" action="three" ajax="false" />
</h:form>
</ui:define>
</ui:composition>
Three.java
#ManagedBean
#ViewScoped
public class Three implements Serializable {
#ManagedProperty("#{two.oneList}")
private List<String> oneList;
#ManagedProperty("#{two.twoChoice}")
private String twoChoice;
private String threeChoice;
//Getters + setters...
}
three.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition template="/WEB-INF/template.xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<ui:define name="header">
<h:outputText value="THREE" />
</ui:define>
<ui:define name="content">
<h:outputText value="#{three.twoChoice}" />
</ui:define>
<h:form>
<p:selectOneMenu value="#{three.threeChoice}">
<f:selectItems value="#{three.oneList}" />
</p:selectOneMenu>
</h:form>
</ui:composition>
Managed properties are not intended to work like that. Keep in mind that a #ViewScoped bean is designed to keep alive as long as the view doesn't change, which means at the moment you navigate from one page to another using the non-ajax command button (in fact you're specifying the navigation-case to go in the action attribute), they should be destroyed, so you can't get any value from them.
Normally, I use #ManagedProperty notation to inject broader scope values (for example, a session value in a view scoped bean). So what is the solution for your case?
Actually you have different options:
You can use <f:viewParam /> tag to send the GET parameters while changing the view.
You can use flash scope, which keeps your values in a map that survives to a redirection. Not recomended if you are using Mojarra implementation of JSF, they still have to fix some problems with them.
Take care of the params yourself and set them in some data structure in session scope, after, when you recover them in your destination bean you can remove them.
I've been trying to put a queue onto a text area, and it is not cooperating. I'll list the relevant section of code below.
<h:form>
<a4j:queue requestDelay="1000" ignoreDupResponses="true"/>
<table>
<tr>
<td>
<h:outputText value="Notes:"/>
</td>
</tr>
<tr>
<td>
<h:inputTextarea value="#{MyActionBean.notes}">
<a4j:ajax event="keyup" listener="#{MyActionBean.updateNotes}"/>
</h:inputTextarea>
The notes get updated as expected, but there is no delay between requests. Is there some bug in my code, do textAreas not work for this? Any help would be appreciated.
EDIT: Just for good measure, tried the following code as well, but it didn't work either.
<h:panelGrid columns="1" width="100%">
<h:outputText value="Notes:"/>
<h:inputTextarea value="#{MyActionBean.notes}">
<a4j:ajax event="keyup" listener="#{MyActionBean.updateNotes}">
<a4j:attachQueue id="notesQueue" requestDelay="1000"/>
</a4j:ajax>
</h:inputTextArea>
</h:panelGrid>
For reference, the technology versions:
JBoss AS 7, Seam 2.3.0, Richfaces 4.2.2, JSF 2.1
For your case you need to nest a4j:attachQueue inside a4j. Try to run the code below and you'll notice that you'll get an output on the console after 15 seconds.
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<h:form>
<a4j:queue name='Y' requestDelay="3000" ignoreDupResponses="true"/>
<h:panelGrid columns="1" width="100%">
<h:outputText value="Notes:"/>
<h:inputTextarea value="#{MyActionBean.notes}">
<a4j:ajax event="keyup" listener="#{MyActionBean.updateNotes}">
<a4j:attachQueue requestDelay="3000"/>
</a4j:ajax>
</h:inputTextarea>
<a4j:status>
<f:facet name="start">
Please wait
</f:facet>
</a4j:status>
</h:panelGrid>
</h:form>
</h:body>
You can use this link if you need more information
UPDATE
I stripped down the code you sent to the bare minimum and I'm sorry to say that it is still working on my end with JBoss. Your issue could be somewhere else (e,g. your ajax might be failing for some reason since you told me "Please Wait" was not appearing). However, I should mention that I'm not familiar with JBoss' conversation scope so I changed it to javax.enterprise.context.SessionScoped (but I don't think that should matter because it was still working when it was requestscoped). I'm including all the code so you can test it yourself as a separate project. Also, since we are using a queue I changed the logging location from updateNotes to setReport so that I could be absolutely certain that the characters were actually being queued. When I typed "This is a test", the only output I saw was the entire String and not each character.
AssessmentCheckListAction.java
import java.io.Serializable;
import javax.faces.context.FacesContext;
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
#Named(value="AssessmentChecklistAction")
#SessionScoped
public class AssessmentCheckListAction implements Serializable {
private static final long serialVersionUID = -4970638494437413924L;
private String report;
public AssessmentCheckListAction() {
}
public void updateNotes() {
//FacesContext.getCurrentInstance().getExternalContext().log(report);
//Logging the setter to make sure everything was queued
}
public String getReport() {
return report;
}
public void setReport(String report) {
FacesContext.getCurrentInstance().getExternalContext().log(report);
this.report = report;
//left blank
}
index.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">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<ui:composition 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:a4j="http://richfaces.org/a4j"
template="template.xhtml">
<ui:define name="content">
<h:form>
<a4j:queue requestDelay="3000" ignoreDupResponses="true"/>
<h:panelGrid columns="1" width="100%">
<h:outputText value="Notes:"/>
<h:inputTextarea value="#{AssessmentChecklistAction.report}">
<a4j:ajax event="keyup" listener="#{AssessmentChecklistAction.updateNotes}">
<a4j:attachQueue requestDelay="3000"/>
</a4j:ajax>
</h:inputTextarea>
<a4j:status>
<f:facet name="start">
Please wait
</f:facet>
</a4j:status>
</h:panelGrid>
</h:form>
</ui:define>
</ui:composition>
</h:body>
</html>
template.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:ui="http://java.sun.com/jsf/facelets">
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="Cache-Control" content="no-store"/>
<meta http-equiv="Pragma" content="no-cache"/>
<meta http-equiv="Expires" content="0"/>
</h:head>
<h:body>
<ui:insert name="content"/>
</h:body>
</html>