I know that I can't do it in Primefaces directly, I understand that I have to do it in Converter but don't really know at which stage and how? And what exactly should I check? Maybe to do this I need to wedge in a lifecycle of JSF? For example after p:Autocomplete add item to list in a "Apply request values phase" I should check if there duplicate item and remove it before "Update model values phase", if I understand JSF lifecycle in a right way? Is it possible at all? Thank you in advance.
It's possible, what you have to do is to keep the model up to date for each of user's selection/unselection. That's done using a <p:ajax />
tag into the <p:autoComplete />
, so the List
of selected items will be updated in the back-end. Later on, when user asks for other query, mind about that List
.
Check out this SSCCE with a List
of String
values (you might choose to use a Converter
or not for your custom classes, but that's not related at all with your question):
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head />
<h:body>
<h:form>
<p:outputLabel value="Multiple:" />
<p:autoComplete multiple="true"
value="#{autoCompleteBean.selectedItems}"
completeMethod="#{autoCompleteBean.completeItem}" var="it"
itemLabel="#{it}" itemValue="#{it}" forceSelection="true">
<p:ajax event="itemSelect" />
<p:ajax event="itemUnselect" />
<p:column>
<h:outputText value="#{it}" />
</p:column>
</p:autoComplete>
</h:form>
</h:body>
</html>
@ManagedBean
@ViewScoped
public class AutoCompleteBean {
/**
* The items currently available for selection
*/
private List<String> items = new ArrayList<String>();
/**
* Current selected items
*/
private List<String> selectedItems = new ArrayList<String>();
/**
* All the items available in the application
*/
private List<String> allItems = new ArrayList<String>();
/**
* Create a hardcoded set of items and add all of them for selection
*/
public AutoCompleteBean() {
allItems.add("item1");
allItems.add("item2");
allItems.add("item3");
allItems.add("item4");
items.addAll(allItems);
}
/**
* Check the current user query for selection. If it fits any of the items
* of the system and it's not already selected, add it to the filtered List
*
* @param query
* @return
*/
public List<String> completeItem(String query) {
List<String> filteredList = new ArrayList<String>();
for (String item : allItems) {
if (item.startsWith(query) && !selectedItems.contains(item)) {
filteredList.add(item);
}
}
return filteredList;
}
public List<String> getItems() {
return items;
}
public List<String> getSelectedItems() {
return selectedItems;
}
public void setSelectedItems(List<String> selectedItems) {
this.selectedItems = selectedItems;
}
}
Current version of PrimeFaces (6.2.x) has an "unique" attribute for this matter.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With