Primefaces 8.0 JSF not updating table [duplicate] - jsf

This question already has answers here:
How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar"
(6 answers)
Closed 2 years ago.
When I click addTagButton, everything works well. It updates all three components: tags, tagId and addTagButton.
<p:commandButton id="addTagButton" icon="ui-icon-plus"
action="#{searchBean.addTag}"
update="tags, tagId, addTagButton"
disabled="#{searchBean.tagChoices.size() == 0}">
</p:commandButton>
Here's the table component:
<h:dataTable id="tags" var="tag" value="#{searchBean.tags}">
<h:column>
<div style="text-align:right;">
<h:outputLabel value="#{tag.typeName}:"/>
</div>
</h:column>
<h:column>
<p:inputText id="tag" size="25" value="#{tag.typeValue}"
disabled="#{searchBean.searchForParent}"/>
</h:column>
<h:column>
<p:commandButton id="delTagButton" icon="pi pi-trash"
action="#{searchBean.deleteTag}"
update=":contentForm:tagId, :contentForm:addTagButton, tags">
<f:setPropertyActionListener
target="#{searchBean.tagId}"
value="#{tag.typeName}" />
</p:commandButton>
</h:column>
</h:dataTable>
When i click on delTagButton that is on each row in tags table, action works fine, :contentForm:tagId and :contentForm:addTagButton update fine. But tags table which is where clicked command button exist, does not update.
When a row is deleted, change must reflect in the tags table which does not work.
Now, If I change h:dataTable to p:dataTable or any other primefaces component, it works. I am trying to make it work with h:dataTable.
Primefaces 8.0, JSF 2.5

Look on this simple example:
<h:form id="form">
<h:panelGroup id="wrapper" layout="block">
<h:dataTable id="table" border="1" value="#{testBean.list}" var="person">
<h:column>#{person.name}</h:column>
<h:column>#{person.surname}</h:column>
<h:column>
<p:commandButton id="delTagButton" icon="pi pi-trash"
action="#{testBean.remove(person)}" update="table">
</p:commandButton>
</h:column>
</h:dataTable>
</h:panelGroup>
</h:form>
To really find out what is being updated look in browser console.
If you're trying to update="table" nothing happens (like in your code). If you try to update a parent of the table (which is often a case), you will get an error an error:
SEVERE: Error Rendering View[/example.xhtml]
org.primefaces.expression.ComponentNotFoundException: Cannot find component for expression "wrapper" referenced from "form:table:0:delTagButton".
at org.primefaces.expression.SearchExpressionFacade.cannotFindComponent(SearchExpressionFacade.java:677)
So we could try with "older" parent and realize that update="#form" works! OK, so we want to help to find id="table\wrapper" component. Let try clientId update="form:table". Like with update="table" nothing happens. And no error from PF (so the element can be found). This could mean that h:dataTable cannot be properly re-rendered from inside itself (but I don't want to throw stones:-)). This is often a case with e.g. popups in JSF 3rd party component libraries.
In this particular example I'd say, you have to update form:wrapper (adding form: works) or just #form to get it work. With your code it would be the same. Try to update some table parent or the whole form.
All of above is tested in JSF 2.2, with last RF, an old PF and OmniFaces. But I think the same would be the case with newer versions.
BTW. I didn't know there is JSF 2.5 :-)

Related

<rowExpansion> evaluated during JSF phases

I have a datatable using rowExpansion.
When the page is loaded, the rowExpansion is not evaluated, which is fine.
When the paginator is used to show the next results or if a submission is done - the rowExpansion evaluation is triggered.
Here is a XHTML example :
<h:form>
<p:dataTable var="data" value="#{bean.dataList}" paginator="true">
<p:column headerText="Details">
<p:rowToggler />
</p:column>
<p:rowExpansion>
<h:panelGroup rendered="#{not empty data.detail}">
<ui:include src="dataDetail.xhtml" />
</h:panelGroup>
</p:rowExpansion>
</p:dataTable>
<h:commandLink id="addData" value="Add data" action="#{bean.addData}" />
</h:form>
I've profiled this flow using visualVM, and used the debugger, to discover that the data.getDetail() method was called during the following JSF phases : (ApplyRequestValuesPhase, ProcessValidationsPhase, UpdateModelValuesPhase), when the paginator was used.
I've come to the deduction that the rowExpansion is part of the view, and is evaluated as a normal component.
Would you mind telling me if it is the expected behaviour for rowExpansion ?
Is there a correct way to prevent the evaluation of the rowExpansion content when using the paginator ?
Thanks for your answers.
NB : I'm using PrimeFaces 5.2.

JSF is not showing component even though the attribute "rendered" evaluates to true

I have a simple JSF page with several tags like this:
...
<h:form>
...
<h:panelGroup id="menuItem1" styleClass="topLevelMenu" layout="block"
rendered="#{MyBean.currentUser.menuAccessible}">
<h:outputText value="Menu 1"/>
</h:panelGroup>
<h:panelGroup id="menuItem2" styleClass="topLevelMenu" layout="block"
rendered="#{MyBean.currentUser.menuAccessible}">
<h:outputText value="Menu 2"/>
</h:panelGroup>
<h:panelGroup id="menuItem3" styleClass="topLevelMenu" layout="block"
rendered="#{MyBean.currentUser.menuAccessible}">
<h:outputText value="Menu 3"/>
</h:panelGroup>
...
</h:form>
...
The rendered condition is "true" (I've verified it with the debugger). What seems strange is that only the second and the third items (Menu 2 and Menu 3) are displayed. The first one, even though it has the same condition for "rendered" as the other two, is not displayed! When I change the first one to rendered="true" then it displays normally.
Any ideas why this could be happening? I have around 15 panelGroups arranged like these in my page (I'm using them to create the menu items for the application).
Note: I'm migrating the application from JSF 1.2 to JSF 2.1. I just made this change t:div (which was correctly working previously) to h:panelGroup layout="block"...

How do update jsf datatable column only

I have a counter in a column of a datatable. Once the counter reaches a certain time, I need to change the background color of that column only. The data for the table is being pulled from a database. I'm using a4j:poll to reRender the column but the issue is that the entire table is rendered. Some code below:
<a4j:region>
<h:form>
<a4j:poll id="poll" interval="1000" enabled="true" reRender="blink" limitToList="true" />
</h:form>
</a4j:region>
<h:form id="form1">
<a4j:outputPanel id="panel1" ajaxRendered="true">
<h:dataTable id="blinks" styleClass="tableClass" value="#{bean.list}" var="_item">
<h:column id="blink">
<f:facet name="header">
<h:outputText value="Header1" />
</f:facet>
<div id="div1" class="#{bean.check() ? 'red' :''}">
<h:outputText value="Counter text (counts seconds)" />
</h:column>
</h:dataTable>
</a4j:outputPanel>
</h:form>
If you meet the following minimum req' JSF 2.0, EL 2.1 and Servlet 2.5
You can try out the Ajax#updateColumn() by Omnifaces , there is an example on how to use it in the showcase
Note that Ajax#updateRow() and Ajax#updateColumn() can only update
cell content when it has been wrapped in some container component with
a fixed ID.
Maybe you can use a push server side events to trigger the update on client side instead of use polling which performs full form.
http://livedemo.exadel.com/richfaces-demo/richfaces/push.jsf?tab=choices&cid=987178
A full description how to use this: Using RichFaces Push and DataTable Ajax Keys for Partial Tables Updates
you should re render by column id, but because you have data which coming from database, and it is a one list, can you confirm what you can do call which real can update one column?

JSF/Primefaces- Action listener on Command button not getting called

I am using JSF2.0 with Prime Faces 3.2. I have a data table with a column that has two command buttons. The second command button is rendered based on a condition. Everything works well until the data table is filtered. Once filtered the first command button without the rendered attribute calls my actionListener without any issues, whereas the second command button with the rendered attribute does not.
PS:The reason i am using f:param intead of setPropertyActionListener is because of a bug in primefaces datatable that passes the wrong row's id when filtered.
Here is my code, any insight into this issue would be great.
<p:column headerText="Column1" filterMatchMode="contains" filterBy="#{item.name}" sortBy="#{item.name}">
<h:outputText value="#{item.name}" style="float:left" />
<span class="inlineButton">
<p:commandButton id="selectBtn" icon="select"
oncomplete="dialog1.show()" actionListener="#{controller.setItem}">
<f:param name="itemId" value="#{item.id}"/>
</p:commandButton>
<p:commandButton id="delBtn" icon="delete"
actionListener="#{controller.setItem}"
oncomplete="delConfirm.show()"
rendered="#{not empty item.id}">
<f:param name="itemId" value="#{item.id}"/>
</p:commandButton>
</span>
</p:column>

Absolute reRendering using RichFaces

My problem is that RichFaces reRender does not work 'under' the current element in the element tree; only upper elements get rerendered.
Is there any way to access lower elements with AJAX?
Any help would be appreciated!
Daniel
EDIT I edited this question to a more general one. See revisions if interested in the original question.
reRender works with providing an the id of the target object you want to reRender (inside the same naming container - form most often)
the id should be a unique string, according to html spec
reRender allows dynamic value - i.e. reRender="#{myBean.currentItemsToRerender}
Based on that I think you should be able to achieve what you want (although it's not entirely clear)
Update:
UIComponent.findComponent(..) has a well-defined algorithm for resolving ids. So for absolute referencing your reRendered id should start with : and then continue through the hierarchy of the naming containers.
Here is an example where changePanel111() changes the content of a lower element:
<h:form id="form" prependId="true">
<rich:panel id="PANEL1">
<h:outputText id="PANEL1TEXT" value="#{ajaxTestBean.panel1}"/>
<rich:panel id="PANEL11">
<h:outputText id="PANEL11TEXT" value="#{ajaxTestBean.panel11}"/>
<rich:panel id="PANEL111">
<h:outputText id="PANEL111TEXT" value="#{ajaxTestBean.panel111}"/>
</rich:panel>
</rich:panel>
<rich:panel id="PANEL12">
<h:outputText id="PANEL12TEXT" value="#{ajaxTestBean.panel12}"/>
<br/>
<a4j:commandLink value="CHANGE PANEL12" action="#{ajaxTestBean.changePanel12}">
<a4j:support reRender="PANEL12" event="onclick"/>
</a4j:commandLink>
<br/>
<a4j:commandLink value="CHANGE PANEL111" action="#{ajaxTestBean.changePanel111}">
<a4j:support reRender="form:PANEL111" event="onclick"/>
</a4j:commandLink>
</rich:panel>
</rich:panel>
</h:form>
Notice how the lower element needs to be identified as form:PANEL111.
Hope this helps!
reRender can point to any component outside the form as well. For example this works:
<h:form>
<a4j:commandButton reRender="panel"/>
</h:form>
<h:panelGrid id="panel">
...
</h:panelGrid>
For my MyFaces+Richfaces App, <rich:panel> tag was not working as described in the selected answer. When I changed it to <a4j:outputPanel ajaxRendered="true" />, it started working as given here "<a4j:commandLink> Not Rerendering"
Configuration: MyFaces 2.1.10(Facelets used for templating) and Richfaces 4.2.3.
Hope this will help.

Resources