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="mt-0">Single</h5>
<div class="formgrid grid">
<div class="field col-12 md:col-4">
<p:outputLabel value="Simple" for="@next"/>
<p:autoComplete id="acSimple" value="#{autoCompleteView.txt1}"
completeMethod="#{autoCompleteView.completeText}" scrollHeight="250"/>
</div>
<div class="field col-12 md:col-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="field col-12 md:col-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="field col-12 md:col-4">
<p:outputLabel value="Max Results(5)" for="@next"/>
<p:autoComplete id="acMaxResults" maxResults="5" value="#{autoCompleteView.txt4}"
completeMethod="#{autoCompleteView.completeText}" scrollHeight="250"
moreText="more items available">
<p:ajax event="moreTextSelect" listener="#{autoCompleteView.onMoreTextSelect}"
update="msgs"/>
</p:autoComplete>
</div>
<div class="field col-12 md:col-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="field col-12 md:col-4">
<p:outputLabel value="DropDown" for="@next"/>
<p:autoComplete id="dd" dropdown="true" value="#{autoCompleteView.txt6}"
completeMethod="#{autoCompleteView.completeText}" scrollHeight="250"/>
</div>
<div class="field col-12 md:col-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="field col-12 md:col-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="field col-12 md:col-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="field col-12 md:col-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="field col-12 md:col-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"
scrollHeight="250"/>
</div>
<div class="field col-12 md:col-4">
<p:outputLabel value="LazyModel" for="lazyModel"/>
<p:autoComplete id="lazyModel" widgetVar="lazyModel" value="#{autoCompleteView.txt11}"
var="customer" itemLabel="#{customer.name}" itemValue="#{customer.name}"
lazyModel="#{autoCompleteView.lazyModel}" lazyField="name"
forceSelection="true" emptyMessage="sorry, no suggestions"
maxResults="10"/>
</div>
<div class="field col-12 md:col-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="field col-12 md:col-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="field col-12 md:col-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 class="field col-12 md:col-4">
<p:outputLabel value="Footer" for="@next"/>
<p:autoComplete id="acFooter" value="#{autoCompleteView.txt10}"
completeMethod="#{autoCompleteView.completeText}"
maxResults="10" emptyMessage="No results">
<f:facet name="footer">
<div class="ui-fluid" style="padding:0.5rem 1rem 1rem 1rem">
<p:button value="Add new" onclick="alert('This could open a dialog')"/>
</div>
</f:facet>
</p:autoComplete>
</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
@ViewScoped
public class AutoCompleteView implements Serializable {
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 String txt10;
private String txt11;
private Country country1;
private Country country2;
private Country country3;
private Country country4;
private Country country5;
private List<Country> selectedCountries;
private LazyDataModel<Customer> lazyModel;
@Inject
private CountryService countryService;
@Inject
private CustomerService service;
@PostConstruct
public void init() {
lazyModel = new LazyCustomerDataModel(service.getCustomers(200));
}
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.emptyList();
}
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 void onMoreTextSelect() {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("More text 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 String getTxt10() {
return txt10;
}
public void setTxt10(String txt10) {
this.txt10 = txt10;
}
public String getTxt11() {
return txt11;
}
public void setTxt11(String txt11) {
this.txt11 = txt11;
}
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 LazyDataModel<Customer> getLazyModel() {
return lazyModel;
}
}
public class Country implements Serializable, Comparable<Country> {
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++, Locale.KOREA));
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("lt", "LT")));
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
@ApplicationScoped
public class CustomerService {
private Random random = new SecureRandom();
private Country[] countries;
private Representative[] representatives;
private String[] firstNames;
private String[] lastNames;
private String[] companies;
@PostConstruct
public void init() {
countries = new Country[]{
new Country(0, "Argentina", "ar"),
new Country(1, "Australia", "au"),
new Country(2, "Brazil", "br"),
new Country(3, "Canada", "ca"),
new Country(4, "Germany", "de"),
new Country(5, "France", "fr"),
new Country(6, "India", "in"),
new Country(7, "Italy", "it"),
new Country(8, "Japan", "jp"),
new Country(9, "Russia", "ru"),
new Country(10, "Spain", "es"),
new Country(11, "United Kingdom", "gb")};
companies = new String[]{"Benton, John B Jr", "Chanay, Jeffrey A Esq", "Chemel, James L Cpa", "Feltz Printing Service",
"Printing Dimensions", "Chapman, Ross E Esq", "Morlong Associates", "Commercial Press", "Truhlar And Truhlar Attys",
"King, Christopher A Esq", "Dorl, James J Esq", "Rangoni Of Florence", "Feiner Bros", "Buckley Miller Wright",
"Rousseaux, Michael Esq"};
representatives = new Representative[]{
new Representative("Amy Elsner", "amyelsner.png"),
new Representative("Anna Fali", "annafali.png"),
new Representative("Asiya Javayant", "asiyajavayant.png"),
new Representative("Bernardo Dominic", "bernardodominic.png"),
new Representative("Elwin Sharvill", "elwinsharvill.png"),
new Representative("Ioni Bowcher", "ionibowcher.png"),
new Representative("Ivan Magalhaes", "ivanmagalhaes.png"),
new Representative("Onyama Limba", "onyamalimba.png"),
new Representative("Stephen Shaw", "stephenshaw.png"),
new Representative("Xuxue Feng", "xuxuefeng.png")};
firstNames = new String[]{"James", "David", "Jeanfrancois", "Ivar", "Tony",
"Adams", "Claire", "Costa", "Juan", "Maria", "Jennifer",
"Stacey", "Leja", "Morrow", "Arvin", "Darci", "Izzy",
"Ricardo", "Clifford", "Emily", "Kadeem", "Mujtaba", "Aika",
"Mayumi", "Misaki", "Silvio", "Nicolas", "Antonio",
"Deepesh", "Aditya", "Aruna", "Jones", "Julie", "Smith",
"Johnson", "Francesco", "Salvatore", "Kaitlin", "Faith",
"Maisha", "Jefferson", "Leon", "Rodrigues", "Alejandro",
"Munro", "Cody", "Chavez", "Sinclair", "Isabel", "Octavia",
"Murillo", "Greenwood", "Wickens", "Ashley"};
lastNames = new String[]{"Butt", "Darakjy", "Venere", "Paprocki", "Foller",
"Morasca", "Tollner", "Dilliard", "Wieser", "Marrier", "Amigon",
"Maclead", "Caldarera", "Ruta", "Albares", "Poquette", "Garufi",
"Gaucho", "Rim", "Whobrey", "Flosi", "Nicka", "Inouye",
"Kolmetz", "Royster", "Slusarski", "Iturbide", "Caudy",
"Chui", "Kusko", "Figeroa", "Vocelka", "Stenseth", "Glick",
"Sergi", "Shinko", "Stockham", "Ostrosky", "Gillian",
"Rulapaugh", "Schemmer", "Oldroyd", "Campain", "Perin",
"Ferencz", "Saylors", "Briddick", "Waycott", "Bowley", "Malet",
"Malet", "Bolognia", "Nestle", "Doe"};
}
public List<Customer> getCustomers(int number) {
List<Customer> customers = new ArrayList<>();
for (int i = 0; i < number; i++) {
customers.add(
new Customer(i + 1000, getName(), getCompany(), getCountry(), getDate(),
CustomerStatus.random(), getActivity(), getRepresentative()));
}
return customers;
}
public List<Country> getCountries() {
return Arrays.asList(countries);
}
public CustomerStatus[] getCustomerStatus() {
return CustomerStatus.values();
}
public List<Representative> getRepresentatives() {
return Arrays.asList(representatives);
}
private String getName() {
return firstNames[random.nextInt(firstNames.length)] + Constants.SPACE
+ (char) (random.nextInt(26) + 'A') + Constants.SPACE
+ lastNames[random.nextInt(lastNames.length)];
}
private Country getCountry() {
return countries[random.nextInt(countries.length)];
}
private String getCompany() {
return companies[random.nextInt(companies.length)];
}
private LocalDate getDate() {
LocalDate now = LocalDate.now();
long randomDay = ThreadLocalRandom.current().nextLong(now.minusDays(30).toEpochDay(), now.toEpochDay());
return LocalDate.ofEpochDay(randomDay);
}
private int getActivity() {
return random.nextInt(100);
}
private Representative getRepresentative() {
return representatives[random.nextInt(representatives.length)];
}
}
@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;
}
}
}