How to use list object in <c:forEach tag? - jsp-tags

I have two list objects in request. Now I want to use them in jsp page by the following approach:
<c:forEach items="${listA}" var="A">
<tr><td>${A.propA}</td><td>${listB[A.index].propB}</td>
</c:forEach>
Is that possible?
Thanks
I got the correct approach:
<c:forEach items="${listA}" var="A" varStatus="status">
<tr><td>${A.propA}</td><td>${listB[status.index].propB}</td>
</c:forEach>

Yes try,
${requestscope.listA}

Related

How to set a Map value in h:inputText

I'm struggling to implement a fairly trivial functionality with JSF which involves dynamically displaying the content of a nested map on a page and editing capabilities for its values. But it has turned out that the MappedValueExpression$Entry that you get when iterating over a map with c:forEach is not writable!
<c:forEach items='#{inflectionBean.word.inflectionalForms}' var="number" >
<p:fieldset legend="#{number.key}">
<c:forEach items="#{number.value}" var="case" >
<p:panel header="#{case.key}">
<h:inputText value="#{case.value}" />
</p:panel>
</c:forEach>
</p:fieldset>
</c:forEach>
When I am trying to submit the above form I'm getting:
javax.el.PropertyNotWritableException: /inflection.xhtml #39,56 value="#{case.value}": The class 'com.sun.faces.facelets.tag.jstl.core.MappedValueExpression$Entry' does not have a writable property 'value'.
I wonder if there are reasonable workarounds or if I am approaching the problem in a wrong way. Thanks!
Basically, what your code is attempting is invoking Map.Entry#setValue(value). This is indeed not possible in EL. Instead, you should be referencing the map value directly on the map itself by key, so that EL can do Map#put(key, value).
<c:forEach items="#{number.value}" var="case">
...
<h:inputText value="#{number.value[case.key]}" />

JSF2 Building Dynamic EL Expressions

I am working on creating a dynamic table using JSTL forEach and a h:dataTable and have all of the controls and potential error message showing nicely, but am now stuck on getting the value set for each of the control. I will need to create (I think) a dynamic EL expression to set the value, but have not been able to get any of my versions to work. I was hoping to build out the expression using c:out, but found out that that tag is not available in JSF2.
So, is it possible to build a dynamic expression in the page?
How can I set the expression in the backing bean if the control hasn't been built yet ?
<h:dataTable id="dtDetails" styleClass="slate_table" value="#{remediationDetail.eventList}" var="dataItem">
<c:forEach items="#{remediationDetail.eventHeaders}" var="key">
<h:column>
<f:facet name="header">#{key.fieldDefinition.fieldConfiguration.customLabel}</f:facet>
<h:inputText value="" id="txtNumber" styleClass="remediation_textbox error_marker" title="#{remediationDetail.errorMessages(dataItem.id, key.fieldDefinition.id)}">
<f:convertNumber maxFractionDigits="0" maxIntegerDigits="19"/>
</h:column>
</c:forEach>
</h:dataTable>
As always, any help or direction is appreciated.
Regards,
Mike
I was not being able to create a Dynamic EL Expression. So, I ended using the index of the c:forEach to help define what values I am looking for. The only catch for this result is that I would be expecting the data that I am about to display to have the same number of positions in the array.
<c:forEach items="#{remediationDetail.eventHeaders}" var="key" varStatus="looper">
<h:column>
<f:facet name="header">#{key.fieldDefinition.fieldConfiguration.customLabel}</f:facet>
<h:inputText id="txtNumber" value="#{dataItem.entityList[looper.index].val}">
<f:convertNumber maxFractionDigits="0" maxIntegerDigits="19"/>
</h:inputText>
</h:column>
</c:forEach>
In my case the following helped to build dynamic EL.
<ui:param name="beanName" value="myBackedBean"/>
<ui:param name="propertyName" value="field1"/>
<ui:param name="nestedPropertyName" value="field1"/>
<p:inputTextarea value="#{sessionScope[beanName][propertyName][nestedPropertyName]}"/>
Inspired of this topic

How to know in JSF 1.2 and richfaches the id from h:column in a h:datatable

I have a datatable from which I open with a click on an image the <rich:modalPanel>. But the <rich:componentControl for="panel" attachTo="showPreview" must have the exact id, in my case below: showPreview, but as my link is inside a dataTable, it will be generated like 1:showPreview 2:showPreview.....n:showPreview
Is there any way to know in which line of the table i am, to get a dynamic binding?
My XHTML in JSF 1.2 looks something like this:
<h:dataTable styleClass="tb_tabletag" id="dtContentPosts" value="#{listOfObjects}" var="object">
<h:column id="columnnumber" >
<h:outputLink id="showPreview" value="#">
<h:graphicImage value="preview.png" />
<rich:componentControl for="panel" attachTo="showPreview" operation="show"
event="onclick"/>
</h:outputLink>
</h:column>
</h:dataTable>
...
...
...
<rich:modalPanel id="panel" autosized="true">
some stuff
</rich:modalPanel>
Thank you for any help!
Thanks Luiggi for your link, with the given source code,this helped me to find my simple trick:
i get now the number with: #{listOfObjects.indexOf(object)}
the only important thing is, that the modalPanel is in a <h:column></h:column> to receive the correct number
works perfect

ui:repeat inside composition not printing values

I am new to jsf. I have the bellow code. When I place ui:repeat inside rich:toolbar it prints the data. But when I place it after the toolbargroup inside composition tag it doesn't print anything. I have a toolbar and I want to show ui:repeat data bellow that toolbar. If I place it in toolbar it shows the data but inside the toolbar not bellow it. How can I place it bellow the toolbar?
Thanks.
Update: I found out the problem. The ui:repeat tag is showing up bellow the toolbar. So how can I add position to ui:repeat?
enter code here<h:body>
<ui:composition> <h:panelGroup layout="block">
<a4j:region>
<rich:toolbar id="header-toolbar" height="30px" itemSeparator="line">
<rich:toolbarGroup location="right" rendered="#{not empty searchType}">
<rich:menuItem
label="search"
mode="ajax"
execute="#this"
oncomplete="#{rich:component(searchFormModalPanel)}.show();"
status="status"/>
</rich:toolbarGroup> </rich:toolbarGroup>
</rich:toolbar>
</a4j:region> //Bellow doesn't show up! <ui:repeat value="#{breadCrumbMB.crumbs}" var="crumb" varStatus="crumStatus">
#{breadCrumbMB.incIndex()}
<h:outputLink value="#{crumb}">
<h:outputText value="#{breadCrumbMB.title(crumb.toString())}" rendered="${breadCrumbMB.lastLink()=='false'}"/></h:outputLink> >
<h:outputText value="#{breadCrumbMB.title(crumb.toString())}" rendered="${breadCrumbMB.lastLink()=='true'}"/>
</ui:repeat> </ui:composition>
</h:body>
Try to include ui:repeat inside a4j:region, if it doesn't work then use a4j:repeat

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