Jsf2 ajax render id not found - ajax

Why i get " contains an unknown id ':commentTextArea' - cannot locate it in the context of the component commentLink" error?
majorra 2.1.7
How i can render commentTextArea.
<ui:repeat var="parentComment" value="#{commentTree.parentCommentsWrapper}"> ....
<h:form>
<h:commandLink id="commentLink" value="comment"
style="height:20px;width:20px;padding: 0; margin: 0;"
action="#{parentComment.changeEditable}">
**<f:ajax render=":commentTextArea"></f:ajax>**
</h:commandLink>
</h:form> <h:panelGroup id="commentTextArea">
<br />
<h:panelGroup rendered="#{parentComment.editable}">
<h:form >
<h:inputTextarea rows="2" cols="20"
value="#{commentTree.newCommentText}"
style="font-family:Arial,Helvetica;font-size:12px;width:365px;margin-right: 4px;margin-left: -1px;">
</h:inputTextarea>
<h:commandButton id="newCommentButton" value="+"
style="height:20px;width:20px;padding: 0; margin: 0;"
action="#{commentTree.saveChildComment(parentComment.comment)}" >
</h:commandButton>
</h:form>
</h:panelGroup>
</h:panelGroup>
</ui:repeat>
'

The id :commentTextArea is an absolute id and relative to the view root. However, ui:repeat is a NamingContainer and "wraps" your commentTextArea. (Check the html source in browser to see what id is generated)
A simple solution would be to use only one form in your 'ui:repeat'. Then the relative id with
<f:ajax render="commentTextArea">
(without :) would work.

Related

how i get clicked CommandLink id in Controller in JSF?

<ui:repeat value="#{prodCtr.paginator.model}" var="o">
<h:form>
<h:commandLink id="#{o.id}" action="ModelInfo.xhtml" actionListener="#{prodCtr.listener}">
<h:panelGrid columns="1" style="border: #ffffff">
<img src="resources/images/#{o.id}.jpg" style="width: 100px;height: 100px"/>
<h:outputLabel value="#{o.price} YTL" style="font-size: 12px;font-family: Georgia, Serif;color: #ff3300" />
<h:commandButton value="Sifaris et" class="button"/>
</h:panelGrid>
</h:commandLink>
</h:form>
</ui:repeat>
java.lang.IllegalArgumentException caught during processing of RENDER_RESPONSE 6 : UIComponent-ClientId=, Message=Empty id attribute is not allowed here
How can i CommandLink id dinamically?Is there an other way?
You don't need to specify the id attribute for the child components when using the <ui:repeat/> tag. It automatically does this.
If you do want to be in control of the id attribute, <ui:repeat/> is the wrong one to use for that. The reason is that at point in time that the components are being placed in the UIViewroot (essentially when the page is being constructed for the first time), the <ui:repeat/> component is not active, i.e. it's not being processed. So the var="o" is not available to the runtime and so nothing is available to be used as id.
To be in control of the id, you should be using the <c:forEach/> tag instead. Your code should look like this:
<c:forEach items="#{prodCtr.paginator.model}" var="o">
<h:form>
<h:commandLink id="#{o.id}" action="ModelInfo.xhtml" actionListener="#{prodCtr.listener}">
<h:panelGrid columns="1" style="border: #ffffff">
<img src="resources/images/#{o.id}.jpg" style="width: 100px;height: 100px"/>
<h:outputLabel value="#{o.price} YTL" style="font-size: 12px;font-family: Georgia, Serif;color: #ff3300" />
<h:commandButton value="Sifaris et" class="button"/>
</h:panelGrid>
</h:commandLink>
</h:form>
</c:forEach>

Ajax not working with primefaces

In my JSF page I have form when I click submit button in the same page I need to show an static content. But When I click <p:commandbutton> nothing appears in the page. When I put ajax="false" then only action taken place but the Static content display in new page.
In my Backing bean I have used Session scoped. I am using JSF 2.0 and Primefaces 3.2.
My JSF Page.
<h:form>
<h:panelGroup rendered="#{not license.showForm}">
<p:panel header="License Key Request" >
<h:panelGrid columns="2" >
..
<h:outputText value="Bla bla"/>
..
<h:outputText value="Bla Bla" />
</h:panelGrid>
<TABLE>
..
<h:outputLabel for="name" value="Requestor Name : *" />
..
<p:inputText id="name" value="#{license.name}" required="true" requiredMessage="Name is required."/>
..
<h:outputLabel for="company" value="Company : * " />
..
<p:inputText id="company" value="#{license.company}" required="true" requiredMessage="Company is required."/>
..
</table>
<p:commandButton value="Form" id="btnAdd" process="#form"
action="#{license.add}" />
..
</table>
</p:panel>
</h:panelGroup>
<h:panelGroup rendered="#{license.showForm}" >
<h:outputText value="Bla Bla"/>
</h:panelGroup>
</h:form>
Your source code is somewhat confusing (e.g. you have two closing table tags). But I assume that you want to show the panelGroup at the bottom if the button is clicked.
The easiest way would be to add an update ="#form" to your commandButton:
<p:commandButton value="Form" id="btnAdd"
process="#form" update="#form"
action="#{license.add}" />
You don't need to update the whole form but only the specific component. Then you need to give the panelGroup an id attribute and use this attribute instead of #form. However, since it is not clear for me how your naming containers are organized, it could be puzzling to find the correct relative id.

Click event on div in JSF2

I have a list represented by a ui:repeat, where each item is a div with some data. What I want is to show the item detail by clicking on the div.
I made it with a button refreshing the form but can't make it work with onclick event on panelGroup.
<h:panelGroup styleClass="container" layout="block">
<ui:repeat value="#{bean.model}" var="item">
<h:panelGroup styleClass="item_data" layout="block">
ID: #{item.id}
<h:commandButton action="#{bean.select}" value="Select item">
<f:param name="itemId" value="#{item.id}"/>
<f:ajax render="#form"></f:ajax>
</h:commandButton>
</h:panelGroup>
<h:panelGroup styleClass="detail"
layout="block"
rendered="#{item eq bean.selected}">
value: #{bean.selected.value}
</h:panelGroup>
</ui:repeat>
</h:panelGroup>
If I understand you correctly, you just want to show the detail section without re-rendering the whole form? If so, then wrap it in a component which is always rendered in the HTML DOM tree, give it an id and refer it instead:
<ui:repeat value="#{bean.model}" var="item">
<h:panelGroup styleClass="item_data" layout="block">
ID: #{item.id}
<h:commandButton action="#{bean.select}" value="Select item">
<f:param name="itemId" value="#{item.id}"/>
<f:ajax render="detail" />
</h:commandButton>
</h:panelGroup>
<h:panelGroup id="detail">
<h:panelGroup styleClass="detail"
layout="block"
rendered="#{item eq bean.selected}">
value: #{bean.selected.value}
</h:panelGroup>
</h:panelGroup>
</ui:repeat>
See also:
Communication in JSF 2.0 - Ajax rendering of content which is by itself conditionally rendered
Update: as per the comments, you actually want to invoke JSF ajax action by <h:panelGroup onclick> no, that's not possible as it doesn't support onclick attribute. You could use a <div> with jsf.ajax.request() function, but cleaner would be to use a <h:commandLink> with CSS display: block so that it spans the entire div.
<h:panelGroup styleClass="item_data" layout="block">
<h:commandLink action="#{bean.select}" value="ID: #{item.id}" styleclass="detailLink">
<f:param name="itemId" value="#{item.id}"/>
<f:ajax render="detail" />
</h:commandLink>
</h:panelGroup>
with e.g.
.detailLink {
display: block;
color: black;
text-decoration: none;
}

Component ID in ui:repeat problems

I'm trying to render a grandparent component.
The code:
<h:form prependId="false>
<h:panelGroup id="outer_panel">
<ui:repeat var="curr" value="#{bean.map}">
<h:panelGroup id="inner_panel">
<h:commandButton value="Remove" action="actionThing" >
<f:ajax render="outer_panel" />
</h:commandButton>
</h:panelGroup>
</ui:repeat>
</h:panelGroup>
</h:form>
I get an exception:
javax.faces.FacesException: Component with id:outer_panel not found
Tried to add the index to the id, which didn't work neither:
<h:form prependId="false>
<h:panelGroup id="outer_panel">
<ui:repeat var="curr" value="#{bean.map}" varStatus="loop">
<h:panelGroup id="inner_panel">
<h:commandButton value="Remove" action="actionThing" >
<f:ajax render="#{loop.index+1}:outer_panel" />
</h:commandButton>
</h:panelGroup>
</ui:repeat>
</h:panelGroup>
</h:form>
Any idea why the ID is not found?
Thanks.
It is not found because you used a relative client ID in render attribute. It becomes relative to the closest parent naming container component. In this case, that's the <ui:repeat> (it prepends generated client ID of the children with the row index). So the component with ID outer_panel has to be inside the <ui:repeat> in order to get it to work. However, the outer_panel is actually outside it.
You need to specify an absolute client ID instead of a relative client ID. To make it absolute (so that it will basically scan from the view root on), prefix the client ID with :.
<f:ajax render=":outer_panel" />
For the case that you didn't use prependId="false" on the <h:form>, then you should have used
<f:ajax render=":form_id:outer_panel" />
instead.

JSF and ajax: listener of dynamically added component never tirggered

I have got a problem with my JSF application.
On a page there's a form where the user can dynamically add components to that very same form. When I use the ajax listener to add the component, it is updated in the view and also in the model. But when I try to remove the dynamiccaly added component by pressing an h:actionLink its ajax listener is never triggered.
This is my code:
<h:form rendered="#{schrijvenController.verslagenController.documentSelected}">
<p>
<span class="noLabel">
#{bundle.JongereJongere}:
</span>
<h:selectOneMenu id="jongereSelect" valueChangeListener="#{schrijvenController.selecteerJongere}" immediate="true"
value="#{schrijvenController.currentJongere.jongereID}"
title="--#{bundle.JongereSelect}--">
<f:selectItems value="#{jongereController.jongerenAsSelectItems}"/>
</h:selectOneMenu>
</p>
<h:panelGroup id="personen">
<ui:repeat value="#{schrijvenController.verslagenController.persoonItems}" var="persoon">
<div class="div_add_persoon">
<div class="div_add_persoon_left">
<span class="noLabel"> #{persoon.aanwezigheid}:</span>
<h:inputText value="#{persoon.searchTerm}"
onkeypress="if (event.keyCode == 13) { onchange(); return false; }">
<f:ajax event="keypress" render="persoonLijst" listener="#{persoon.getPersonenWhereNameLikeSelectItems}" />
</h:inputText>
<h:selectOneMenu id="persoonLijst" styleClass="fixedWitdhDropDown"
value="#{persoon.currentPersoon.persoon_id}"
title="--#{bundle.PersoonSelect}--">
<f:selectItems value="#{persoon.personenWhereNameLikeSelectItems}"/>
<f:ajax event="change" render="#form" listener="#{persoon.add}" />
</h:selectOneMenu>
</div>
<h:panelGroup layout="block" styleClass="div_add_persoon_right">
<ui:repeat value="#{persoon.personen}" var="persoonPersoon">
<h:panelGroup layout="block" styleClass="div_schrijvenPersoon">
<h:outputText value=" #{persoonPersoon.naam} #{persoonPersoon.voornaam} " />
<h:commandLink value="X" id="linkske">
<f:ajax event="click" render="#form" listener="#{persoon.delete}" />
</h:commandLink>
</h:panelGroup>
</ui:repeat>
</h:panelGroup>
</div>
</ui:repeat>
<div class="clear" />
This is a Prt Sc of my view:
http://i206.photobucket.com/albums/bb69/bartloterman/pscreen.jpg?t=1302028364
If one clicks on an element from the list, it's added to the right inside a div together with a commandLink with the text "x". But when I click the "x" link nothing happens (no function is being executed). It is as if the view can't find the component. I'm using Datamodels.
I've been looking all day for a solution on the web but I couldn't find one. Any help would be greatly appreciated.
I managed to solve the problem by using the following code in my view
<h:commandLink value="X">
<f:ajax render="#form" execute="#form" listener="#{persoon.delete}" />
</h:commandLink>
Seems I needed render="#form" and execute="#form"

Resources