AutoComplete displays suggestions while the input is being type. AutoComplete features various options, customizable content, multiple selection, effects and events.
<div class="card ui-fluid ">
<h:form>
<p:growl id="msgs" showDetail="true" skipDetailIfEqualsSummary="true"/>
<h5 class="p-mt-0">Single</h5>
<div class="p-formgrid p-grid">
<div class="p-field p-col-12 p-md-4">
<p:outputLabel value="Simple" for="@next"/>
<p:autoComplete id="acSimple" value="#{autoCompleteView.txt1}"
completeMethod="#{autoCompleteView.completeText}" scrollHeight="250"/>
</div>
<div class="p-field p-col-12 p-md-4">
<p:outputLabel value="Min Length (3)" for="@next"/>
<p:autoComplete id="acMinLength" minQueryLength="3" value="#{autoCompleteView.txt2}"
completeMethod="#{autoCompleteView.completeText}" effect="fade" scrollHeight="250"/>
</div>
<div class="p-field p-col-12 p-md-4">
<p:outputLabel value="Delay(1000)" for="@next"/>
<p:autoComplete id="acDelay" queryDelay="1000" value="#{autoCompleteView.txt3}"
completeMethod="#{autoCompleteView.completeText}" effect="blind" scrollHeight="250"/>
</div>
<div class="p-field p-col-12 p-md-4">
<p:outputLabel value="Max Results(5)" for="@next"/>
<p:autoComplete id="acMaxResults" maxResults="5" value="#{autoCompleteView.txt4}"
completeMethod="#{autoCompleteView.completeText}" scrollHeight="250"/>
</div>
<div class="p-field p-col-12 p-md-4">
<p:outputLabel value="Force Selection" for="@next"/>
<p:autoComplete id="acForce" forceSelection="true" value="#{autoCompleteView.txt5}"
completeMethod="#{autoCompleteView.completeText}" scrollHeight="250"/>
</div>
<div class="p-field p-col-12 p-md-4">
<p:outputLabel value="DropDown" for="@next"/>
<p:autoComplete id="dd" dropdown="true" value="#{autoCompleteView.txt6}"
completeMethod="#{autoCompleteView.completeText}" scrollHeight="250"/>
</div>
<div class="p-field p-col-12 p-md-4">
<p:outputLabel value="Cache" for="@next"/>
<p:autoComplete id="cache" cache="true" cacheTimeout="30000" value="#{autoCompleteView.txt7}"
completeMethod="#{autoCompleteView.completeText}" scrollHeight="250"/>
</div>
<div class="p-field p-col-12 p-md-4">
<p:outputLabel value="Select Event" for="@next"/>
<p:autoComplete id="event" value="#{autoCompleteView.txt8}"
completeMethod="#{autoCompleteView.completeText}" scrollHeight="250">
<p:ajax event="itemSelect" listener="#{autoCompleteView.onItemSelect}" update="msgs"/>
</p:autoComplete>
</div>
<div class="p-field p-col-12 p-md-4">
<p:outputLabel value="Empty message" for="@next"/>
<p:autoComplete id="emptyMessage" value="#{autoCompleteView.txt9}"
completeMethod="#{autoCompleteView.noResults}"
emptyMessage="No results" scrollHeight="250">
<p:ajax event="emptyMessageSelect" listener="#{autoCompleteView.onEmptyMessageSelect}"
update="msgs"/>
</p:autoComplete>
</div>
<div class="p-field p-col-12 p-md-4">
<p:outputLabel value="Pojo" for="@next"/>
<p:autoComplete id="pojo" value="#{autoCompleteView.country1}"
completeMethod="#{autoCompleteView.completeCountry}"
var="country" itemLabel="#{country.name}" itemValue="#{country}"
converter="#{countryConverter}" forceSelection="true" scrollHeight="250"/>
</div>
<div class="p-field p-col-12 p-md-4">
<p:outputLabel value="Pojo (via REST)" for="pojoRest"/>
<p:autoComplete id="pojoRest" widgetVar="countryPojoRest" value="#{autoCompleteView.country5}"
var="country" itemLabel="#{country.displayName}" itemValue="#{country}"
converter="#{countryConverter}"
completeEndpoint="#{request.contextPath}/rest/country/autocomplete"
forceSelection="true" emptyMessage="sorry, no suggestions"
moreText="more items available" scrollHeight="250"/>
</div>
<div class="p-field p-col-12 p-md-4">
<p:outputLabel value="Custom Content" for="@next"/>
<p:autoComplete id="countryCustom" value="#{autoCompleteView.country2}"
completeMethod="#{autoCompleteView.completeCountry}"
var="country" itemLabel="#{country.name}" itemValue="#{country}"
converter="#{countryConverter}" forceSelection="true" scrollHeight="250">
<p:column>
<span class="flag flag-#{country.code}" style="width: 30px; height: 20px"/>
<h:outputText style="vertical-align: middle; margin-left: .5rem" value="#{country.name}"/>
</p:column>
</p:autoComplete>
</div>
<div class="p-field p-col-12 p-md-4">
<p:outputLabel value="Itemtip" for="@next"/>
<p:autoComplete id="itemTip" value="#{autoCompleteView.country3}"
completeMethod="#{autoCompleteView.completeCountry}"
var="country" itemLabel="#{country.name}" itemValue="#{country}"
converter="#{countryConverter}" scrollHeight="250">
<f:facet name="itemtip">
<h:panelGrid columns="2" cellpadding="5">
<f:facet name="header">
<span class="flag flag-#{country.code}" style="width: 30px; height: 20px"/>
</f:facet>
<h:outputText value="Name"/>
<h:outputText value="#{country.name}"/>
<h:outputText value="Code"/>
<h:outputText value="#{country.code}"/>
</h:panelGrid>
</f:facet>
</p:autoComplete>
</div>
<div class="p-field p-col-12 p-md-4">
<p:outputLabel value="Group" for="@next"/>
<p:autoComplete id="group" value="#{autoCompleteView.country4}"
completeMethod="#{autoCompleteView.completeCountry}"
var="country" itemLabel="#{country.name}" itemValue="#{country}"
converter="#{countryConverter}" forceSelection="true"
groupBy="#{autoCompleteView.getCountryGroup(country)}" escape="false" scrollHeight="250"/>
</div>
</div>
<h5>Multiple</h5>
<p:autoComplete id="countries" multiple="true" value="#{autoCompleteView.selectedCountries}"
completeMethod="#{autoCompleteView.completeCountry}"
var="country" itemLabel="#{country.name}" itemValue="#{country}"
converter="#{countryConverter}" forceSelection="true" scrollHeight="250">
<p:column>
<span class="flag flag-#{country.code}" style="width: 30px; height: 20px" />
<h:outputText style="vertical-align: middle; margin-left: .5rem" value="#{country.name}"/>
</p:column>
</p:autoComplete>
</h:form>
</div>
@Named
@RequestScoped
public class AutoCompleteView {
private String txt1;
private String txt2;
private String txt3;
private String txt4;
private String txt5;
private String txt6;
private String txt7;
private String txt8;
private String txt9;
private Country country1;
private Country country2;
private Country country3;
private Country country4;
private Country country5;
private List<Country> selectedCountries;
@Inject
private CountryService countryService;
public List<String> completeText(String query) {
String queryLowerCase = query.toLowerCase();
List<String> countryList = new ArrayList<>();
List<Country> countries = countryService.getCountries();
for (Country country : countries) {
countryList.add(country.getName());
}
return countryList.stream().filter(t -> t.toLowerCase().startsWith(queryLowerCase)).collect(Collectors.toList());
}
public List<String> noResults(String query) {
return Collections.EMPTY_LIST;
}
public List<Country> completeCountry(String query) {
String queryLowerCase = query.toLowerCase();
List<Country> countries = countryService.getCountries();
return countries.stream().filter(t -> t.getName().toLowerCase().contains(queryLowerCase)).collect(Collectors.toList());
}
public void onItemSelect(SelectEvent<String> event) {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Country Selected", event.getObject()));
}
public void onEmptyMessageSelect() {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Empty message selected"));
}
public String getTxt1() {
return txt1;
}
public void setTxt1(String txt1) {
this.txt1 = txt1;
}
public String getTxt2() {
return txt2;
}
public void setTxt2(String txt2) {
this.txt2 = txt2;
}
public String getTxt3() {
return txt3;
}
public void setTxt3(String txt3) {
this.txt3 = txt3;
}
public String getTxt4() {
return txt4;
}
public void setTxt4(String txt4) {
this.txt4 = txt4;
}
public String getTxt5() {
return txt5;
}
public void setTxt5(String txt5) {
this.txt5 = txt5;
}
public String getTxt6() {
return txt6;
}
public void setTxt6(String txt6) {
this.txt6 = txt6;
}
public String getTxt7() {
return txt7;
}
public void setTxt7(String txt7) {
this.txt7 = txt7;
}
public String getTxt8() {
return txt8;
}
public void setTxt8(String txt8) {
this.txt8 = txt8;
}
public String getTxt9() {
return txt9;
}
public void setTxt9(String txt9) {
this.txt9 = txt9;
}
public Country getCountry1() {
return country1;
}
public void setCountry1(Country country1) {
this.country1 = country1;
}
public Country getCountry2() {
return country2;
}
public void setCountry2(Country country2) {
this.country2 = country2;
}
public Country getCountry3() {
return country3;
}
public void setCountry3(Country country3) {
this.country3 = country3;
}
public Country getCountry4() {
return country4;
}
public void setCountry4(Country country4) {
this.country4 = country4;
}
public Country getCountry5() {
return country5;
}
public void setCountry5(Country country5) {
this.country5 = country5;
}
public List<Country> getSelectedCountries() {
return selectedCountries;
}
public void setSelectedCountries(List<Country> selectedCountries) {
this.selectedCountries = selectedCountries;
}
public void setCountryService(CountryService countryService) {
this.countryService = countryService;
}
public char getCountryGroup(Country country) {
return country.getName().charAt(0);
}
}
public class Country implements Serializable, Comparable<Country> {
private static final long serialVersionUID = 1L;
private int id;
private String name;
private String code;
private Locale locale;
private boolean rtl;
public Country() {}
public Country(int id, Locale locale) {
this(id, locale.getDisplayCountry(), locale.getCountry().toLowerCase(), locale);
}
public Country(int id, Locale locale, boolean rtl) {
this(id, locale.getDisplayCountry(), locale.getCountry().toLowerCase(), locale);
this.rtl = rtl;
}
public Country(int id, String name, String code) {
this(id, name, code, null);
}
public Country(int id, String name, String code, Locale locale) {
this.id = id;
this.name = name;
this.code = code;
this.locale = locale;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public Locale getLocale() {
return locale;
}
public void setLocale(Locale locale) {
this.locale = locale;
}
public String getLanguage( ) {
return locale == null ? "en" : locale.getLanguage();
}
public String getDisplayLanguage( ) {
return locale == null ? "English" : locale.getDisplayLanguage();
}
public boolean isRtl() {
return rtl;
}
public void setRtl(boolean rtl) {
this.rtl = rtl;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Country country = (Country) o;
return id == country.id &&
Objects.equals(name, country.name) &&
Objects.equals(code, country.code);
}
@Override
public int hashCode() {
return Objects.hash(id, name, code);
}
@Override
public String toString() {
return name;
}
@Override
public int compareTo(Country o) {
return name.compareTo(o.name);
}
}
@Named
@ApplicationScoped
public class CountryService {
private List<Country> countries;
private Map<Integer, Country> countriesAsMap;
private List<Country> locales;
private Map<Integer, Country> localesAsMap;
@PostConstruct
public void init() {
countries = new ArrayList<>();
locales = new ArrayList<>();
String[] isoCodes = Locale.getISOCountries();
for (int i = 0; i < isoCodes.length; i++) {
Locale locale = new Locale("", isoCodes[i]);
countries.add(new Country(i, locale));
}
Collections.sort(countries, (Country c1, Country c2) -> c1.getName().compareTo(c2.getName()));
int i = 0;
locales.add(new Country(i++, Locale.US));
locales.add(new Country(i++, Locale.FRANCE));
locales.add(new Country(i++, Locale.GERMANY));
locales.add(new Country(i++, Locale.ITALY));
locales.add(new Country(i++, new Locale("es", "ES")));
locales.add(new Country(i++, new Locale("ca", "ES")));
locales.add(new Country(i++, new Locale("nl", "NL")));
locales.add(new Country(i++, new Locale("pt", "BR")));
locales.add(new Country(i++, new Locale("pt", "PT")));
locales.add(new Country(i++, new Locale("ar", "SA"), true));
locales.add(new Country(i++, new Locale("cs", "CZ")));
locales.add(new Country(i++, new Locale("el", "GR")));
locales.add(new Country(i++, new Locale("fa", "IR"), true));
locales.add(new Country(i++, new Locale("hi", "IN")));
locales.add(new Country(i++, new Locale("in", "ID")));
locales.add(new Country(i++, new Locale("hr", "HR")));
locales.add(new Country(i++, new Locale("hu", "HU")));
locales.add(new Country(i++, new Locale("iw", "IL"), true));
locales.add(new Country(i++, new Locale("ka", "GE")));
locales.add(new Country(i++, new Locale("lv", "LV")));
locales.add(new Country(i++, new Locale("no", "NO")));
locales.add(new Country(i++, new Locale("pl", "PL")));
locales.add(new Country(i++, new Locale("ro", "RO")));
locales.add(new Country(i++, new Locale("ru", "RU")));
locales.add(new Country(i++, new Locale("sk", "SK")));
locales.add(new Country(i++, new Locale("sl", "SI")));
locales.add(new Country(i++, new Locale("sr", "RS")));
locales.add(new Country(i++, new Locale("sv", "SE")));
locales.add(new Country(i++, new Locale("tr", "TR")));
locales.add(new Country(i++, new Locale("uk", "UA")));
locales.add(new Country(i++, new Locale("vi", "VN")));
locales.add(new Country(i++, Locale.SIMPLIFIED_CHINESE));
locales.add(new Country(i++, 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;
}
}
@Named
@FacesConverter(value = "countryConverter", managed = true)
public class CountryConverter implements Converter<Country> {
@Inject
private CountryService countryService;
@Override
public Country getAsObject(FacesContext context, UIComponent component, String value) {
if (value != null && value.trim().length() > 0) {
try {
return countryService.getCountriesAsMap().get(Integer.parseInt(value));
} catch (NumberFormatException e) {
throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Conversion Error", "Not a valid country."));
}
} else {
return null;
}
}
@Override
public String getAsString(FacesContext context, UIComponent component, Country value) {
if (value != null) {
return String.valueOf(value.getId());
} else {
return null;
}
}
}