h:dataTable renders rows correctly but does not show cell values while ui:repeat does - jsf

I have the following data table.
<h:dataTable value="#{flightReservation.flightList}" var="flight">
<h:column>
<h:outputText value="#{flight.fromPlace}" />
</h:column>
<h:column>
<h:outputText value="#{flight.toPlace}" />
</h:column>
</h:dataTable>
It does not show any data inside the cells, even though the number of rows is equal to the flightList size.
When I replace it by <ui:repeat>, then it shows the data.
<ui:repeat value="#{flightReservation.flightList}" var="value">
<h:outputText value="#{value.fromPlace}" />
<h:outputText value="#{value.toPlace}" />
</ui:repeat>
How is this caused and how can I solve it?

I encountered the same behaviour once and it was simply an issue with the scope of variables:
You are saying, that the number of rows is correct, but the content not displayed. You are naming the variable flight and I assume that a value with this name has been used earlier in your markup or even used as a <ui:param>.
The Datatable is now iterating (internal) and generating the correct amount of rows, but when it tries to access the properties of fligt jsf refers to the earlier declared variable and fails to find the properties fromPlace, toPLace etc.
Try to rename your variable and see if this solves your issue.
The example bellow would produce stringList.size() times yoloyolo even if one would expect the content of the list to be shown. And if the listsource is made out of objects, any instance access on the attributes will fail cause yoloylo is not an object of the expected type.
<ui:param name="foo" value="yoloyolo" />
<h:dataTable value="#{backingBean.stringList}" var="foo">
<h:column>
<f:facet name="header">string</f:facet>
- #{foo}
</h:column>
</h:dataTable>

Related

JSF validation error prevents updating another valid rows of an h:dataTable placed in an h:form

I have an h:dataTable inside of an h:form, where each row has it's own h:commandButton type="submit" action="#{bean.saveChanges(item)}".
f:inputs are declared as required and they also need to match a pattern.
If every input is in the right format, then it works fine.
Otherwise it needs only one input to be wrong and an updating function on a commandButton corresponding to a completely different item in another row seems not to be called, therefore not updated in the database.
Also only the wrong row's validation message is displayed and the changes are maintained in the view by a (backing Spring view scoped) bean, so the user might actually think, that the initial row was indeed updated in the database too.
Is there a way, how to separate individual rows of the h:dataTable, so that the validation messages of another row does not stop other items from being updated by the method of a (Spring/backing) bean?
Use ajax to process/execute only the current row. You can achieve that by explicitly specifying the client IDs of the input components in <f:ajax execute>.
<h:form>
<h:dataTable ...>
<h:column>
<h:inputText id="foo" ... />
</h:column>
<h:column>
<h:inputText id="bar" ... />
</h:column>
<h:column>
<h:inputText id="baz" ... />
</h:column>
<h:column>
<h:commandButton ...>
<f:ajax execute="foo bar baz #this" ... />
</h:commandButton>
</h:column>
</h:dataTable>
</h:form>
This won't process the inputs in other rows. Use if necessary <f:ajax render> to update the <h:message(s)> associated with the inputs.
See also:
Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes
The required on the input cause the Process validation to fail and the render response to be invoked.
A simple solution could be You could remove the required from the input and handle the case in you managed bean. Since the action would move on till Phase 5: Invoke application the valid data can be saved. For all invalid rows highlight the row by having a boolean in you data model.

How do I display a list of items inside a list of items on a JSF page? [duplicate]

<h:dataTable value="#{SearchingBeans.list}" var="entry">
<h:column>
<f:facet name="header">
<h:outputLabel>Photo</h:outputLabel>
</f:facet>
</h:column>
<h:column>
<f:facet name="header">
<h:outputLabel>Pseudo</h:outputLabel>
</f:facet>
<h:outputLabel value="#{entry.pseudo}"></h:outputLabel>
</h:column>
<h:column>
<f:facet name="header">
<h:outputLabel>Description</h:outputLabel>
</f:facet>
<h:outputLabel value="#{entry.description}"></h:outputLabel>
</h:column>
<h:column>
<f:facet name="header">
<h:outputLabel>Photo</h:outputLabel>
</f:facet>
<h:outputLabel value="#{entry.photo[0].path}"></h:outputLabel> <-- this a List
</h:column>
</h:dataTable>
i got a entities member one of his property is a List photo with get/set
that property is populate
i don't know how to fetch that value in jsf i want only the first picture for each member since their have 2-3 photos. Its that possible?? any other solution will be appreciate.
Just iterate over it using <ui:repeat> or <h:dataTable> the usual way. It's perfectly valid to nest multiple iterating components in each other. In case of <h:dataTable>, you only need to make sure that you put the nested iterating component inside a <h:column>.
E.g.
<h:dataTable value="#{bean.entities}" var="entity">
<h:column>
#{entity.property}
</h:column>
<h:column>
<ui:repeat value="#{entity.subentities}" var="subentity">
#{subentity.property}
</ui:repeat>
</h:column>
</h:dataTable>
or
<h:dataTable value="#{bean.entities}" var="entity">
<h:column>
#{entity.property}
</h:column>
<h:column>
<h:dataTable value="#{entity.subentities}" var="subentity">
<h:column>
#{subentity.property}
</h:column>
</h:dataTable>
</h:column>
</h:dataTable>
You'll potentially only run into issues when you nest multiple <ui:repeat> components and use <f:ajax> in it while using an older version of Mojarra.
Only JSTL <c:forEach> wouldn't work when nested inside a JSF iterating component for the reasons explained here JSTL in JSF2 Facelets... makes sense?
Unrelated to the concrete problem, please don't abuse <h:outputLabel> for pure text presentation. It generates a HTML <label> element which is intented to label an input element by for attribute. However, you're doing that nowhere in the code. You should be using <h:outputText> instead. By the way, I'm lately seeing this more often in code of starters. There must be somewhere a bad tutorial or resource which is abusing the <h:outputLabel> this way instead of <h:outputText> or even plain EL in template text. Which tutorial/resource was you using? Then I can contact the author about this severe misinstruction. See also Purpose of the h:outputLabel and its "for" attribute

JSF 2 h:dataTable with inputText values binded to List. Values not updating [duplicate]

This question already has an answer here:
Using <ui:repeat><h:inputText> on a List<String> doesn't update model values
(1 answer)
Closed 7 years ago.
I'm trying to display the data from a List contained in a bean via a datatable, and have actions performed by code as the user types. It initially displays ok, and changes to the List are reflected in UI.
My issue is that values entered into the inputText are ignored. Tried looking for solutions, I've tried checking the List as the values changed, and also tried to check without the ajax in case that was the issue (no change). Have tried using session and view scoped bean without luck. Tried wrapping the Strings in a POJO.
Going crazy here. Feel like I'm missing something obvious. Any idea?
<h:dataTable id="multioptionanswers"
value="#{multiTextBean.texts}" var="texts">
<h:column>
<f:facet name="header">
<h:outputText value="Enter Values"></h:outputText>
</f:facet>
<h:inputText value="#{texts}" immediate="true">
<f:ajax event="blur" execute=":addgroup"
render=":addgroup"
listener="#{multiTextBean.update}" />
</h:inputText>
</h:column>
</h:dataTable>
**addgroup is a panel group that the data table resides in.
Worked it out, needed change to how the inputtext read the data. Solution below in case it helps someone :
<h:dataTable id="multioptionanswers" binding="#{table}"
value="#{multiTextBean.texts}" var="texts">
<h:column>
<f:facet name="header">
<h:outputText value="Enter Values"></h:outputText>
</f:facet>
<h:inputText
value="#{multiTextBean.texts[table.rowIndex]}">
<f:ajax event="blur" execute=":addgroup" render=":addgroup"
listener="#{multiTextBean.update}" />
</h:inputText>
</h:column>
</h:dataTable>

JSF h:column tag not evaluating rendered attribute

I've got a JSF data table that conditionally displays each item based on a Boolean property of the item, as follows:
<h:dataTable value='#{sessionBean.items}' var='item'>
<h:column rendered='#{item.visible}'>
<h:outputText value='#{item.description}'/>
</h:column>
</h:dataTable>
My problem is that the rendered attribute does not seem to be referring to visible property in my item at all. I've put a tracing message in the getter for the property, and can confirm that the getter is not getting called at all. What really puzzles me though, is that the following works:
<h:dataTable value='#{sessionBean.items}' var='item'>
<h:column rendered='true'>
<h:outputText value='visible = #{item.visible}'/>
<h:outputText value='#{item.description}'/>
</h:column>
</h:dataTable>
That is, in this case all items are rendered, and the text "visible = true" or "visible = false" is successfully output for each. It is only in the column rendered attribute that the getter is not working.
Does anyone have any idea what might cause this behaviour, and what I should do to correct it?
Table columns (read: <td> elements which are all in the same column, which thus applies on all rows) cannot be rendered on a per-row basis. That's not really a JSF restriction, but more a HTML restriction. Ask yourself, how should the HTML end up to look like? What should the browser do with all those missing <td> elements on a per-row basis? Right, it makes no sense at all :)
Just move the row-based rendering to the cell contents:
<h:column>
<h:outputText value="#{item.description}" rendered="#{item.visible}"/>
</h:column>
Or make it a bean based rendering if you actually want to hide the whole column altogether:
<h:column rendered="#{sessionBean.visible}">
<h:outputText value="#{item.description}"/>
</h:column>

jsf 2 composite component problem when use f:facet

I am new to JSF, so I have many problems with it. I have solved much, but now I have a problem when I make composite component of column.
This is the code:
myPage.xhtml:
<h:dataTable >
<util:myCol />
</h:dataTable>
myCol.xhtml:
<composite:interface>
</composite:interface>
<composite:implementation>
<h:column>
<f:facet name="header" >
<h:outputText value="user name" />
</f:facet>
<h:outputText value="some data" />
</h:column>
</composite:implementation>
The problem is that the column does not render.
So I have changed a little in code:
myPage.xhtml:
<h:dataTable >
<h:column>
<util:myCol />
</h:column>
</h:dataTable>
myCol.xhtml:
<composite:interface>
</composite:interface>
<composite:implementation>
<f:facet name="header" >
<h:outputText value="user name" />
</f:facet>
<h:outputText value="some data" />
</composite:implementation>
Here the column renders, but the header "user name" does not appear.
How to solve the problem? Thanks in advance.
Case 1:
dataTable only treats column control children as columns. You are adding a composite control to the dataTable and a the column to the composite control.
Case 2:
The problem is probably to do with where the facets are set. These are set on a map on the parent control. The control you are adding the header facet to is the composite control, not the column.
Note: the links are to JSF 1.2 (JEE5) stuff, but the principle still applies.
I don't know if you still follow this thread, but we had problems inserting facets due to a bug.
Starting the content inside the facet with a comment (server side comment < ! - - - - > ) may solve the problem showing the content. We encountered problems with facets having one liners in there.. putting an extra comment as the first statement is the workaround for the problem.
Kind regards,
Gijs
Does it render correctly when you have all of the JSF on one page? Setting up your JSF on a single page at first can be helpful to make sure that the basics are right; after that works, you can break it up into composite components.
Also, I have noticed (using JSF and Richfaces) that sometimes you can't separate 'parents' and 'children' at times; a rich:toolBar and it's rich:toolBarGroup's need to be on the same actual page, for example. I haven't worked with Facelets much so you might have a different situation.
Best of luck.
Edit:
Try pulling the header out of the composite control, i.e.:
<h:dataTable >
<h:column>
*HEADER_FACET_GOES_HERE*
<util:myCol />
</h:column>
</h:dataTable>
Use composite:facet in interface and composite:renderFacet or composite:insertFacet in implementation.
<composite:interface>
<composite:facet name="foo"/>
<composite:attribute name="value"/>
</composite:interface>
<composite:implementation>
<h:inputText id="value" value="#{cc.attrs.value}"/>
<composite:renderFacet name="foo"/>
<composite:insertChildren/>
</composite:implementation>

Resources