I use JSF in implementation MyFaces 2.0. In my web application I want to have page with button "show more". User get page, there are only button and hide form with some information (e.g. with label). When user click this button he would see on the same page with showed label. When he click again label should hide.
myPage.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:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
</h:head>
<h:body>
<h:form>
<h:commandButton value="show more" action="#{bean.showOrHide}">
<f:ajax render=":formWithLabel"/>
</h:commandButton>
</h:form>
<hr/>
<h:form id="formWithLabel" rendered="#{bean.show}">
<h:outputLabel value="More information"/>
</h:form>
</h:body>
Bean.java:
@ManagedBean
@ViewScoped
public class Bean {
private boolean show;
//getters, setters
public void showOrHide(){
show = !show;
}
}
This code seems to be not working. What is wrong?
Indeed, this approach won't work.
The
<f:ajax render=":formWithLabel"/>
works basically as follows:<update id="formWithLabel">
with therin the updated HTML.document.getElementById("formWithLabel")
to find the element so that its inner HTML content can be replaced with the one from ajax response.However, as the
<h:form id="formWithLabel" rendered="#{bean.show}">
is never rendered in first place, JavaScript can't find anything in HTML document to replace the inner HTML content with the one from ajax response and fails silently.You need to wrap it in another JSF component which is always rendered to HTML output, so that JavaScript can find it while it needs to update the HTML document based on ajax response.
See also:
Unrelated to the concrete problem, you may stumble upon a new problem when you intend to invoke actions on this form. You might want to swap the
<h:panelGroup>
with the<h:form>
.See also: