Update component with Ajax results in Exception - ajax

It seems like I am simply unable to grasp, how updating components with Ajax works. I keep on getting an Exception "Cannot find component with identifier ":menu-item-container" referenced from "j_idt12:0:j_idt16:j_idt76"."
This is my code:
<!DOCTYPE html>
<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:view contentType="text/html">
<h:head>
<title><ui:insert name="pageTitle"></ui:insert></title>
</h:head>
<h:body>
<h:outputStylesheet library="css" name="style.css" />
<div class="menu-navigation">
<ul>
<li>Menu</li>
<ui:repeat var="category"
value="#{restaurantsBean.restaurant.categories}">
<h:form>
<li><p:commandLink update=":menu-item-container">
<div>
#{category.name}
<f:setPropertyActionListener value="#{category.id}"
target="# {restaurantMenuBean.selected}" />
</div>
</p:commandLink></li>
</h:form>
</ui:repeat>
</ul>
</div>
<div id="menu-item-container">
<ui:repeat var="category"
value="#{restaurantsBean.restaurant.categories}">
<p:outputPanel>
<h:panelGroup id="pangroup" layout="block"
rendered="#{restaurantMenuBean.active(category.id)}">
<div class="some-heading">
<h2>#{category.name}</h2>
</div>
<div class="category-description">#{category.description}</div>
<ui:repeat var="item" value="#{category.items}">
<p:outputPanel
rendered="#{restaurantMenuBean.needLightbox(item)}">
<ui:include src="/lightbox-item.xhtml"></ui:include>
</p:outputPanel>
<p:outputPanel
rendered="#{!restaurantMenuBean.needLightbox(item)}">
<ui:include src="/nolightbox-item.xhtml"></ui:include>
</p:outputPanel>
</ui:repeat>
</h:panelGroup>
</p:outputPanel>
</ui:repeat>
</div>
</h:body>
</f:view>
</html>
This is the related area of html source output, which tells me, my "menu-item-container" is right at the root and the update-attribute only needs a separation marker ":" in front of its id.
<div id="menu-item-container"><span id="j_idt17:0:j_idt64"></span><span id="j_idt17:1:j_idt64"><div id="j_idt17:1:pangroup">
<div class="some-heading">

The to-be-updated components are resolved using the algorithm as described in UIViewRoot#findComponent(). It should be obvious that it can find fullworthy JSF components only.
Your menu-item-container is however a plain HTML <div> element and thus unavailable in the JSF component tree.
Replace it by a fullworthy JSF component.
<h:panelGroup id="menu-item-container" layout="block">
The <h:panelGroup> renders by default a <span> and the layout="block" turns it into a <div>.

Related

Ajax doesn't invoke the method on Managed Bean from selectOneMenu valueChanged item

I'm trying to invoke an method to update an outputLabel after changing the value selected on my SelectOneMenu. I've already tried all the questions that was answered here, but it's not working. The method on my Managed Bean is not being invoked, I tried to print something on console and doesn't work. There's no Exceptions. I've found this answer
commandButton/commandLink/ajax action/listener method not invoked or input value not updated
but I don't know if I'm missing something, probably I've already checked all the adressed points in the answer.
My SelectOneMenu code is
<h:selectOneMenu id="creditos" value="#{comprarCreditoBean.quantidadeCreditos}" required="true" requiredMessage=" *Campo obrigatório!">
<f:selectItem itemLabel="Selecione uma opção" noSelectionOption="true"/>
<f:selectItem itemValue="30" itemLabel="30 Créditos" />
<f:selectItem itemValue="60" itemLabel="60 Créditos" />
<f:selectItem itemValue="90" itemLabel="90 Créditos" />
<f:selectItem itemValue="120" itemLabel="120 Créditos" />
<f:ajax event="change"
execute="formulario"
render="valPagamento"
listener="#{comprarCreditoBean.tratarMudancaCreditos}"/>
</h:selectOneMenu>
<br />
</h:panelGroup>
<h:message class="mensagens" for="creditos" />
<h:outputLabel value="Total a Pagar: "/>
<h:outputLabel id="valPagamento" value="#{comprarCreditoBean.valorPagamento}" required="true" requiredMessage=" *Campo obrigatório!">
<f:convertNumber currencySymbol="R$" type="currency"/>
</h:outputLabel>
The master template is using the <h:head> and the selectOneMenu is already inside a <h:form> component.
On my ManagedBean the following method should be invoked:
public void tratarMudancaCreditos(AjaxBehaviorEvent evento){
System.out.println("Hi");
System.out.println(this.quantidadeCreditos);
if(this.quantidadeCreditos == 30){
this.valorPagamento = 1.0;
}else if(this.quantidadeCreditos == 60){
this.valorPagamento = 2.0;
}else if(this.quantidadeCreditos == 90){
this.valorPagamento = 3.0;
}else if(this.quantidadeCreditos == 120) {
this.valorPagamento = 4.0;
}
}
I'm really worried about the way I'm trying to update the value that should be updated on my page, if the method is not being invoked, nothing I'm doing inside it would work.
I'm using Tomcat 8.0 and JSF 2.0 if it's relevant
#Edit1
I'm using a template, so I'm posting a relevant code from my template.
First, on the page where's the SelecteOneMenu is situated, I have the following code just to identify that I'm using template.
<ui:composition template="/Template.xhtml"
xmlns:jsp="http://java.sun.com/JSP/Page"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:b="http://bootsfaces.net/ui"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html" version="2.0">
In the same page, I have
<ui:define name="corpo-da-pagina">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"><span class="tituloPanel">Comprar Créditos</span></h3>
</div>
<div class="panel-body" align="center">
<h:form id="formulario">
<h:panelGrid columns="3">
<h:outputLabel value="Quantidade de Créditos (1 Minuto = 1 crédito): "/>
<h:panelGroup>
<h:selectOneMenu id="creditos" value="#{comprarCreditoBean.quantidadeCreditos}" required="true" requiredMessage=" *Campo obrigatório!">
<f:selectItem itemLabel="Selecione uma opção" noSelectionOption="true"/>
<f:selectItem itemValue="30" itemLabel="30 Créditos" />
<f:selectItem itemValue="60" itemLabel="60 Créditos" />
<f:selectItem itemValue="90" itemLabel="90 Créditos" />
<f:selectItem itemValue="120" itemLabel="120 Créditos" />
<f:ajax event="change"
execute="formulario"
render="valPagamento"
listener="#{comprarCreditoBean.tratarMudancaCreditos}"/>
</h:selectOneMenu>
<br />
</h:panelGroup>
<h:message class="mensagens" for="creditos" />
<h:outputLabel value="Total a Pagar: "/>
<h:outputLabel id="valPagamento" value="#{comprarCreditoBean.valorPagamento}" required="true" requiredMessage=" *Campo obrigatório!">
<f:convertNumber currencySymbol="R$" type="currency"/>
</h:outputLabel>
<h:commandButton class="btn btn-default" value="Comprar" action="#{comprarCreditoBean.efetuarCompra}"/>
<h:button class="btn btn-default" value="Voltar" outcome="paginaPrincipal"/>
</h:form>
This is basically the construction from my page, other things are fine.
My template.xhtml is defined on this code:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:b="http://bootsfaces.net/ui"
xmlns:h="http://java.sun.com/jsf/html" version="2.0">
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<meta name="viewport" content="width=device-width" />
<!-- CSS -->
<link rel="stylesheet" type="text/css" href="resources/css/estilo.css" />
<link rel="stylesheet" type="text/css" href="resources/css/bootstrap.min.css" />
<link rel="stylesheet" type="text/css" href="resources/css/bootstrap.css" />
<!-- JS -->
<script src="resources/js/jquery.js"></script>
<script src="resources/js/bootstrap.min.js"></script>
<!-- Ícone Navegador -->
<link href="resources/imagens/icone.png" rel="shortcut icon" type="image/x-icon" />
<title>e-BlueCard</title>
</h:head>
<h:body>
<f:view>
<div id="header" align="center">
<ui:include src="/menu.xhtml" />
</div>
<ui:insert name="corpo-da-pagina">Conteúdo</ui:insert>
<div class="well well-sm" align="center">
<div id="footer" align="center">
<span id="rodape">2016. Análise e Desenvolvimento de Sistemas - e-blue Card. Todos os direitos reservados.</span>
</div>
</div>
</f:view>
</h:body>
#Edit 2
I've found an interesting thing. I've tried to open on Chrome browser, and using the F12 to see the console, always when I tried to change the value from the SelectOneMenu, the console from browser shows the following error:
Error caught by Chrome
You should replace <jsp:root ...> in your template with <html ...></html> like this
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
OTHER LIBRARIES HERE
>
<h:head>
HEADER CONTENT HERE
</h:head>
<h:body>
BODY CONTENT HERE
</h:body>
</html>
Here is a link that can help you understand JSF templates

Can't render elements in another form from inside a jQuery-tabs dynamically loaded tab

i have main page as that contains interests composite component and links for lazy loaded tabs as follows:
1- profile page:
<?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 template="../templates/application.xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:o="http://omnifaces.org/ui"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:myapp="http://java.sun.com/jsf/composite/component"
xmlns:p="http://java.sun.com/jsf/passthrough">
<ui:define name="head">
<title>Profile</title>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<link rel="stylesheet" type="text/css" href="#{request.contextPath}/resources/assets/css/jquery/jquery-ui.css" media="screen"/>
<link rel="stylesheet" type="text/css" href="#{request.contextPath}/resources/assets/css/override-jquery.css" media="screen"/>
<style>
li
{
outline: none !important;
}​
</style>
</ui:define>
<ui:define name="right-side">
<div class="three-column right">
<myapp:interest bean="#{interestBean}" value="#{interestBean.interest}" id="interestCmp"></myapp:interest>
</div>
</ui:define>
<ui:define name="content">
<div class="tabs">
<ul>
<li><a id="tab1" href="tabs/tab1.xhtml">tab1</a></li>
<li><a id="tab2" href="tabs/tab2.xhtml">tab2</a></li>
</ul>
</div>
<script type="text/javascript">head.ready(function(){$('.tabs').tabs();});</script>
</ui:define>
</ui:composition>
2- interests composite component:
<?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:ui="http://java.sun.com/jsf/facelets" xmlns:composite="http://java.sun.com/jsf/composite">
<composite:interface>
<composite:attribute name="id" />
<composite:attribute name="index" />
<composite:attribute name="value" />
<composite:attribute name="bean" />
</composite:interface>
<composite:implementation xmlns:myapp="http://java.sun.com/jsf/composite/component">
<div >
<aside class="interests">
<header class="header-w-flag icon-star">
<h1>Interests</h1>
</header>
<h:form id="interestForm">
<h:panelGroup id="showInterests" layout="block">
<ui:repeat var="interest" value="#{interestBean.getUserInterests()}" >
<div class="interest">
<div class="interest-name">#{interest.interestName}
<h:commandLink action="#{interestBean.deleteInterest(interest)}" rendered="#{permissionBean.isCurrentUser(profileBean.user)}" >
<i class="icon-delete control-icon" style="cursor:pointer;display:none;"></i>
<f:ajax render="#form" execute="#this"></f:ajax>
</h:commandLink></div>
<div class="people-grid">
<ui:repeat var="user" value="#{interestBean.getUsersByInterest(interest.id)}" varStatus="status" >
<h:panelGroup id="interestedUsers">
<a title="#{user.firstName} #{user.lastName}" href="../profile/index.xhtml?id=#{user.id}"><img src="#{applicationBean.avatarBaseURL}#{user.avatarUrl}" alt="#{user.firstName}" /></a>
</h:panelGroup>
</ui:repeat>
</div>
</div>
</ui:repeat>
</h:panelGroup>
</h:form>
</aside>
</div>
</composite:implementation>
</html>
3- the tab1 code:
<?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"
xmlns:o="http://omnifaces.org/ui"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:myapp="http://java.sun.com/jsf/composite/component"
xmlns:p="http://java.sun.com/jsf/passthrough">
<div id="tab1">
<!-- feed here -->
<h:panelGroup layout="block" class="posts" id="feedContainer">
<h:form id="profileFeeds">
<ui:repeat var="post" value="#{feedBean.feeds}" varStatus="status" >
<myapp:feedpost value="#{post}" index="{status.index}"></myapp:feedpost>
</ui:repeat>
<h:panelGroup layout="block" rendered="#{feedBean.feeds.size()==0}">
<div class="post blue">
<div class="post-content">
<h1>Nothing</h1>
</div>
</div>
</h:panelGroup>
<div class="post load"><h:commandLink action="#{feedBean.getMoreHomeFeeds()}" styleClass="btn btn-primary btn-small">Show more feeds
<f:ajax render=":feedContainer" ></f:ajax>
</h:commandLink></div>
</h:form>
</h:panelGroup>
</div>
</html>
4- feedpost composite component that is linked from tab1:
<?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:ui="http://java.sun.com/jsf/facelets" xmlns:composite="http://java.sun.com/jsf/composite">
<composite:interface>
<composite:attribute name="id" />
<composite:attribute name="index" />
<composite:attribute name="value" />
</composite:interface>
<composite:implementation xmlns:myapp="http://java.sun.com/jsf/composite/component">
<h:panelGroup layout="block" class="post">
<div class="post-content">
<h:panelGroup layout="block">
<h1><h:outputFormat value="#{cc.attrs.value.title}" /></h1>
</h:panelGroup>
tText value="#{baseBean.replaceWithHTMLBreak(cc.attrs.value.note)}" escape="false"/></p>
</h:panelGroup>
</div>
<myapp:comments value="#{cc.attrs.value}"></myapp:comments>
</h:panelGroup>
</composite:implementation>
</html>
5- comments composite component that is linked from feedpost component:
<?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:ui="http://java.sun.com/jsf/facelets" xmlns:composite="http://java.sun.com/jsf/composite">
<composite:interface>
<composite:attribute name="id" />
<composite:attribute name="index" />
<composite:attribute name="value" />
</composite:interface>
<composite:implementation>
<h:panelGroup layout="block" class="comments" id="feedcomments">
<div class="actions">
<h:commandLink id="addToInterestLink" value="#{msg['action.addto.interests']}" styleClass="action-like"
action="#{feedBean.addToInterests(cc.attrs.value)}">
<f:ajax execute="#this" render=":interestCmp:interestForm:showInterests"></f:ajax>
</h:commandLink>
</div>
</h:panelGroup>
</composite:implementation>
</html>
when clicking on tab1 link (lazy loaded jquery tab) that contains the comments composite component that has the link to render interests div in interest component, i am getting following exception:
<f:ajax> contains an unknown id ':interestCmp:interestForm:showInterests' - cannot locate it in the context of the component addToInterestLink
NOTE: one workaround i have found for the issue is to add the tab1 content statically to the page instead of linking it.
please advise how to fix that.
Okay, in a nutshell and somewhat simplified (composite components actually don't play a role in the problem), your problem is here:
profile.xhtml:
<my:composite id="interestCmp"> <!-- Yes, invalid code; just to summarize. -->
<h:form id="interestForm">
<h:panelGroup id="showInterests">
...
</h:panelGroup>
</h:form>
</my:composite>
<div class="tabs">
<ul>
<li><a id="tab1" href="tabs/tab1.xhtml">tab1</a></li>
<li><a id="tab2" href="tabs/tab2.xhtml">tab2</a></li>
</ul>
</div>
<script>head.ready(function(){$('.tabs').tabs();});</script>
And somewhere in tab1.xhtml
<h:form id="profileFeeds">
<h:commandLink value="Add">
<f:ajax render=":interestCmp:interestForm:showInterests" />
</h:commandLink>
</h:form>
You're thus using jQuery UI tabs to have a tabbed panel with dynamic content. However, the tab page tab1.xhtml doesn't share the same JSF view as the main page profile.xhtml. It are physically completely distinct views. That totally explains why the <f:ajax> couldn't find the desired component in the component tree (the current view). It can only see components which are contained in tab1.xhtml itself. It doesn't see those of profile.xhtml. It can't even see those in tab2.xhtml.
It will only work if you preload tabs by <ui:include> instead of dynamically load them. This way the tab1.xhtml will physically end up in the same view as the desired component. Let's assume that you only need to do that for tab1.xhtml and the tab2.xhtml can be kept dynamically loaded. This should then solve your problem:
<div class="tabs">
<ul>
<li><a id="tab1" href="#tab1_page">tab1</a></li>
<li><a id="tab2" href="tabs/tab2.xhtml">tab2</a></li>
</ul>
<div id="tab1_page">
<ui:include src="tabs/tab1.xhtml" />
</div>
</div>
You only need to replace the <?xml...?><!DOCTYPE ...><html xmlns...> and </html> of tab1.xhtml (and actually also tab2.xhtml) by <ui:composition xmlns...> and </ui:composition> respectively. Because otherwise you end up in syntactically invalid HTML.
If you really need to have dynamically/lazily loaded tabs, then you'd better look for a fullworthy JSF component capable of the job, such as PrimeFaces <p:tabView>. Even more, PrimeFaces uses jQuery/UI under the covers for the look'n'feel, so many things will be very simliar to the current approach.

jsf ajax rendered does not work

I would like to ask why partial rendering for primefaces does not work. POST requests are keeping sent, but it does not rerender.
<?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:p="http://primefaces.org/ui">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<p:messages />
<h:form>
<table style="width: 100%">
<tr>
<td><p:outputLabel for="inp1" value="S1" /></td>
<td>
<p:inputText id="inp1" value="#{form.e.s1}">
<p:ajax process="inp1" update="msg1"
event="keyup" />
</p:inputText>
<p:watermark for="inp1" value="Wpisz S1" />
<p:message for="inp1" id="msg1" />
</td>
</tr>
<tr>
<td>Toolbox</td>
<td>
<p:selectBooleanCheckbox id="inpToolbox" value="#{form.toolbox}">
<p:ajax process="inpToolbox" update="toolboxOptions" />
</p:selectBooleanCheckbox><br />
<p:panel id="toolboxOptions" rendered="#{form.toolbox}">
Name: <p:inputText value="#{form.toolboxDescription}" /><br />
Number: <p:inputText value="#{form.toolboxNr}" /><br />
</p:panel>
</td>
</tr>
</table>
<p:commandButton action="#{form.save}" ajax="false"
value="Save" />
</h:form>
</h:body>
</html>
I have no idea, why it should not work. I want every time changes the toolbox value to show the additional information form about toolbox
When you would like to update some part of the view you have to specify an id of an element which is actually present in the DOM. But the panel you are trying to update is not always present in the DOM, only in the case that form.toolbox evaluates to true. So when it is false it cant be updated and so it will not be added to the view.
What you can do to solve this problem is, to wrap the panel inside another element and update that element. This will work because the wrapper-element is always present.
So try the following for the part of the panel:
<h:panelGroup id="toolboxOptions">
<p:panel id="toolboxOptionsPanel" rendered="#{form.toolbox}">
....
</p:panel>
</h:panelGroup>
Have a look at to answer of the following question for further explanation:
JSF + PrimeFaces: `update` attribute does not update component

<f:ajax> contains an unknown id when switching from PrimeFaces to jsf/html

this is my 1st question here :)
My code is as follows:
<?xml version="1.0"?>
<f:view 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:p="http://primefaces.org/ui"
>
<h:head />
<h:body>
<h:form id="filterForm">
<h:outputStylesheet library="css" name="main.css" />
<div id="filterPane">
<h:panelGroup rendered="#{not empty filters.categories}">
<div class="filter">
<div class="filterCategories" style="width: 100%;">
<h4>Kategorien</h4>
<p />
<h:selectManyCheckbox layout="pageDirection"
value="#{filters.selectedCategories}"
valueChangeListener="#{filters.categoryValueChanged}">
<f:selectItems value="#{filters.categories}" var="category"
itemLabel="#{category.displayName} (#{category.count})"
itemValue="#{category.name}" />
<f:ajax render="#form" />
</h:selectManyCheckbox>
</div>
</div>
</h:panelGroup>
</div>
</h:form>
</h:body>
</f:view>
I get the same error as some others before me here #stackoverflow - but none of the suggested solutions worked for me.:
<f:ajax> contains an unknown id 'A5539:filterForm:j_idt9' - cannot locate it in the context of the component j_idt9
Before my switch from <p:selectManyCheckbox to <h:selectManyCheckbox the code was working fine.
We need to change to <h:selectedManyCheckbox, because the PrimeFaces variant is not selectable for a non-JavaScript user. I need the form <h:form id="filterForm"> to be re-rendered as a consequence of my AJaX request via the <f:ajax> element.
Beside the initial <f:ajax render="#form" /> I unsuccessfully tried to reference the <h:form id="filterForm"> element with the following variants:
<f:ajax render=":filterForm" />
<f:ajax render=":#{component.parent.parent}" />
I also tried some more stupid ones.
Any hint, anybody!? :)

Ajax-render a table which is inside a different form

I am facing a problem rendering a data table when selecting a date from <rich:calendar>. I use <a4j:ajax> for the rendering but with no effect. Here is the code sample:
<!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:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:rich="http://richfaces.org/rich"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:composite="http://java.sun.com/jsf/composite">
<rich:panel header="#{lang.reportPanelHeader}" id="panel" rendered="#{navigation.reportRendered}" width="700px" style="margin-left:250px">
<a4j:status onstart="#{rich:component('statPane')}.show()" onstop="#{rich:component('statPane')}.hide()" />
<h:form id="data_table_form">
<rich:dataTable value="#{validateReportAction.reportList}" var="report" iterationStatusVar="it" id="data_table" rows="5">
<rich:column>
<f:facet name="header">#</f:facet>
#{it.index + 1}
</rich:column>
<rich:column>
....
</rich:column>
<f:facet name="footer">
<rich:dataScroller page="#{validateReportAction.page}" />
</f:facet>
</rich:dataTable>
</h:form>
<rich:popupPanel id="statPane" autosized="true" style="border: none; background-color: #e6e6e6;">
....
</rich:popupPanel>
<div id="bottom">
<h:form id="calendarForm">
<div id="left">
<div class="input" id="test_cal">
<rich:calendar
dataModel="#{calendarModel}"
value="#{validateReportAction.selectedDate}"
boundaryDatesMode="scroll"
required="true"
requiredMessage="#{lang.dateRequiredMsg}"
mode="ajax"
id="date"
datePattern="dd.MM.yyyy"
popup="false">
<a4j:ajax event="change" render="#all"/>
</rich:calendar>
<span class="error_msg">
<rich:message for="date" ajaxRendered="true"/>
</span>
</div>
</div>
</h:form>
</div>
</rich:panel>
</ui:composition>
I am forced to use #all in the calendar in <a4j:ajax event="change" render="#all"/> but I want to render only the data table. How can I do this?
Since it's located in a different naming container parent, you need to refer it by its absolute client ID. To find it out, open the page in the webbrowser. Rightclick and View Source. Locate the HTML <table> element which is generated by <rich:dataTable id="data_table">. It'll look something like this:
<table id="data_table_form:data_table">
You need to take exactly that ID, prefix with the JSF naming container separator character (which defaults to :) and use it in the render attribute.
<a4j:ajax event="change" render=":data_table_form:data_table" />
See also:
How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar"

Resources