double reference in EL expression - jsf-2

I'm trying to make a "rich:dataTable" with a dynamic number of columns. I have a bean with a List of columns (with attributes headerName and fieldName) and a list of items to be represented in the table so I have next code:
<rich:dataTable id="data_table" value="#{bean.list}" var="item">
<c:forEach items="#{bean.columnList}" var="col">
<rich:column>
<f:facet name="header">
<h:outputText value="#{col['headerName']}" />
</f:facet>
<h:outputText value="??" />
</rich:column>
</c:forEach>
</rich:dataTable>
The problem is that I don't know how to put the value="??" to represent what I want. I want something like:
value="#{item.#{col.fieldName}}"
but I don't know how can I represent it with the correct Expression Language.
I'm using JSF2.1 and Richfaces 4.3.2
Con somebody help me with this issue?

Use the brace notation #{bean[property]}. It allows you to use variables instead of constants as property names.
value="#{item[col.fieldName]}"

Related

Filter Facet is not working in Richface 4.3x

In the Code below, You can observe two things:
1) Default sorting is getting utilized.
2) Image based custom filter is used.
Problem I am facing : When I click on filter image default sorting is getting triggered.
Need a way by which If I click on filter, default sorting doesn't get triggered. (This was achieved in Richface 3.3 by putting this custom filter in filter facet.)
Any help or hint would be greatly appreciated.
<rich:column sortBy="#{model.modVal}" label="Model Value"
sortable="true" id="modelVal" rendered="#{backingBean.renderMap['modVal']}">
<f:facet name="header">
<h:outputText value="Model Value" />
<h:graphicImage title="Filter"
value="#{backingBean.dataModel.modValFilter }">
<a4j:ajax event="click" render="filterCol"
execute="#form"
listener="#{backingBean.loadModalPanelData('modVal') }"
oncomplete="#{rich:component('filterCol')}.show()">
</a4j:ajax>
</h:graphicImage>
</f:facet>
<h:outputText value="#{model.modeVal}"
title="#{model.modelVal}" />
</rich:column>
Use manual sorting, and place a click-able panel in your header for sorting, and another panel for filtering.
The filter facet has been deprecated in favour of the header facet. So what you used to have in the filter facet, you can place in the header facet:
<f:facet name="header">
<h:panelGrid>
<h:outputText value="Model Value"/>
<h:graphicImage title="Model Filter"/>
</h:panelGrid>
</f:facet>

Can't dynamically set component identifier

I have a p:inputText field inside a dataTable and I'm trying to set its identifier dynamically.
However I get the following error:
component identifier must not be a zero-length String
None of the String used as id are null or of zero-length
<h:form id="updateform">
<p:dataTable id="updatetable" value="#{EditingBean.row}" var="column"
style="width: 983px; overflow-x: auto; white-space: normal;">
<f:facet name="header">
<h:outputText value="#{EditingBean.currentStatement.statementName}" />
</f:facet>
<p:column rendered="#{column.display}" style="white-space: normal;">
<h:outputText value="#{column.alias}" />
</p:column>
<p:column rendered="#{column.display}" style="white-space: normal;">
<p:inputText id="#{column.name}" value="#{column.value}" />
</p:column>
<f:facet name="footer" style="text-align: right;">
<h:commandButton value="Update" action="#{EditingBean.update()}"
ajax="false" />
</f:facet>
</p:dataTable>
</h:form>
The id attribute must be set during view build time.
However, as #{column} is declared as <h:dataTable var>, it's only available during view render time. As it runs after view build time, it's thus null during view build time.
I'm not sure about the concrete functional requirement for which you thought that doing this would be the right solution. The code is not self-documenting enough to properly guess it. So it's hard to give a suitable answer. In any case, you've basically 2 options:
Use an iterating tag which runs during view build time, such as JSTL <c:forEach>.
<c:forEach items="#{EditingBean.row}" var="column">
...
<p:inputText id="#{column.name}" ... />
You perhaps actually don't need a dynamic ID at all. Give it a fixed ID.
<p:inputText id="name" ... />
JSF will already take care of generating unique IDs (prefixed with row index) in HTML output. Rightclick page and do View Source to see it yourself.
See also:
JSTL in JSF2 Facelets... makes sense?

<rich:dataTable> from listOfMaps

I have a SessionScoped bean which has a list of maps. I am attempting to get a <rich:dataTable> produced using <a4j:repeat>.
The list of maps is being populated correctly, although there is no dataTable output. From reading articles on stack-overflow, I think my problem may be occuring due to the life-cycle problems or my novice understanding of jsf with richfaces.
Using: Tomcat 7, JSF 2.1x - Mojarra, Richfaces 4.x
Here is what I have so far;
<rich:dataTable value="#{myBean.myMap}" var="map">
<a4j:repeat value="#{myBean.myMap[0].keySet().toArray()}" var="key">
#{map[key]}
</a4j:repeat>
</rich:dataTable>
If someone could point my in the correct direction, the help would be greatly appreciated!
Answer:
As stated below the solution is to instead use <c:forEach> and use <rich:columns>.
Solution:
<rich:dataTable value="#{queryBean.test}" var="map">
<c:forEach items="#{queryBean.test[0].keySet().toArray()}" var="key">
<rich:column style="text-align:left; width:auto;">
<f:facet name="header">
<h:outputText value="#{key}" />
</f:facet>
<h:outputText value="#{map[key]}" />
</rich:column>
</c:forEach>
</rich:dataTable>
First of all <rich:dataTable> has to contain columns - <rich:column>
Assuming you want to have dynamic table (the number of columns based on the length of the map) you will have to use <c:forEach> instead of <a4j:repeat>. I have answered a question about this a while ago, take a look.

Primefaces crop converter error

I am using the following code and try to crop an image which takes its value from a bean :
<p:panelGrid columns="2">
<p:row>
<p:column>
<p:imageCropper id="imageCropperId" value="#{imageCropperBean.croppedImage}"
image="#{imageCropperBean.newImageName}">
</p:imageCropper>
</p:column>
<p:column>Bild innerhalb des Rahmens positionieren</p:column>
<p:column>
<p:graphicImage id="localCroppedImage" value="#{imageCropperBean.newImageName}" />
</p:column>
</p:row>
<p:row>
<p:column colspan="3">
<p:commandButton value="Crop" actionListener="#{imageCropperBean.crop}"
update=":growl imageCropperId localCroppedImage" />
</p:column>
</p:row>
</p:panelGrid>
I am always getting the error : {0}: Conversion error occurred. inside growl, due to :
value="#{imageCropperBean.croppedImage}"
The converter attribute from declaration says :
An el expression or a literal text that defines a converter for the
component. When it's an EL expression, it's resolved to a converter
instance. In case it's a static text, it must refer to a converter id.
but the EL expression is evaluated at String. What should I do? It works if I put a normal String pointing to an existing image.
I have managed to fix this error.
For the ones which will have the same problem, basically this occurs when
Either errors are being thrown during cropping phase (e.g. files not found or if the cropped image is not relative to the original one)
Either the value which is evaluated from EL image="#{imageCropperBean.newImageName}" is evaluated to null, while trying to skip the cropping (I couldn't suceed with required="true" so I used rendering="someCondition")

Create table columns dynamically in JSF

I'm working on dashboard application where I have to retrieve a set of records and display in dynamic tables boxes. Page frame length is fixed. now of columns and rows can be initialized. It should look like this sample:
Currently I'm using data table to display but it prints all the data in one column. How would I change my code to above pattern?
<o:dataTable id="tabBlSearch" var="item"
onkeyup="handleLeftRightArrowOnDataTable('frmDashBoard:tabBlSearch')"
value="#{bLDashBoardAction.listBondLoc}">
<o:column style="width: 20px;">
<h:outputText value="#{item.awb}" />
</o:column>
</o:dataTable>
You can achieve this with standard JSF components using a <h:panelGrid> wherein <c:forEach> is been used to generate the cells during the view build time. The <ui:repeat> won't work as that runs during view render time.
<h:panelGrid columns="5">
<c:forEach items="#{bean.items}" var="item">
<h:panelGroup>
<h:outputText value="#{item.value}" />
</h:panelGroup>
</c:forEach>
</h:panelGrid>
As to component libraries, I don't see anything in OpenFaces' showcase, but PrimeFaces has a <p:dataGrid> for exactly this purpose, even with pagination support.
<p:dataGrid columns="5" value="#{bean.items}" var="item">
<p:column>
<h:outputText value="#{item.value}" />
</p:column>
</p:dataGrid>

Resources