I'm having a problem with the tag in JSF2.0 and I hope someone can point out what I'm doing wrong. Here's what I've got in the UI:
<h:panelGroup>
<h:form id="theForm">
<h:selectOneMenu id="theMenu" value="#{viewBean.selectedItem}">
<f:ajax event="change" render="selectedItemText"/>
<f:selectItem itemLabel=""/>
<f:selectItems value="#{viewBean.selectableItems}"/>
</h:selectOneMenu>
<h:outputText id="selectedItemText" value="#{viewBean.selectedItemText}" />
</h:form>
</h:panelGroup>
This is working great - my conversation-scoped backing bean has a method setSelectedItem, and it's called and it does its thing the first time I select a different item from the menu; the output text is updated in the frontend, and I'm happy. However, further changes to the menu selection do not trigger a call to the setter via ajax. I've also tried this with a listener on the f:ajax tag - the listener method is only called that first time as well (breakpoints in the code to figure this out).
Am I doing something incorrectly?
I had a similar problem.
My second commandButton below only works once in the JSF view below that has a view param. Adding <f:param> to my first commandButton solved the problem. This is a situation not covered by BalusC's very helpful discussion.
<!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">
<f:view>
<f:metadata>
<f:viewParam name="id" value="#{fooManager.millis}" required="true"/>
</f:metadata>
<h:head>
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
</h:head>
<h:body>
<h:form id="fooForm">
<h:commandButton
id="barBbutton"
value="foo:test"
action="#{fooManager.test}">
<f:param name="id" value="1"/>
<f:ajax render="fooMillis1"/>
</h:commandButton>
<p>
<h:outputText id="fooMillis1" value="foo:display1: #{fooManager.millis}"/>
</p>
<p>
<h:outputText id="fooMillis2" value="foo:display2: #{fooManager.millis}"/>
</p>
</h:form>
<h:form id="barForm">
<h:commandButton
id="barButton"
value="bar:test"
action="#{barManager.test}">
<f:ajax render="barMillis1"/>
</h:commandButton>
<p>
<h:outputText id="barMillis1" value="bar:display1: #{barManager.millis}"/>
</p>
<p>
<h:outputText id="barMillis2" value="bar:display2: #{barManager.millis}"/>
</p>
</h:form>
</h:body>
</f:view>
</html>
And my FooManager and BarManager look the same:
#ManagedBean
#ViewScoped
public class FooManager {
public long getMillis() {
return millis;
}
public void setMillis(long millis) {
this.millis = millis;
}
public void test() {
setMillis(System.currentTimeMillis());
}
private long millis;
}
When it is not working, my Weblogic/Mojarra library does not give any helpful hint. There is no error anywhere. It was only after numerous tries that I came up with a working button like the first one above.
I had the same issue.
For the code below ajax was run only once.
<h:inputText id="element_id" value="#{viewBean.someValue}"></h:inputText>
<h:commandLink action="#{viewBean.someAction}" value="click me">
<f:ajax render=":my_form:another_element" execute="element_id> </f:ajax>
</h:commandLink>
When I add to render attribute the element which I'm executing then the ajax is triggered every time.
<h:inputText id="element_id" value="#{viewBean.someValue}"></h:inputText>
<h:commandLink action="#{viewBean.someAction}" value="click me">
<f:ajax render=":my_form:another_element element_id" execute="element_id> </f:ajax>
</h:commandLink>
I had a similar problem, in my case everithing worked fine in all browsers except that in IE9 the ajax was fired only once.
I was using render="#form" and when I changed it to render="#all", it worked fine. I dunno why, since I only have one Form in that page, and all my components are in that form.
So I would advise you to check the render and execute tags, at least in my case it was the solution
I had the same bug, fixed it using Primeface's p:ajax instead of f:ajax.
Related
I found a problem while using the bootsfaces inputText with ajax.
I'm using JSF 2.2, Bootsfaces 0.8.1 and Primefaces 5.3.
I'm trying to enter a date value into the inputText field. As soon as I enter the last value for the date the inputText should trigger the change event. At this point I would like to use ajax for calling a bean method. The problem is, that my field loses focus as soon as I try to enter the last value and the method's never been invoked.
So I tried a bit with Primefaces and it almost works like I wanted. At this point I got different questions:
Why does my inputText field lose the focus while entering the last value? (Bootsfaces)
Why is the bean method never called after I lose the focus? (Bootsfaces)
Is it possible to invoke the bean method after the bean value has been set by the field? (Primefaces)
I added the code below, so maybe you can reproduce this behaviour.
test.xhtml - sample xhtml with both primefaces and bootsfaces fields
<?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:b="http://bootsfaces.net/ui"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
<meta charset="UTF-8"/>
</h:head>
<h:body>
<h:form id="form">
<b:panel id="filterPanel" title="Filter properties" immediate="true" collapsed="false" collapsible="true">
<b:row>
<b:column span="12">
<b:inputText id="dateA" type="date" value="#{test.dateA}" immediate="true" class="form-control">
<f:ajax event="change" listener="#{test.searchA()}"/>
</b:inputText>
</b:column>
</b:row>
<b:row>
<b:column span="12">
<p:inputText id="dateB" type="date" value="#{test.dateB}" immediate="true" class="form-control">
<p:ajax event="change" listener="#{test.searchB()}"/>
</p:inputText>
</b:column>
</b:row>
</b:panel>
</h:form>
</h:body>
</html>
TestBean.java - my bean for setting the values and calling methods
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#ManagedBean(name = "test")
#ViewScoped
public class TestBean {
private String dateA;
private String dateB;
public void searchA() {
System.out.println("Search A");
}
public void searchB() {
System.out.println("Search B");
}
public String getDateA() {
return dateA;
}
public void setDateA(String dateA) {
this.dateA = dateA;
System.out.println(dateA);
}
public String getDateB() {
return dateB;
}
public void setDateB(String dateB) {
this.dateB = dateB;
System.out.println(dateB);
}
}
Please help me finding a solution or explain me what I'm doing wrong here.
Thanks
mweber
You've found a subtle difference between BootsFaces and PrimeFaces. I recommend you always define the values of process and update for the sake of clarity. In your case,
<b:inputText id="dateA" type="date" value="#{test.dateA}" immediate="true" class="form-control">
<f:ajax event="change" listener="#{test.searchA()}" render="#none"/>
</b:inputText>
makes the BootsFaces input field behave exactly like its PrimeFaces counterpart.
The default values of update and process are different. Since BootsFaces 0.8.5, the default values are:
process="#form" for <b:commandButton /> and <b:commandLink />
process="#this" for every other BootsFaces component
update="#form" for every BootsFaces component
According to Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes, the PrimeFaces default values are:
For the sake of convenience, here's my version of the XHTML file:
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
xmlns:b="http://bootsfaces.net/ui"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
<meta charset="UTF-8"/>
</h:head>
<h:body>
<h:form id="form">
<b:panel id="filterPanel" title="Filter properties" immediate="true" collapsed="false" collapsible="true">
<b:row>
<b:column span="12">
<b:inputText id="dateA" type="date" value="#{test.dateA}" immediate="true" class="form-control">
<f:ajax event="change" listener="#{test.searchA()}" render="#none"/>
</b:inputText>
</b:column>
</b:row>
<b:row>
<b:column span="12">
<p:inputText id="dateB" type="date" value="#{test.dateB}" immediate="true" class="form-control">
<p:ajax event="change" listener="#{test.searchB()}"/>
</p:inputText>
</b:column>
</b:row>
</b:panel>
</h:form>
</h:body>
</html>
I've tested it with BootsFaces 0.8.5.
I have a field that is rendered conditionally, based on a dropdown. All of that goes without problem, but when I submit the form of which the newly rendered component should be part of, it doesn't get submitted.
The code is fairly straightforward:
<h:form id="form">
<p:layout id="layout">
...
<p:layoutUnit id="layoutUnit">
...
<p:panel id="panel">
<p:outputPanel id="container1">
<p:selectOneMenu id="value1" value="#{bean.value1}">
<f:selectItem itemValue="1"/>
<f:selectItem itemValue="2"/>
<f:selectItem itemValue="3"/>
<f:selectItem itemValue="18"/>
<p:ajax event="change" update="container2"/>
</p:selectOneMenu>
</p:outputPanel>
<p:outputPanel id="container2">
<p:inputText id="value2"
value="#{bean.value2}"
rendered="#{bean.value1 eq 18}"
>
</p:inputText>
</p:outputPanel>
</panel>
<div id="buttons">
<p:commandButton id="commandButton" action="#{bean.save}" value="save" />
</div>
</layoutUnit>
</layout>
</form>
Tried possible solutions:
#ViewScoped of JSF is not usable, because it clashes with CDI
JSF Dynamic Rendered Component's Value becomes null when the form is submitted
conditionally rendered input component does not update value
commandButton/commandLink/ajax action/listener method not invoked or input value not updated
I can think of a few scenarios causing this behaviour:
'Rendered' seems to re-evaluate based on values in the backing bean,
rather than the new values given in the UI (if it defaults to 1, it is 1 again on submit, not 18). The component therefore
doesn't get submitted.
The added component isn't correctly added to
the form, and therefore not submitted.
?
Option 1 seems to be the most likely one, but could anyone point me in the right direction?
I work with WAS8.5 (so JSF2.0), Primefaces and CDI.
Using CDI's #ConversationScoped in addition to #Named is a solution. That scope works comparable to the #ViewScoped from JSF.
To get it working I've simply added code from the example here. So in short:
Bean.java
#Named
#ConversationScoped
public class Bean implements Serializable{
#Inject
private Conversation conversation;
Bean values, getters & setters
public void initConversation(){
if (!FacesContext.getCurrentInstance().isPostback() && conversation.isTransient()) {
conversation.begin();
}
}
public String endConversation(){
if(!conversation.isTransient()){
conversation.end();
}
}
public String navigateAwayFromScreen(){
endConversation();
}
}
beanOutput.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:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets">
<f:event listener="#{bean.initConversation}" type="preRenderView"/>
<h:form id="form">
<p:layout id="layout">
...
<p:layoutUnit id="layoutUnit">
...
<p:panel id="panel">
<p:outputPanel id="container1">
<p:selectOneMenu id="value1" value="#{bean.value1}">
<f:selectItem itemValue="1"/>
<f:selectItem itemValue="2"/>
<f:selectItem itemValue="3"/>
<f:selectItem itemValue="18"/>
<p:ajax event="change" update="container2"/>
</p:selectOneMenu>
</p:outputPanel>
<p:outputPanel id="container2">
<p:inputText id="value2"
value="#{bean.value2}"
rendered="#{bean.value1 eq 18}"
>
</p:inputText>
</p:outputPanel>
</panel>
<div id="buttons">
<p:commandButton id="commandButton" action="#{bean.navigateAwayFromScreen}" value="Go away!" />
</div>
</layoutUnit>
</layout>
</form>
</html>
Now, a conversation gets started when you open the page (due to the initConversation being called from the top of beanOutput.xhtml), and ended when you click the button navigateAwayFromScreen.
(However, if you are able to work with JSF2.2, it should be possible to use the #ViewScoped in combination with CDI. (I say 'should': I am not in the situation to upgrade. But it may be useful to others to examine)).
I have the below Test.xhtml where i can select mode as Sea/Air. I don't want to load the all the 4 pages(Page1.xhtml, Page2.xhtml, Page3.xhtml, Page4.xhtml) into the jsf view tree. In my scenario, mode once selected and saved that can not be changed to other mode. The saved mode will be shown as view mode. Since at any point of time i need only 2 files (Page1.xhtml, Page2.xhtml (or) Page3.xhtml, Page4.xhtml)... I am using the JSTL tag handler for dynamic including the pages. the below thing is working fine. But i am not able to understand how the rendering working.
Test.xhtml
<!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:ui="http://java.sun.com/jsf/facelets"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich"
xmlns:c="http://java.sun.com/jsp/jstl/core">
<h:head><title>JSF And JSTL</title>
<link href="../css/styles.css"
rel="stylesheet" type="text/css"/>
</h:head>
<h:body>
<div align="center">
<h:form id="form1">
<h:panelGrid columns="2">
<h:outputLabel value="Select Mode"/>
<h:selectOneMenu id="selectPageId" value="#{testBean.selectedMode}">
<f:selectItem itemLabel="Select" />
<f:selectItem itemLabel="Sea" itemValue="sea" />
<f:selectItem itemLabel="Air" itemValue="air" />
<f:ajax execute="#this" render="pageGroup"/>
</h:selectOneMenu>
</h:panelGrid>
<h:panelGroup id="pageGroup">
<c:if test="#{'sea' eq testBean.selectedMode}">
<ui:include src="Page1.xhtml" />
<ui:include src="Page2.xhtml" />
</c:if>
<c:if test="#{'air' eq testBean.selectedMode}">
<ui:include src="Page3.xhtml" />
<ui:include src="Page4.xhtml" />
</c:if>
</h:panelGroup>
</h:form>
</div>
</h:body>
</html>
TestBean.java
package com.test;
#ManagedBean(name = "testBean")
#ViewScoped
public class TestBean {
private String selectedMode;
public String getSelectedMode() {
return selectedMode;
}
public void setSelectedMode(String selectedMode) {
this.selectedMode = selectedMode;
}
}
Updated Again
Please help to clarify the below.
When i send a request first time to access the Test.xhtml, the jsf view (UIViewRoot) gets created. Since testBean.selectedMode by default is null.. this created view would not contain any component details of <c:if> and <ui:include> which are inside of <h:panelGroup id="pageGroup">.
After that when i send a second request(ajax postback) by selecting the mode as sea, the UIViewRoot gets created again for the request in the Restore View Phase. While UIViewRoot creation for this request in Restore View Phase, the tag handlers(<c:xxx>, <f:xxx>, <ui:include>) will get executed.
Since the selected value 'sea' will be updated to model(TestBean.java) only in Update Model Values Phase, in the Restore View Phase the EL #{testBean.selectedMode} will be evaluated to null.
So in my example Test.xhtml page the both tag handlers (<c:if test="#{'sea' eq testBean.selectedMode}"> and <c:if test="#{'air' eq testBean.selectedMode}">) will be evaluated to false. So the UIViewRoot does not contain any information related to the components inside <h:panelGroup id="pageGroup">.
Even though the UIViewRoot does not contain the components information inside the <h:panelGroup id="pageGroup">, How JSF able to render the included pages(<ui:include src="Page1.xhtml" />,<ui:include src="Page2.xhtml" />) successfully?
I am not sure how JSF rendering happening here. While Rendering, Is JSF re-creating the component tree for the particular rendering part(<h:panelGroup id="pageGroup">).?
Note: The example is working fine when i select mode as sea/air. The corresponding parts are rendering correctly.
I have some problems with session scoped bean working with f:viewParam. So I have two pages, test_first.xhtml and test_second.xhtml, and a TestBean.java.
first.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.org/ui">
<h:head/>
<h:body>
<h:form>
<h:link value="link1" outcome="test_second" >
<f:param name="id" value="1"/>
</h:link>
<br/><br/>
<h:link value="link2" outcome="test_second" >
<f:param name="id" value="2"/>
</h:link>
</h:form>
</h:body>
</html>
second.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.org/ui">
<f:metadata>
<f:viewParam name="id" value="#{testBean.userId}" />
</f:metadata>
<h:head/>
<h:body>
<h:form>
This is the second page.
<h:outputText value="Selected id is #{testBean.userId}" />
<h:commandButton value="Print page id" action="#{testBean.print()}" />
<h:commandButton styleClass="submitButton" value="Submit" action="#{testBean.submit}">
<f:ajax execute="#form" render="#form"/>
</h:commandButton>
</h:form>
</h:body>
</html>
TestBean.java:
#ManagedBean
#SessionScoped
public class TestBean implements Serializable{
private Integer userId;
public void print() {
System.out.println(userId);
}
public void submit() {
System.out.println(userId);
}
/...
}
Start running from first.xhtml, if I open link1 in a new tab and then open link2 in another new tab. Now I got two pages.
If I click the "Print page id" button in link1, 1 will be printed in the console. In link2 the printed value will be 2.
But if I click the Submit button in link1, 2 will be printed and the rendered text will change from 1 to 2. (because link2 is opened later and the bean is session scoped?)
(Update: Why is this case? How can I still print "1" if I click "Submit"?)
I want to keep the bean as session scoped for other properties basically. So any thoughts on this or any alternative methods? Many thanks!
If you want it working in different tabs or windows, you need to put those tab specific properties on a ViewScoped or RequestScoped Bean. For properties that are session specific, you could create another Bean and make it SessionScoped.
Popup panels in RichFaces are pretty ugly to work with to be honest. There are several calls to some JavaScripts involved which makes it not easy to derive something that works in general. Anyway, I was trying the following:
<?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">
<ui:composition 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:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
<h:commandLink>
<h:graphicImage library="images/icons" name="#{buttonImageFileName}" />
<rich:tooltip value="#{buttonTooltipText}" direction="bottomRight" />
<rich:componentControl target="#{popupId}" operation="show" />
</h:commandLink>
<rich:popupPanel modal="true"
height="#{popupHeight}"
resizeable="#{popupResizable}"
onmaskclick="#{componentCallToId}.hide(); return false;"
id="#{popupId}">
<f:facet name="header">
<h:outputText value="#{popupHeaderText}" />
</f:facet>
<f:facet name="controls">
<h:outputLink value="#" onclick="#{componentCallToId}.hide(); return false;">
<h:outputText value="X" />
</h:outputLink>
</f:facet>
<p>#{popupSubject}</p>
<p>
<h:inputText value="#{inputTextBean[inputTextProperty]}" styleClass="full-width" id="#{inputTextId}" />
</p>
<h:panelGrid columns="2" style="margin: 0 auto;">
<h:commandButton value="OK"
action="#{acceptButtonBean[acceptButtonMethod](acceptButtonMethodArg)}"
onclick="#{componentCallToId}.hide(); return true;">
<a4j:ajax execute="#this #{inputTextId}" render="#form" />
</h:commandButton>
<h:commandButton value="Cancel" onclick="#{componentCallToId}.hide(); return false;" immediate="true" />
</h:panelGrid>
</rich:popupPanel>
</ui:composition>
This displays an image button which pops up a simple input dialog, which is supposed to be hidden by clicking outside the popup (onmaskclick="..."), by X'ing the popup in the top right corner (<f:facet> with onclick="..."), or by pressing the Cancel <h:commandButton onclick="...">. On OK the AJAX form is supposed to be submitted and the popup is hidden, too. But nothing happens (can't close):
The EL expression #{componentCallToId}.hide(); return false; is the "problem child" in the above. It is not working that way.
In its original, non-Facelets variant here (http://showcase.richfaces.org/richfaces/component-sample.jsf?demo=popup&sample=modalPopup&skin=classic) the call to control the component looks like this:
<h:commandButton value="Cancel" onclick="#{rich:component('add-root-chapter-popup')}.hide(); return false;" immediate="true" />
I pass the following parameters to <ui:include>:
<ui:include src="/subviews/add-node-clink-input-popup.xhtml">
<ui:param name="buttonImageFileName" value="add.png" />
...
<ui:param name="popupId" value="add-root-chapter-popup" />
<ui:param name="componentControlCallToId" value="rich:component('add-root-chapter-popup')" />
...
</ui:include>
Notice the long entry (the rest seems to be working - even the strange syntax for the bean + method + arg, but this is not the focus here).
Q:
Why isn't <ui:param name="componentControlCallToId" value="rich:component('add-root-chapter-popup')" /> working? Currently nothing happens when clicking outside the popup, X'ing, or pressing OK or Cancel (popup staying).
Firebug only shows:
syntax error
.hide(); return false;
Looks like the expression is evaluated to null/empty string.
What's wrong? Can it be fixed? What are my alternatives?
PS: Note, that I've previously tried to use the "popupId" in the Facelets expression like
<h:commandButton value="Cancel" onclick="#{rich:component('popupId')}.hide(); return false;" immediate="true" />
but this has the same result.
Omitting the single quotes did the trick:
<h:commandButton value="Cancel" onclick="#{rich:component(popupId)}.hide(); return false;" immediate="true" />
I thought they were part of JS, but they seem to be EL here.
Also you could try this:-
onmaskclick="#{rich:component('cc.attrs.popupId')}.hide()"
If the quotes cause you any problem use " instead of them.
I believe here you are trying to parse the id to the popup panel dynamically through your custom components exposed variables.
Where in you might be parsing the value for id as
popupId="xyz"
If this being the situation the above solution would work just fine.