jsf make ui:param result static - jsf

I am using templating and pass some values by to use them in the template:
<ui:repeat var="entry" value="#{showEntriesBean.entries}" id="repeatId">
<ui:include src="/templates/entryTemplate.xhtml">
<ui:param name="prePath" value="/" />
<ui:param name="allowedToSee" value="#{bean.calcRandom(0, 10)}" />
</ui:include>
<br />
</ui:repeat>
I found out, that everytime I use the "allowedToSee" variable in my entryTemplate.xhtml, it recalculates its value.
Is there any way to pass the result of calcRandom in a static way? So it is ONCE calculated (when the allowedToSee value is calculated) and performs like a final number? I don't want it to be calculated everytime #{allowedToSee} is used

If you want the value to be held, you should held it somewhere.
What I would do:
1) Create a List<Integer> property.
2) When the values of the entries properties are set, call a method (preRenderEvent? #PostConstruct?) that introduces in your list as many items as there are in entries.
3) Consult that list using the varStatus attribute of ui:repeat
Little more of less, like:
<ui:repeat var="entry" value="#{showEntriesBean.entries}" id="repeatId" varStatus="status">
<ui:include src="/templates/entryTemplate.xhtml">
<ui:param name="prePath" value="/" />
<ui:param name="allowedToSee" value="#{bean.getPrecalculedRandomAt(status.index)}" />
</ui:include>
<br />
</ui:repeat>
More on the varStatus attribute: http://docs.oracle.com/javaee/6/javaserverfaces/2.0/docs/pdldocs/facelets/ui/repeat.html

Related

Get string behind binding object

I have the following JSF construct:
<c:set var="myVar" value="#{myBean.getMyMap()}" scope="request" />
<h:form>
<p>
<h:outputText value="Output1: " />
<h:selectOneMenu value="#{myMappingsBean.data.attribute1}" binding="#{input1}" required="true">
<f:selectItems var="entry" value="#{myVar}"/>
<p:ajax update="myDropdown"/>
</h:selectOneMenu>
</p>
<p>
<h:outputText value="Output2: " />
<h:selectOneMenu id="myDropdown" value="#{myMappingsBean.data.attribute2}" binding="#{input2}" required="true" converter="javax.faces.Double">
<f:selectItems var="entry" value="#{myVar.get(input1.value)}"/>
</h:selectOneMenu>
</p>
</h:form>
Behind myVar is a map defined like that: Map<String, Collection<Double>>
The first dropdown menu shows a list of all the keys of that map (like desired), but the value behind that is the collection of values.
Here the HTML output of one option of that dropdown:
<option value="[1.0, 2.0]">SomeString</option>
My second dropdown should list the collection of double values stored in the map behind the key, that is selected by the first menu.
The problem now is, when I use value="#{myVar.get(input1.value)}" the value I get from .value is the collection and not the string/key of the map. So I never get the desired result.
How can I get the string/key behind the binded object input1? Is there something like input1.name or .toString? Is somewhere a documentary for this?
Ok, I solved it by applying the solution from here.
The first drop down has to be edited to the following:
<p>
<h:outputText value="Output1: " />
<h:selectOneMenu value="#{myMappingsBean.data.attribute1}" binding="#{input1}" required="true">
<f:selectItems var="entry" value="#{myVar.entrySet()}" itemValue="#{entry.key}" itemLabel="#{entry.key}"/>
</h:selectOneMenu>
</p>
As you can see, the entry set is created from the map and from that you use the key as value and label.
And with that the value behind input1.value now is not the collection of doubles but the key of the map.

Variable set by ui:param or c:set inside ui:repeat is not available outside ui:repeat

I would like to define a variable and reuse it somewhere else on the page. I'm defining variable in JSF using <ui:param> and <c:set> and resetting it in the <ui:repeat> depending on condition as follows:
<ui:param name="title" value="default value"/>
<c:set var="title2" value="default val"/>
<ui:repeat value="#{aClip.revisions}" var="revs" varStatus="revStat">
<ui:repeat value="#{revs.metadataMap.entry}" var="entryLst">
<ui:repeat value="#{entryLst}" var="entry">
<ui:repeat value="#{entry.value}" var="metaVal">
<ui:repeat value="#{metaVal.values}" var="aValue">
<ui:fragment rendered="#{metaVal.key eq 'Title'}">
rendered //this prints. condition is evaluted to true
<ui:param name="title" value="#{aValue}"/>
<c:set var="title2" value="#{aValue}"/>
title2 -- #{title2} title -- #{title} //prints
</ui:fragment>
</ui:repeat>
</ui:repeat>
</ui:repeat>
</ui:repeat>
</ui:repeat>
title2 -- #{title2} title -- #{title} //does not print value not even defualt val
I know condition is true and value is set, but when I try to use it outside loop, it doesn't evalute. It doesn't even evalute to defualt value given to variable while defining.
How is this caused and how can I solve it?

Dynamically build the column values

I am building a component that will build a data table dynamically. I need to pass in the field name from the class and concatenate it to the var attribute of the table. example : "tblVar.firstName". I have tried this using a ui:param as the below code shows, but it just prints the string expression it doesn't evaluate the firstName.
Is there a way to take a string and turn it into an EL expression.
<composite:interface>
<composite:attribute name="pageBean" type="pagecode.app.Maintenence" required="true"/>
<composite:attribute name="dataTableList"/>
<composite:attribute name="columnHeader"/>
<composite:attribute name="columnFieldName"/>
</composite:interface>
<composite:implementation>
<p:dataTable id="doc_code_table" value="#{cc.attrs.pageBean.documentCodeList}"
var="tblVar" rowIndexVar="index" paginator="false">
<ui:param value="#{tblVar}.#{cc.attrs.columnFieldName}" name="colValue"/>
<p:column headerText="#{cc.attrs.columnHeader}">
<h:outputText value="#{colValue}"/>
</p:column>
</p:dataTable>
</composite:implementation>
You're there indeed creating a string variable. The effect is exactly the same as when you do this:
<h:outputText value="#{tblVar}.#{cc.attrs.columnFieldName}" />
This is not right. You should use the brace notation #{bean[property}} to use a variable as property name. Thus, so:
<h:outputText value="#{tblVar[cc.attrs.columnFieldName]}"/>
See also:
Our EL wiki page

JSF Compound EL expression

I am trying to validate a inputText box based on the selection of a CheckBox as shown below.
< <h:inputText required="#{param[facesContext.externalContext.response.namespace'form:checkBoxId']}"> >.
The issue is as you see, the component Ids are dynamic, I should be able to use facesContext.externalContext.response.namespace inside the EL expression. Is there a solution to it, appreciate any suggestions.
Thanks.
Just bind the UIComponent to a page scoped property and access its getValue() method.
<h:selectBooleanCheckbox binding="#{checkbox}" />
<h:inputText required="#{not empty checkbox.value and checkbox.value}" />
As to the dynamicness, you can also go around by just giving it a fixed id.
<h:form id="form">
<h:selectBooleanCheckbox id="checkbox" />
<h:inputText required="#{not empty param['form:checkbox'] and param['form:checkbox']}" />
</h:form>
It's however only ugly when it gets lengthy.

Dynamically changing the visibility of the JSF components

My requirement is like this: I am having a text input and whenever a value change event occurs, a select many list box has to be populated. If there is no matching records found, then a text input has to appear instead of a select many list box.
<h:column>
<h:selectManyListbox size="3" value="#{hostInfoBean.gateKeeperendPointReference}" rendered="#{hostInfoBean.selectManyRendered}" id="gateKeeperendPointReference">
<f:selectItems value="#{hostInfoBean.gateKeeperendPointReferenceItems}" />
</h:selectManyListbox>
<h:inputText id="gateKeeperendPointReferenceText" size="30" rendered="#{!hostInfoBean.selectManyRendered}">
</h:inputText>
</h:column>
Also I am using a4j for the value change listener,
<a4j:support event="onchange" reRender="hostInfo:gateKeeperendPointReference" focus="GFacPath"
ajaxSingle="true" />
'selectManyRendered' is a boolean value which I am determining in the JAVA bean. The program works only for the default value of the boolean variable. If the boolean value is changed during runtime, then the toggle between the visibility of selectManyListbox and inputText is not working. Please help to fix this. Am i missing something?
regards,
Suresh
If the "rendered" attribute resolves to false, then the component isn't in your tree and can't be found as a "rerender" target. When you have components that are rendered conditionally you want to wrap them in a component that is always available as a target, like so:
<h:inputText value="#{myBean.text}" >
<a4j:support event="onkeyup" reRender="listZone" ajaxSingle="true" />
</h:inputText>
<h:panelGroup id="listZone">
<h:selectManyListbox value="#{myBean.list}" rendered="#{myBean.renderList}" >
<f:selectItems value="#{myBean.listItems}" />
</h:selectManyListbox>
<h:inputText size="30" rendered="#{!myBean.renderList}/>
<h:panelGroup id="listZone">

Resources