Primefaces datatable: multiple selection list is in another list - jsf

I have a question, how do I map the datatable multiple selecion in a list that is an element of another list:
<p:dataTable id="subDataTable#{index}" value="#{objectBean.subDataModels.get(index)}"
selection="#{objectBean.selectedLists.get(index)}" var="subRowTable"
rowKey="#{subRowTable.primaryKeyObj.toString()}">
With index is a int variable, and in my objectBean
private List<List<Object>> subDataModels; // and getter, setter
private List<List<Object>> selectedLists; // and getter, setter
I got error:
javax.faces.FacesException: Multiple selection reference must be an Array or a List for datatable
I need the solution for this case or the related topic about it.
Thanks for your help.

Related

Edit hashmap in JSF or Primefaces datatable

I have an object that represents a service provider. In that object I have this hashmap
private Map<MetaDataKeys, String> metaData;
The "MetaDatatKeys" is a enum that looks like this,
public enum MetaDataKeys {
PROVIDER_NAME, PROVIDER_CONTACT_NAME, PROVIDER_SERVICE_RADIUS;
}
I would like to display the hashmap key/value pairs in a datatable or similar for editing, something along the lines of,
<p:dataTable id="providerDatatable" var="infoMap" value="#{editUserBean.editUser.metaData}">
<p:column><h:outputText value="#{infoMap.key.metaData}"/></p:column>
<p:column><h:inputText value="#{infoMap.key.value}"/></p:column>
</p:dataTable>
In my backing bean "editUser" is the object that contains the map.
what is the best way to go about this? I have not been successful in even getting the table to render and populate with values. In searching most examples use a string or a primitive for the key.
You should make iteration in the datatable by Map.entrySet() it's better way. If you try to do itaration by Map.keySet() and than take value by key you can take O(n^2).
For your task realisation looks like:
<p:dataTable id="providerDatatable" var="infoMap" value="#{editUserBean.editUser.metaData.entrySet()}">
<p:column><h:outputText value="#{infoMap.key}"/></p:column>
<p:column><h:inputText value="#{infoMap.value}"/></p:column>
</p:dataTable>
To edit table row you can you use p:cellEditor more info about this component you can find at the Primefaces show case

NullPointerException while displaying the same page after some taks in jsf

First I want to tell :
I saw How to use JSF's h:selectBooleanCheckbox with h:dataTable to create one object per row?
and my problem is like same but not solved problem.
Following is my code :
*.xhtml
<rich:column>
<h:selectBooleanCheckbox id="resolveTxn" value="#{verifyTransactionBean.checked[verifyTxnList.id]}"/>
</rich:column>
.
.//Some code here
.
<h:commandButton value="Resolve" action="#{verifyTransactionBean.resolveToTxn}" styleClass="btn" />
and following is my code
private Map<Long, Boolean> checked = new HashMap<Long, Boolean>();
public void resolveToTxn() {
List<ToVerifyTxnDTO> list = new ArrayList<ToVerifyTxnDTO>();
for (ToVerifyTxnDTO dTO : toVerifyTxnDTOList) {
if(checked.get(dTO.getId())){//I got null pointer exception here
Long id=dTO.getId();
verifyTransactionSessionBeanLocal.updateResolvedflag(id);
}
}
}
What I want to do ?
I want to pass checked row id as parameter on following :
verifyTransactionSessionBeanLocal.updateResolvedflag(id);
And after clicking the button Resolve some operation should be done and refresh dataTable and display same page. Operation is done but getting null pointer exception while displaying (Reddering) the same page
Thanks
The if () test on a Boolean will throw NullPointerException if the Boolean itself is actually null instead of true or false. In other words, the checked.get(dTO.getId()) has unexpectedly returned null for some reason.
That can have several causes:
The JSF implementation hasn't properly updated the checked map with the value from <h:selectBooleanCheckbox> for some reason.
The EL implementation was using Boolean instead of boolean for some reason.
The toVerifyTxnDTOList has incompatibly changed during the process which caused that the currently iterated dTO isn't the one which was been displayed in the table at the moment checkboxes were clicked (perhaps because the bean is request scoped instead of view scoped).
The toVerifyTxnDTOList contains more items than present in the checked map because you're using pagination and displaying only a subset at once.
In any case, to fix the NullPointerException, just add an additional nullcheck:
Boolean dtoChecked = checked.get(dTO.getId());
if (dtoChecked != null && dtoChecked) {
// ...
}
This however doesn't fix the underlying cause of your problem. My best guess would be that the toVerifyTxnDTOList contains more items than actually being displayed in the table. Thus, it's one of the last mentioned two causes mentioned in the list. The first mentioned two causes are theoretically possible, but in practice I haven't seen this before.

Edit HashMap into Datatable

for manage a cart i have create an HashMap and i convert this in a list for display into a PrimeFaces Datatable with this method:
public List<Map.Entry<Livre, Integer>> getPanier() {
Set<Map.Entry<Livre, Integer>> panierSet = panier.entrySet();
return new ArrayList<Map.Entry<Livre, Integer>>(panierSet);
}
Once the list shown i wish to update the quantity directly inside the datatable with inputText.
But i have no idea if this is possible ? or if i need to convert HashMap in ArrayList for do this traitement.
You can use something like this in your table
<h:inputText value="#{myMap[someVarUsedInDatatable.keyOfThatRow]}"/>
That will allow you to read and modify the relevant value in the relevant key...

Bind the value of an input component to a list item by index

here is an example :
<h:outputLabel for="category1" value="Cateogry"/>
<h:selectOneMenu id ="category1" value="#{articleManageBean.categoryId1}"
converter="categoryConverter">
<f:selectItems value="#{articleManageBean.categories}" var="category"
itemValue="#{category.id}" itemLabel="#{category.name}" />
</h:selectOneMenu>
and here is the managed bean that I have
#ManagedBean
#SessionScoped
public class ArticleManageBean {
private Long categoryId1;
private List<Category> categories;
//...
}
The categories list gets populated from db, and selectOneMenu gets populated with this list using a converter.
My First question:
If I want to create another selectOneMenu in my jsf page I would have to copy paste the entire thing and just change the value of selectOneMenu to say categoryId2 thus putting another attribute to managed bean called categoryId2. That is not practical. I want to map these values of selectMenu to list items, for instance to an attribute
List<Long> categoryIds;
if I use
<h:selectOneMenu id ="category1" value="#{articleManageBean.categoryIds.[0]}" >
I get an error
javax.el.PropertyNotFoundException: /createArticle.xhtml #47,68 value="#{articleManageBean.categoriesId[0]}": Target Unreachable, 'null' returned null
If I nitialize the Araylist then I get this exception
javax.el.PropertyNotFoundException: /createArticle.xhtml #47,68 value="#{articleManageBean.categoriesId[0]}": null
My second question:
Is there a way to dinamicly write selectOneMenu tags, by that I mean not to copy paste the entire tag, just somehow create a function that take the categoryId parameter and writes automaticaly the tag (somekind of custom tag maybe ?)
Hope you understood my questions
thanks in advance
Use the brace notation instead to specify the index.
<h:selectOneMenu id="category1" value="#{articleManageBean.categoryIds[0]}">
You only need to make sure that you have already prepared the values behind #{articleManageBean.categoryIds}. JSF won't do that for you. E.g.
private List<Long> categoryIds = new ArrayList<Long>();
public ArticleManageBean() {
categoryIds.add(null);
categoryIds.add(null);
categoryIds.add(null);
// So, now there are 3 items preserved.
}
an alternative is to use Long[] instead, this doesn't need to be prefilled.
private Long[] categoryIds = new Long[3]; // So, now there are 3 items preserved.

How do I bind a inputbox values to a map value in a backing bean property when using a wizard

I am using the Primefaces wizard component. On one tab I am dynamically creating input boxes based on previous tabs input(user type). The inputbox text labels are derived from a list. In my backing bean, I have a map that contains input labels as keys and inputbox inputs as values.
Clicking on next, I would like the map(values) to be updated with the user input (corresponding to the key)
<c:forEach items="#{gdsiGeodataBean.actionCommand.fields}" var="reqs">
<h:outputLabel for="#{reqs.name}" value="#{reqs.name}:* " />
<pou:inputText value="#{gdsiGeodataBean.actionCommand.values['reqs.name']}" required="true" requiredMessage="Input is required."/>
</c:forEach>
My backing bean :
private List<RequiredParam> fields; // +getter (no setter required)
private Map<String, String> values; // +getter (no setter required)
public CommandAction(String actionName, String actionParams, String context) {
this.actionName = actionName;
this.actionParams = actionParams;
this.contextName = context;
//Set up parameters
getRequiredParams();
getOptionalParams();
fields = getFields();
values = new HashMap<String, String>();
}
Essentially what I would like is for the map values to be updated with user inputs from the textinput boxes.
Your approach to bind the input value to a map is not entirely correct.
<pou:inputText value="#{gdsiGeodataBean.actionCommand.values['reqs.name']}" required="true" requiredMessage="Input is required."/>
You're specifying a fixed map key instead of a dynamic map key based on the currently iterated #{reqs}. This way all submitted values will end up in one and same fixed map key "reqs.name", whereby each one overrides each other so that you only get the value of the last field in the map.
You need to remove those singlequotes to make it a really dynamic key.
<pou:inputText value="#{gdsiGeodataBean.actionCommand.values[reqs.name]}" required="true" requiredMessage="Input is required."/>
Unrelated to the concrete question, even though this approach will work when used as-is in your question, the <c:forEach> will fail in certain circumstances. E.g. when used inside a composite component or an iterating JSF component. Rather use <ui:repeat> instead. See also JSTL in JSF2 Facelets... makes sense?

Resources