Get string behind binding object - jsf

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.

Related

Setting a SelectOneListbox default selection, which is populated from a hashmap

I have a selectOneListBox that is populated with a hashmap's key as the label and the value as the value.
How do i set the first object in the list as the default selection, so it looks highlighted
<!--the list box containing the results from the search-->
<h:form id="newPointsResultList" styleClass="simpleformstyle">
<p:selectOneListbox id="selectedPoints_listbox"
value="#{mapBean.selectedPoint}"
converter="omnifaces.SelectItemsConverter"
scrollHeight="395"
styleClass="simpleformstyle10"
rendered="#{not empty mapBean.newPointsHashMap}" >
<f:selectItems value="#{mapBean.newPointsHashMap}" />
<p:ajax listener="#{mapBean.valueChanged}" update=":newPointsGrid:selectedPoint_grid" process="#this" />
<f:param name="idUser" value="#{mapBean.tipTourUser.idUser}" />
</p:selectOneListbox>
</h:form>
<br />
I set the mapBean.selectedPoint to the value of the first object in the hashmap, and then the selectOneListBox highlights the default selection

p:selectOneMenu, custom content and editable=true

I have the following usage of the p:selectOneMenu:
<p:selectOneMenu id="selectField"
value="#{someBean.someField}"
converter="#{selectItemConverter}" var="x" editable="true">
<f:selectItems
value="#{selectItemsBean.getSelectItems(tab, field)}" var="si"
itemLabel="#{si.label}" itemValue="#{si}" />
<p:column>
<h:outputText value="#{si.label}" />
</p:column>
<p:column>
<h:graphicImage library="images" name="noway_16x16.png"
title="#{si.disabledReason}" rendered="#{si.disabled}" />
</p:column>
<p:ajax event="change" update="#form" partialSubmit="true" process="selectField" />
</p:selectOneMenu>
As you can see, I use custom content in combination with editable=true. When I submit the form, the Converter gets the label of a selected item as the value, not the actual value. In the HTML page, the values are correct, e.g. <option value="C">C-style mounting</option>. With editable=false, the correct value (e.g. C is sent to the converter, with editable=true the converter retrieves C-style mounting.
What I want is that the user can either select one of the pre-defined items in the list and the server submits that value of the item OR the user enters something and that is submitted as value. But the current behavior is a bit strange - or am I just wanting too much?

h:selectOneMenu in p:dataTable doesn't submit its value

I have a question about selectOneMenu and settting the values. I have an Object SampleDesc that has and ID, Text, and a List<SampleDescValues>. For each datatable row the Text is the output label and the select one menu values are the List<SampleDescValues>.
XHTML:
<h:panelGroup id="tables">
<p:dataTable resizableColumns="true"
var="sampleDesc" id="SampleDescTable" rowIndexVar="rowIndex"
value="#{sampleBean.sampleDescList.list}"
rendered="#{sampleBean.sampleDescList.list.size() gt 0}">
<p:column>
<h:outputLabel value="#{sampleDesc.sampleDescText}"/>
</p:column>
<p:column>
<h:selectOneMenu required="#{sampleBean.sampleDescList.list.size() gt 0}" converter="#{sampleDescValueConverter}"
id="SampleDescValue" value="#{sampleBean.selectedSampleDescList.get(rowIndex)}">
<f:selectItem itemLabel="Select One" itemValue="#{null}"/>
<f:selectItems value="#{sampleDesc.sampleDescValues}" var="sdv"
itemLabel="#{sdv.sampleDescValuesText}" itemValue="#{sdv}" />
</h:selectOneMenu>
</p:column>
</p:dataTable>
</h:panelGroup>
I have the converter setup and it works because ive set it to a single SampleDescValue and it set the value.
The problem is when i try and populate the form with a Sample from the database it can only set one of the dropdowns when there could be an infinite number of selectonemenu's
I set the value selected to private List<SampleDescValue> selectedSampleDescList;
When i try and submit it does nothing, it works when the datatable is not rendered.
Your menu value is wrong:
<h:selectOneMenu value="#{sampleBean.selectedSampleDescList.get(rowIndex)}">
It's not possible to perform a set operation on this EL expression.
Use the brace notation instead:
<h:selectOneMenu value="#{sampleBean.selectedSampleDescList[rowIndex]}">
Note that this expects a non-null selectedSampleDescList. So make sure that you've already properly initialized it with a new ArrayList<>() beforehand. EL won't do that for you. It will only set the list items using List#add(index, object) method.
See also:
Our EL wiki page
Unrelated to the concrete problem, this expression
#{sampleBean.sampleDescList.list.size() gt 0}
can be simplified as follows
#{not empty sampleBean.sampleDescList.list}
And this is unnecessary in the required attribute of the <h:selectOneMenu> as it would always evaluate true at that point. Just use required="true" directly instead.

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