SelectManyCheckbox is used to choose multiple items from a collection.
<style>
    .grid-checkbox td {
        padding: .5rem;
    }
</style>
<div class="card">
    <h:form>
        <p:growl>
            <p:autoUpdate />
        </p:growl>
        
        <h5 style="margin-top:0px">Basic Layout</h5>
        <p:selectManyCheckbox id="basicAjax" value="#{checkboxView.selectedOptions}" widgetVar="blub">
            <p:ajax listener="#{checkboxView.selectedOptionsChanged}" />
            <f:selectItem itemLabel="Option 1" itemValue="Option 1"/>
            <f:selectItem itemLabel="Option 2" itemValue="Option 2"/>
            <f:selectItem itemLabel="Option 3" itemValue="Option 3"/>
        </p:selectManyCheckbox>
        
        <h5>Responsive</h5>
        <p:selectManyCheckbox id="grid2" value="#{checkboxView.selectedCities2}" layout="responsive"
                              columns="3">
            <f:selectItems value="#{checkboxView.cities}" var="city" itemLabel="#{city}" itemValue="#{city}"/>
        </p:selectManyCheckbox>
        <h5>Line Direction</h5>
        <p:selectManyCheckbox id="lineDirection" value="#{checkboxView.selectedCities}" layout="lineDirection">
            <f:selectItems value="#{checkboxView.cities}" var="city" itemLabel="#{city}" itemValue="#{city}"/>
        </p:selectManyCheckbox>
        
        <h5>Page Direction</h5>
        <p:selectManyCheckbox id="pageDirection" value="#{checkboxView.selectedCities}" layout="pageDirection">
            <f:selectItems value="#{checkboxView.cities}" var="city" itemLabel="#{city}" itemValue="#{city}"/>
        </p:selectManyCheckbox>
        <h5>Custom Layout</h5>
        <p:outputPanel id="customPanel">
            <p:selectManyCheckbox id="custom" value="#{checkboxView.selectedOptions2}" layout="custom">
                <p:ajax listener="#{checkboxView.selectedOptions2Changed}" />
                <f:selectItem itemLabel="Option 1" itemValue="Option 1"/>
                <f:selectItem itemLabel="Option 2" itemValue="Option 2"/>
                <f:selectItem itemLabel="Option 3" itemValue="Option 3"/>
            </p:selectManyCheckbox>
            <div class="grid text-center">
                <div class="col">
                    <p:outputLabel for="opt1" value="Option 1" styleClass="block mb-2"/>
                    <p:checkbox id="opt1" for="custom" itemIndex="0"/>
                </div>
                
                <div class="col">
                    <p:outputLabel for="opt2" value="Option 2" styleClass="block mb-2"/>
                    <p:checkbox id="opt2" for="custom" itemIndex="1"/>
                </div>
                <div class="col">
                    <p:outputLabel for="opt3" value="Option 3" styleClass="block mb-2"/>
                    <p:checkbox id="opt3" for="custom" itemIndex="2"/>
                </div>
            </div>
        </p:outputPanel>
        <h5>Grouped</h5>
        <p:selectManyCheckbox id="grid3" value="#{checkboxView.selectedCountries}" layout="pageDirection"
                              columns="1" styleClass="grid-checkbox">
            <f:selectItems value="#{checkboxView.countries}" var="country" itemLabel="#{country}"
                           itemValue="#{country}"/>
        </p:selectManyCheckbox>
    </h:form>
</div>
package org.primefaces.showcase.view.input;
import org.primefaces.event.SelectEvent;
import org.primefaces.event.ToggleSelectEvent;
import org.primefaces.event.UnselectEvent;
import org.primefaces.showcase.domain.Country;
import org.primefaces.showcase.service.CountryService;
import java.util.ArrayList;
import java.util.List;
import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.RequestScoped;
import jakarta.faces.application.FacesMessage;
import jakarta.faces.context.FacesContext;
import jakarta.faces.model.SelectItem;
import jakarta.faces.model.SelectItemGroup;
import jakarta.inject.Inject;
import jakarta.inject.Named;
@Named
@RequestScoped
public class CheckboxView {
    private String[] selectedOptions;
    private String[] selectedOptions2;
    private String[] selectedCities;
    private String[] selectedCities2;
    private List<String> cities;
    private List<SelectItem> countries;
    private String[] selectedCountries;
    private List<Country> countries2;
    private List<Country> selectedCountries2;
    private List<SelectItem> countries3;
    private List<Country> selectedCountries3;
    @Inject
    private CountryService service;
    @PostConstruct
    public void init() {
        cities = new ArrayList<>();
        cities.add("Miami");
        cities.add("London");
        cities.add("Paris");
        cities.add("Istanbul");
        cities.add("Berlin");
        cities.add("Barcelona");
        cities.add("Rome");
        cities.add("Brasilia");
        cities.add("Amsterdam");
        countries = new ArrayList<>();
        SelectItemGroup europeCountries = new SelectItemGroup("European Countries");
        europeCountries.setSelectItems(new SelectItem[]{
            new SelectItem("Germany", "Germany"),
            new SelectItem("Turkey", "Turkey"),
            new SelectItem("Spain", "Spain")
        });
        SelectItemGroup americaCountries = new SelectItemGroup("American Countries");
        americaCountries.setSelectItems(new SelectItem[]{
            new SelectItem("United States", "United States"),
            new SelectItem("Brazil", "Brazil"),
            new SelectItem("Mexico", "Mexico")
        });
        countries.add(europeCountries);
        countries.add(americaCountries);
        countries2 = service.getCountries();
        countries3 = new ArrayList<>();
        SelectItemGroup europeCountries3 = new SelectItemGroup("European Countries");
        europeCountries3.setSelectItems(isoCodesToSelectItemArray("DE", "TR", "ES"));
        SelectItemGroup americaCountries3 = new SelectItemGroup("American Countries");
        americaCountries3.setSelectItems(isoCodesToSelectItemArray("US", "BR", "MX"));
        countries3.add(europeCountries3);
        countries3.add(americaCountries3);
    }
    public String[] getSelectedOptions() {
        return selectedOptions;
    }
    public void setSelectedOptions(String[] selectedOptions) {
        this.selectedOptions = selectedOptions;
    }
    public String[] getSelectedOptions2() {
        return selectedOptions2;
    }
    public void setSelectedOptions2(String[] selectedOptions2) {
        this.selectedOptions2 = selectedOptions2;
    }
    public String[] getSelectedCities() {
        return selectedCities;
    }
    public void setSelectedCities(String[] selectedCities) {
        this.selectedCities = selectedCities;
    }
    public String[] getSelectedCities2() {
        return selectedCities2;
    }
    public void setSelectedCities2(String[] selectedCities2) {
        this.selectedCities2 = selectedCities2;
    }
    public List<String> getCities() {
        return cities;
    }
    public void setCities(List<String> cities) {
        this.cities = cities;
    }
    public List<SelectItem> getCountries() {
        return countries;
    }
    public void setCountries(List<SelectItem> countries) {
        this.countries = countries;
    }
    public String[] getSelectedCountries() {
        return selectedCountries;
    }
    public void setSelectedCountries(String[] selectedCountries) {
        this.selectedCountries = selectedCountries;
    }
    public List<Country> getCountries2() {
        return countries2;
    }
    public void setCountries2(List<Country> countries2) {
        this.countries2 = countries2;
    }
    public List<Country> getSelectedCountries2() {
        return selectedCountries2;
    }
    public void setSelectedCountries2(List<Country> selectedCountries2) {
        this.selectedCountries2 = selectedCountries2;
    }
    public List<SelectItem> getCountries3() {
        return countries3;
    }
    public void setCountries3(List<SelectItem> countries3) {
        this.countries3 = countries3;
    }
    public List<Country> getSelectedCountries3() {
        return selectedCountries3;
    }
    public void setSelectedCountries3(List<Country> selectedCountries3) {
        this.selectedCountries3 = selectedCountries3;
    }
    public void onToggleSelect(ToggleSelectEvent event) {
        FacesMessage msg = new FacesMessage();
        msg.setSummary("Toggled: " + event.isSelected());
        msg.setSeverity(FacesMessage.SEVERITY_INFO);
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }
    public void onItemSelect(SelectEvent event) {
        FacesMessage msg = new FacesMessage();
        msg.setSummary("Item selected: " + event.getObject().toString());
        msg.setSeverity(FacesMessage.SEVERITY_INFO);
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }
    public void onItemUnselect(UnselectEvent event) {
        FacesMessage msg = new FacesMessage();
        msg.setSummary("Item unselected: " + event.getObject().toString());
        msg.setSeverity(FacesMessage.SEVERITY_INFO);
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }
    public void selectedOptionsChanged() {
        String message = "selectedOptions changed to: ";
        if (selectedOptions != null) {
            for (int i = 0; i < selectedOptions.length; i++) {
                if (i > 0) {
                    message += ", ";
                }
                message += selectedOptions[i];
            }
        }
        FacesContext.getCurrentInstance().addMessage(null,
                new FacesMessage(FacesMessage.SEVERITY_INFO, message, null));
    }
    public void selectedOptions2Changed() {
        String message = "selectedOptions2 changed to: ";
        if (selectedOptions2 != null) {
            for (int i = 0; i < selectedOptions2.length; i++) {
                if (i > 0) {
                    message += ", ";
                }
                message += selectedOptions2[i];
            }
        }
        FacesContext.getCurrentInstance().addMessage(null,
                new FacesMessage(FacesMessage.SEVERITY_INFO, message, null));
    }
    private SelectItem[] isoCodesToSelectItemArray(String... isoCodes) {
        return CountryService.toCountryStream(isoCodes)
                .map(country -> new SelectItem(country, country.getName()))
                .toArray(SelectItem[]::new);
    }
}
package org.primefaces.showcase.domain;
import java.io.Serializable;
import java.util.Locale;
import java.util.Objects;
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);
    }
}
package org.primefaces.showcase.service;
import org.primefaces.showcase.domain.Country;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Named;
@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("bn", "BD")));
        locales.add(CountryService.toCountry(new Locale("bs", "BA")));
        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("uz", "UZ")));
        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;
    }
}