Edit HashMap into Datatable - jsf

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...

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

PrimeFaces datatable default sortBy from backing bean

I have a data table with a POJO object:
<p:dataTable id="table" var="object" sortBy="#{object.name}" sortOrder="DESCENDING">
object has fields id, name, date, size for example. I am able to set default sort field using xhtml, but I want set it from backing bean.
I am able to parse column id when user creates sort request for example name.
public void sortEventListener(AjaxBehaviorEvent actionEvent) {
String id = ((SortEvent) actionEvent).getSortColumn().getColumnKey();
String[] idPath = id.split(":");
sortBy = idPath[idPath.length - 1];
sortOrder = ((SortEvent) actionEvent).isAscending();
}
My task detects which column user wants to sort and persists it to db. After reload the data table should be sorted by this column.
When I set
sortBy="#{bean.sortBy}" // sortBy = name
it's not working and data table is not sorted after rendering the page.
Please help.
If you bind your data table to a org.primefaces.component.datatable.DataTable object in your bean or find the table component in your bean, you can use the table object to set the sortBy value expression programmatically.
To get an idea how PrimeFaces is handling sorting, you can have a look at the source code at GitHub.
When you have the sort column, you can easily get the sort value expression. So, in your listener you could use something like:
UIColumn sortColumn = sortEvent.getSortColumn();
ValueExpression sortByVE = sortColumn.getValueExpression("sortBy");
By the way, you can replace the parameter type AjaxBehaviorEvent with SortEvent in your sort listener method.
Now, store the sortByVE expression, and set it as the sortBy value expression of the bound table when needed:
dataTable.setValueExpression("sortBy", sortByVE);
If you want to create the value expression from scratch, use something like:
FacesContext context = FacesContext.getCurrentInstance();
ExpressionFactory ef = context.getApplication().getExpressionFactory();
ValueExpression ve = ef.createValueExpression(context.getELContext(),
"#{object.name}",
Object.class);
dataTable.setValueExpression("sortBy", ve);
In this example "#{object.name}" is fixed. You should construct it based on the value you get from your sort listener.
If you want to find your table in your bean, OmniFaces Components might be helpful. It also offers a shortcut method to create value expressions.
See also:
How does the 'binding' attribute work in JSF? When and how should it be used?
Programmatically getting UIComponents of a JSF view in bean's constructor
How do I set the value of HtmlOutputTag in JSF?

Primefaces datatable: multiple selection list is in another list

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.

Create and add f:selectItems to HtmlSelectOneRadio programmatically

I'm using JSF to create a questionnaire and therefore I need to create my whole xhtml pragmatically because there are different types of questions and the number of them is not predefined.
All I have is a h:panelGrid on my view and the rest is generated in my backing bean.
I have no problem creating HtmlOutputText and HtmlInputText. For that purpose I create them using getApplication e.g. like this:
getApplication().createComponent(HtmlOutputText.COMPONENT_TYPE);
and then add the component to my grid like this:
grid.getChildren().add(questionnumber);
where "grid" is my panelGrid element.
So I put my questions in a loop and based on the type of question from the db I decide what type of component to create. If the question is a normal text question I can easily use a HtmlInputText. But I have multiple choice questions too. Therefore I need to create SelectOneRadio menus and add SelectItems in them.
I can create a HtmlSelectOneRadio using the same createComponent method that I mentioned above. But I'm unable to add options to it (selectitem components). Is there a way that I can do this? Do we have a UIComponent for this that I am missing?
I found the solution myself. I had to use UISelectItems and add it to my SelectOneMenu like this:
final UISelectItem select = (UISelectItem) getApplication().createComponent(UISelectItem.COMPONENT_TYPE);
List<SelectItem> items = new ArrayList<SelectItem>();
for (int k = 0; k < options.length; k++){
items.add(new SelectItem(options[k]));
}
UISelectItems selectItems = new UISelectItems();
selectItems.setValue(items);
selectOneRadio.getChildren().add(selectItems);
grid.getChildren().add(selectOneRadio);

Is this a bug in primefaces autocomplete?

I'm trying to put an autocomplete that fetches suggestions as a list of Entry<String, Integer>
<p:autoComplete completeMethod="#{suggester.suggestTopics}"
var="x1" itemLabel="#{x1.key}" itemValue="#{x1.value.toString()}"
value="#{topicController.selected}" />
Manged bean code is as follows:
private int selected;
public int getSelected() {
return selected;
}
public void setSelected(int selected) {
this.selected= selected;
}
But this fails saying the Integer class doesn't have method/property named key. If I remove the value attribute from autocomplete then it starts working properly. But when I put value attribute it starts expecting that the object inside var should be of the same type as that inside value attribute. I believe/expect it should be that the object inside itemValue should be of the same type as that inside value attribute.
I want to use POJOs for suggestions but pass just the entity Id to the value
Using :
Primefaces 3.1
JSF 2.1.6
I believe/expect it should be that the object inside itemValue should
be of the same type as that inside value attribute.
Yes this makes sense, and it is the same in the primefaces showcase:
<p:autoComplete value="#{autoCompleteBean.selectedPlayer1}"
id="basicPojo"
completeMethod="#{autoCompleteBean.completePlayer}"
var="p" itemLabel="#{p.name}" itemValue="#{p}"
converter="player" forceSelection="true"/>
As you see is var="p" and itemValue="#{p} where p is an instance of Player. And selectedPlayer1 is also an instance of Player.
I don't know if it works with a Map since the Primefaces example is called "Pojo support" and the suggestions should be a List of elements of the same type as in the value attribute.
I think you want to use the Simple auto complete , but instead you looked at the wrong example on the showcase of the Pojo Support
x1 refers to the int selected - while it expect to be referred to a POJO (with key and value properties.) , that's why you get the message
Integer class doesn't have method/property named key
Or simple use the Simple auto complete
As commented to Matt you dont need to rebuild Player(Pojo) from Db. You can set simply id property of Player(Pojo) and in action method may be utilize this id to fetch it from DB.
In your case in convertor you might do
Entry<String, Integer> e = new Entry<String, Integer>();
e.setId(value) // where value is passed in to convertor in method getAsObject.....
This value will be set to private Entry<String, Integer> selected
I have used Pojo autocomplete but not tried with generic classes.
Hope this helps.
I know the question is outdated but I've had the same problem.
The point is that you have to assign var to p (var="p"). I think it's terribly unobvious (documentation doesnot mention it has to be that way) 'cause I thought I can assign any var name I want.

Resources