PickList is a dual list input component featuring Drag and Drop based reordering, transition effects, pojo support, theming filtering, captions, checkbox selection, client-server callbacks, responsive layout and more.
<h:form>
<p:growl id="msg" showDetail="true" escape="false"/>
<div class="card">
<h5 style="margin-top: 0">Basic PickList</h5>
<p:pickList id="pickList" value="#{pickListView.cities}" var="cities" itemLabel="#{cities}" itemValue="#{cities}"/>
</div>
<div class="card">
<h5 style="margin-top: 0">Instant Checkbox PickList</h5>
<p:pickList id="instantPickList" value="#{pickListView.cities}" var="cities" itemLabel="#{cities}" itemValue="#{cities}" transferOnCheckboxClick="true"
showCheckbox="true" showSourceControls="false" showTargetControls="false" />
</div>
<div class="card">
<h5>Advanced</h5>
<p:pickList id="pojoPickList" value="#{pickListView.countries}" var="country"
itemValue="#{country}" itemLabel="#{country.name}" showSourceControls="true"
showTargetControls="true" showCheckbox="true"
showSourceFilter="true" showTargetFilter="true"
sourceFilterPlaceholder="Filter available countries"
targetFilterPlaceholder="Filter starting countries"
filterMatchMode="contains" converter="#{countryConverter}" responsive="true">
<f:facet name="sourceCaption">Available</f:facet>
<f:facet name="targetCaption">Starting</f:facet>
<p:ajax event="transfer" listener="#{pickListView.onTransfer}" update="msg"/>
<p:ajax event="select" listener="#{pickListView.onSelect}" update="msg"/>
<p:ajax event="unselect" listener="#{pickListView.onUnselect}" update="msg"/>
<p:ajax event="reorder" listener="#{pickListView.onReorder}" update="msg"/>
<p:column style="width:94%">
<div class="flex align-items-center">
<span class="flag flag-#{country.code} mr-2" style="width: 30px; height: 20px" />
<h:outputText value="#{country.name}"/>
</div>
</p:column>
</p:pickList>
</div>
</h:form>
@Named
@RequestScoped
public class PickListView {
@Inject
private CountryService service;
private DualListModel<String> cities;
private DualListModel<Country> countries;
@PostConstruct
public void init() {
//Cities
List<String> citiesSource = new ArrayList<>();
List<String> citiesTarget = new ArrayList<>();
citiesSource.add("San Francisco");
citiesSource.add("London");
citiesSource.add("Paris");
citiesSource.add("Istanbul");
citiesSource.add("Berlin");
citiesSource.add("Barcelona");
citiesSource.add("Rome");
cities = new DualListModel<>(citiesSource, citiesTarget);
//Countries
List<Country> countriesSource = service.getCountries().subList(0, 10);
List<Country> countriesTarget = new ArrayList<>();
countries = new DualListModel<>(countriesSource, countriesTarget);
}
public DualListModel<String> getCities() {
return cities;
}
public void setCities(DualListModel<String> cities) {
this.cities = cities;
}
public CountryService getService() {
return service;
}
public void setService(CountryService service) {
this.service = service;
}
public DualListModel<Country> getCountries() {
return countries;
}
public void setCountries(DualListModel<Country> countries) {
this.countries = countries;
}
public void onTransfer(TransferEvent event) {
StringBuilder builder = new StringBuilder();
for (Object item : event.getItems()) {
builder.append(((Country) item).getName()).append("<br />");
}
FacesMessage msg = new FacesMessage();
msg.setSeverity(FacesMessage.SEVERITY_INFO);
msg.setSummary("Items Transferred");
msg.setDetail(builder.toString());
FacesContext.getCurrentInstance().addMessage(null, msg);
}
public void onSelect(SelectEvent<Country> event) {
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Item Selected", event.getObject().getName()));
}
public void onUnselect(UnselectEvent<Country> event) {
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Item Unselected", event.getObject().getName()));
}
public void onReorder() {
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "List Reordered", null));
}
}
@Named
@ApplicationScoped
public class CountryService {
private List<Country> countries;
private Map<Integer, Country> countriesAsMap;
private List<Country> locales;
private Map<Integer, Country> localesAsMap;
public static Stream<Country> toCountryStream(String... isoCodes) {
return Stream.of(isoCodes)
.map(isoCode -> new Locale("", isoCode))
.map(CountryService::toCountry);
}
public static Country toCountry(Locale locale) {
return CountryService.toCountry(locale, false);
}
public static Country toCountry(Locale locale, boolean rtl) {
//use hash code from locale to have a reproducible ID (required for CountryConverter)
return new Country(locale.hashCode(), locale, rtl);
}
@PostConstruct
public void init() {
countries = CountryService.toCountryStream(Locale.getISOCountries())
.sorted(Comparator.comparing(Country::getName))
.collect(Collectors.toList());
locales = new ArrayList<>();
locales.add(CountryService.toCountry(Locale.US));
locales.add(CountryService.toCountry(Locale.UK));
locales.add(CountryService.toCountry(new Locale("en", "AU")));
locales.add(CountryService.toCountry(Locale.FRANCE));
locales.add(CountryService.toCountry(Locale.GERMANY));
locales.add(CountryService.toCountry(new Locale("de", "AT")));
locales.add(CountryService.toCountry(new Locale("de", "CH")));
locales.add(CountryService.toCountry(Locale.ITALY));
locales.add(CountryService.toCountry(Locale.KOREA));
locales.add(CountryService.toCountry(new Locale("es", "ES")));
locales.add(CountryService.toCountry(new Locale("ca", "ES")));
locales.add(CountryService.toCountry(new Locale("nl", "NL")));
locales.add(CountryService.toCountry(new Locale("pt", "BR")));
locales.add(CountryService.toCountry(new Locale("pt", "PT")));
locales.add(CountryService.toCountry(new Locale("ar", "SA"), true));
locales.add(CountryService.toCountry(new Locale("ar", "TN"), true));
locales.add(CountryService.toCountry(new Locale("bg", "BG")));
locales.add(CountryService.toCountry(new Locale("cs", "CZ")));
locales.add(CountryService.toCountry(new Locale("el", "GR")));
locales.add(CountryService.toCountry(new Locale("fa", "IR"), true));
locales.add(CountryService.toCountry(new Locale("fi", "FI")));
locales.add(CountryService.toCountry(new Locale("da", "DK")));
locales.add(CountryService.toCountry(new Locale("hi", "IN")));
locales.add(CountryService.toCountry(new Locale("in", "ID")));
locales.add(CountryService.toCountry(new Locale("hr", "HR")));
locales.add(CountryService.toCountry(new Locale("ja", "JP")));
locales.add(CountryService.toCountry(new Locale("hu", "HU")));
locales.add(CountryService.toCountry(new Locale("he", "IL"), true));
locales.add(CountryService.toCountry(new Locale("ka", "GE")));
locales.add(CountryService.toCountry(new Locale("ckb", "IQ"), true));
locales.add(CountryService.toCountry(new Locale("km", "KH")));
locales.add(CountryService.toCountry(new Locale("ky", "KG")));
locales.add(CountryService.toCountry(new Locale("kk", "KZ")));
locales.add(CountryService.toCountry(new Locale("lt", "LT")));
locales.add(CountryService.toCountry(new Locale("lv", "LV")));
locales.add(CountryService.toCountry(new Locale("ms", "MY")));
locales.add(CountryService.toCountry(new Locale("no", "NO")));
locales.add(CountryService.toCountry(new Locale("pl", "PL")));
locales.add(CountryService.toCountry(new Locale("ro", "RO")));
locales.add(CountryService.toCountry(new Locale("ru", "RU")));
locales.add(CountryService.toCountry(new Locale("sk", "SK")));
locales.add(CountryService.toCountry(new Locale("sl", "SI")));
locales.add(CountryService.toCountry(new Locale("sr", "BA")));
locales.add(CountryService.toCountry(new Locale("sr", "RS")));
locales.add(CountryService.toCountry(new Locale("sv", "SE")));
locales.add(CountryService.toCountry(new Locale("th", "TH")));
locales.add(CountryService.toCountry(new Locale("tr", "TR")));
locales.add(CountryService.toCountry(new Locale("uk", "UA")));
locales.add(CountryService.toCountry(new Locale("vi", "VN")));
locales.add(CountryService.toCountry(Locale.SIMPLIFIED_CHINESE));
locales.add(CountryService.toCountry(Locale.TRADITIONAL_CHINESE));
}
public List<Country> getCountries() {
return new ArrayList<>(countries);
}
public Map<Integer, Country> getCountriesAsMap() {
if (countriesAsMap == null) {
countriesAsMap = getCountries().stream().collect(Collectors.toMap(Country::getId, country -> country));
}
return countriesAsMap;
}
public List<Country> getLocales() {
return new ArrayList<>(locales);
}
public Map<Integer, Country> getLocalesAsMap() {
if (localesAsMap == null) {
localesAsMap = getLocales().stream().collect(Collectors.toMap(Country::getId, country -> country));
}
return localesAsMap;
}
}