How to get value from Map<TestClass,Object> in item label - jsf

Below is the jsf code
<h:selectOneMenu>
<f:selectItems value="#{bean.mapObject}"var="entity"
itemValue="#{entity.key}" itemLabel="#{entity.value.code}"/>
</h:selectOneMenu>
Backing bean has map defined as
private Map<TestClass, Object> mapObject;
TestClass has two variables and getters/setters
String code;
String name;
Issue I am having is : On JSF, on Selectonemenu, for itemLabel i would like to display the TestClass String value i.e code should be displayed.
Presently on SelectOneMenu on UI, I am getting
TestClass[code=t,name=anu] on the drop down, instead i want code value i..e 't'
Please let me know how to acheive this.

The <f:selectItems var> should in case of maps specify the Map.Entry. The <f:selectItems value> should therefore specify Collection<Map.Entry>. This is not natively recognized yet when you just specify a Map (will come in JSF 2.3).
You basically need to explicitly set the value to Map#entrySet() as below in case you intend to use map key as item value and ma:
<h:selectOneMenu>
<f:selectItems value="#{bean.mapObject.entrySet()}"var="entry"
itemValue="#{...}" itemLabel="#{...}" />
</h:selectOneMenu>
The Map.Entry object has getKey() and getValue() methods which return respectively the map entry's key and map entry's value, which are in your case respectively TestClass and Object. You seem to want to display the code property of TestClass as item label. So, this should do:
<h:selectOneMenu>
<f:selectItems value="#{bean.mapObject.entrySet()}"var="entry"
itemValue="#{...}" itemLabel="#{entry.key.code}" />
</h:selectOneMenu>
You're not terribly clear on what exactly you'd like to use as item value, so I've left it open.
See also:
Our selectOneMenu wiki page

You need to change the itemlabel attribute, (with current value entity.value.code). It should be replaced by entity.key.code ?
Also the value needs to call the method .entrySet , because the map in itself is not a collection.
<h:selectOneMenu>
<f:selectItems value="#{bean.mapObject.entrySet()}" var="entry"
itemValue="#{entry.key}" itemLabel="#{entry.key.code}"/>
</h:selectOneMenu>
Alternatively, since it's the key you want, you could iterate the keys immediately.
<h:selectOneMenu>
<f:selectItems value="#{bean.mapObject.keySet()}" var="key"
itemValue="#{key}" itemLabel="#{key.code}"/>
</h:selectOneMenu>

Related

How to get index of selected item of jsf f:selectItems?

I have seleconeradio, for example:
<h:selectOneRadio value="#{myBean.selectedValue}" layout="pageDirection">
<f:selectItems value="#{myBean.myList}" var="a" itemValue="#{a}" itemLabel="#{a}"/>
</h:selectOneRadio>
where myList is list of integers, e.g. 1,3,2,4.
If user selects second element (i.e. 3) I want in myBean selectedValue to be 2, so I want to get index of selectItems item.
What should I write in f:selectItems itemValue tag? Or it is impossible?
P.S. I can do it by creating a new class in which I have the index property and create a new list of that class, giving the right index. But it is very bad solution.
You can actually use c:forEach for this case. This is especially usefull when you have to deal with a collection containing duplicates and therefore can't use indexOf() for example.
<h:selectOneRadio value="#{myBean.selectedValue}" layout="pageDirection">
<c:forEach items="#{myBean.myList}" var="a" varStatus="idx">
<f:selectItem itemValue="#{idx.index}" itemLabel="#{a}"/>
</c:forEach>
</h:selectOneRadio>
Just be sure to include the JSP JSTL Core namespace if you haven't done yet.
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core
you should use indexOf(Object o) .. it returns the index of the first occurrence of the specified element in this list, or -1 if this list does not contain the element...
your code should probably look like this..
int index = myList.indexof(selectedValue);

How to select first item of a list in <h:selectOneMenu> and render the page during initial load for the first selected item

I have following code:
<h:selectOneMenu value="#{AssetSummaryPageModel.selectedSensorId}" styleClass="facility_dropDown_list" required="true" >
<f:selectItems value="#{AssetSummaryPageModel.childFacilitySelectionList}" required="true" />
<a4j:ajax event="valueChange" execute="#this" status="nameStatus"
render="assetSummaryMainPanel"/>
</h:selectOneMenu>
When I select one item from the dropdown, it is rendering the page for the selected item. But, I want to render the page (with the first item of the dropdown list) during initial load. How can I do that. Any help please!!!!
That's easy. in your AssetSummaryPageModel-Bean you will add a new method with the #PostConstruct annotation so it will be called after the bean has been constructed. In this method you will set selectedSensorId to the first item of your childFacilitySelectionList.
When your page is being rendered, JSF will see that a value was already selected and will set this one as the selected one.
#PostConstruct
public void init() {
selectedSensorId = childFacilitySelectionList.get(0);
}
I got the answer of the question. I decleared the following code in init() method in Pagemodel-Bean and it is being loaded during its initial load:
selectedSensor = getAsset().getCompanyModuleAssets().get(0);
selectedSensorId = selectedSensor.getCoModAssetId();
Thanks :-)

How to retrieve and show list of values in listbox and text corresponding to list item in textarea

I need to use a list box to show some values from database and do further processing when a single value from the list is selected.
At the PrimeFaces showcase site the example loads fixed (static) data into the listbox and there is one PrimeFaces command for each list item. How do I show items in a list box dynamically, when I may not know the number of items beforehand?
I also need to show some text corresponding to the item selected in list, in a textarea. Do I have to use an event listener for this purpose? I would like to leave the text area blank at the beginning. Only when a value is selected in the list box, then I want to use a bean to retrieve and store data using that textarea. Is this possible? How do I implement this?
How do I show items in a list box dynamically, when I may not know the number of items beforehand?
Use <f:selectItems> which you bind to a List<T> property. Basic example, assuming you're using EJB/JPA to interact with DB:
private Item selectedItem; // +getter+setter
private List<Item> availableItems; // +getter
#EJB
private ItemService service;
#PostConstruct
public void init() {
availableItems = service.list();
}
with
<p:selectOneListbox value="#{bean.selectedItem}" converter="itemConverter">
<f:selectItems value="#{bean.availableItems}" var="item"
itemValue="#{item}" itemLabel="#{item.someLabel}" />
</p:selectOneListbox>
The itemConverter should implement javax.faces.convert.Converter and convert from the Item object to its unique string representation (usually its DB identifier) in getAsString() and convert the other way round getAsObject().
I also need to show some text corresponding to the item selected in list, in a textarea. Do I have to use an event listener for this purpose?
Just put a <p:ajax> (the PrimeFaces equivalent of standard JSF <f:ajax>) in the listbox which updates the textarea. E.g.
<p:selectOneListbox value="#{bean.selectedItem}" converter="itemConverter">
<f:selectItems value="#{bean.availableItems}" var="item"
itemValue="#{item}" itemLabel="#{item.someLabel}" />
<p:ajax update="textarea" />
</p:selectOneListbox>
<p:inputTextarea id="textarea" value="#{bean.selectedItem.someText}" />
It'll be invoked when you select an item.
See also:
Our h:selectOneMenu wiki page - same applies to PrimeFaces p:selectOneListbox
Yes, for demonstration purposes most of the examples are loaded with static data. But if you look at the same example on PF showcase, the second listbox code is as follows:
<h:outputText value="Scrollbar: " />
<p:selectOneListbox id="scroll" value="#{autoCompleteBean.selectedPlayer1}"
converter="player" style="height:100px">
<f:selectItems value="#{autoCompleteBean.players}"
var="player" itemLabel="#{player.name}" itemValue="#{player}" />
</p:selectOneListbox>
and f:selectItems value attribute can point to a collection, an array, a map or a SelectItem instance. So coming to the above example players could be any list that is being populated using a database in the managed bean.
But if the instance is not a SelectItem, the labels are obtained by calling a toString on each object and finally the selected itemValue is set to the selectedPlayer1 attribute but you can also see that there is a converter in between so the incoming itemValue string is converted back to a player object and then set to selectedPlayer1.
And if you want to display the selected item in a text area, you can do something like this:
<h:outputText value="Scrollbar: " />
<p:selectOneListbox id="scroll" value="#{autoCompleteBean.selectedPlayer1}"
converter="player" style="height:100px">
<f:selectItems value="#{autoCompleteBean.players}"
var="player" itemLabel="#{player.name}" itemValue="#{player}" />
<p:ajax update="displayArea"/>
</p:selectOneListbox>
<p:inputTextarea id="displayArea" value="#{autoCompleteBean.selectedPlayer1}" />
Here the inputTextarea is updated using ajax with the value selected by the user.

How to save h:inputText values of a h:dataTable? My attempt only saves the value of last row

I'm having trouble making a dataTable where each row has a inputText and a commandLink. When the link is clicked, only it's row's inputText's data is submitted.
Something like this?
<h:dataTable value="#{bean.items}" var="item">
<h:column>
<h:inputText value="#{bean.value}"/>
</h:column>
<h:column>
<h:commandLink action="#{bean.save}" value="save">
<f:setPropertyActionListener target="#{bean.item}" value="#{item}" />
</h:commandLink>
</h:column>
</h:dataTable>
Bean:
#RequestScoped
public class Bean {
private Item item;
private String value;
Right now, as it is, it's using the last row's inputText to fill the value. I wrapped another h:form, but it broke other things and I've learned that nested h:form is not the right way to do it hehe
What's the correct way to do this?
Thanks.
You're binding the value of all HTML input elements to one and same bean property. This is of course not going to work if all those HTML input elements are inside the same form. All values are subsequently set on the very same property in the order as the inputs appeared in the form. That's why you end up with the last value. You'd like to move that form to inside the <h:column> (move; thus don't add/nest another one).
The usual approach, however, would be to just bind the input field to the iterated object.
<h:inputText value="#{item.value}"/>
An alternative, if you really need to have your form around the table, is to have a Map<K, V> as bean property where K represents the type of the unique identifier of the object behind #{item} and V represents the type of value. Let's assume that it's Long and String:
private Map<Long, String> transferredValues = new HashMap<Long, String>();
// +getter (no setter necessary)
with
<h:inputText ... value="#{bean.values[item.id]}" />
This way you can get it in the action method as follows:
String value = values.get(item.getId());
By the way, if you happen to target Servlet 3.0 containers which supports EL 2.2 (Tomcat 7, Glassfish 3, etc), then you can also just pass the #{req} as a method argument without the need for a <f:setPropertyActionListener>.
<h:commandLink ... action="#{bean.save(item)}" />
See also:
How and when should I load the model from database for h:dataTable
How can I pass selected row to commandLink inside dataTable?
How to dynamically add JSF components

How to dynamically create a <f:selectItem> list?

Is there a way to dynamically create a selectItem list? I dont really want to have to create lots of bean code to make my lists return List<SelectItem>.
I tried this:
<ice:selectManyCheckbox>
<ui:repeat var="product" value="#{productListingService.list}">
<f:selectItem itemLabel="#{product.description}" value="#{product.id}"/>
</ui:repeat>
</ice:selectManyCheckbox>
but it doesnt work.
Any ideas?
Use <f:selectItems> instead. It accepts next to List<SelectItem> and SelectItem[] also a Map<String, Object> as value where the map key is the item label and map value is the item value. Or if you're already on JSF 2.0, then you can use a List<SomeBean> instead where the current item can be referenced by the var attribute.
<f:selectItems value="#{productListingService.list}" var="product"
itemLabel="#{product.description}" itemValue="#{product.id}" />
See also:
Our <h:selectOneMenu> wiki page

Resources