Enhanced user experience with the powerful and easy to use Ajax Framework.
<div class="card">
    <h:form>
        <h5 class="mt-0">Basic</h5>
        <h:panelGrid columns="3" cellpadding="7">
            <p:outputLabel for="name" value="Name"/>
            <p:inputText id="name" value="#{basicView.text1}"/>
            <h:outputText id="display" value="#{basicView.text1}"/>
        </h:panelGrid>
        <p:commandButton value="Submit" update="display" styleClass="mt-3" />
    </h:form>
</div>
<div class="card">
    <h:form>
        <h5 class="mt-0">Action Listener</h5>
        <h:panelGrid columns="2" cellpadding="7">
            <h:outputText value="Counter: "/>
            <h:outputText id="output" value="#{basicView.number}"/>
        </h:panelGrid>
        <p:commandButton value="Increment" action="#{basicView.increment}" update="output" styleClass="mt-3"/>
    </h:form>
</div>
<div class="card">
    <h:form>
        <h5 class="mt-0">Events</h5>
        <h:panelGrid columns="3" cellpadding="7">
            <p:outputLabel for="@next" value="KeyUp"/>
            <p:inputText id="firstname" value="#{basicView.text2}">
                <p:ajax event="keyup" update="display2" process="@this"/>
            </p:inputText>
            <h:outputText id="display2" value="#{basicView.text2}"/>
            <p:outputLabel for="@next" value="Blur"/>
            <p:inputText id="middlename" value="#{basicView.text3}">
                <p:ajax event="blur" update="display3"/>
            </p:inputText>
            <h:outputText id="display3" value="#{basicView.text3}"/>
            <p:outputLabel for="@next" value="Input"/>
            <p:inputText id="lastname" value="#{basicView.text4}">
                <p:ajax event="input" update="display4"/>
            </p:inputText>
            <h:outputText id="display4" value="#{basicView.text4}"/>
        </h:panelGrid>
        <h5>Listener</h5>
        <h:panelGrid columns="3" cellpadding="7">
            <p:outputLabel for="@next" value="Keyup"/>
            <p:inputText id="counter" value="#{basicView.text5}">
                <p:ajax event="keyup" update="display5" listener="#{basicView.handleKeyEvent}"/>
            </p:inputText>
            <h:outputText id="display5" value="#{basicView.text5}"/>
        </h:panelGrid>
    </h:form>
</div>
<div class="card">
    <h:form>
        <h5 class="mt-0">Advanced</h5>
        <p:growl id="msgs" showDetail="true" skipDetailIfEqualsSummary="true"/>
        <h:panelGrid columns="2" cellpadding="7" styleClass="mb-3">
            <p:outputLabel for="country" value="Country"/>
            <p:selectOneMenu id="country" value="#{basicView.country}" style="width:12rem">
                <p:ajax listener="#{basicView.onCountryChange}" update="city"/>
                <f:selectItem itemLabel="Select Country" itemValue="" noSelectionOption="true"/>
                <f:selectItems value="#{basicView.countries}"/>
            </p:selectOneMenu>
            <p:outputLabel for="city" value="City"/>
            <p:selectOneMenu id="city" value="#{basicView.city}" style="width:12rem">
                <f:selectItem itemLabel="Select City" itemValue="" noSelectionOption="true"/>
                <f:selectItems value="#{basicView.cities}"/>
            </p:selectOneMenu>
        </h:panelGrid>
        <p:commandButton value="Submit" update="msgs" action="#{basicView.displayLocation}" icon="pi pi-check"/>
    </h:form>
</div>
package org.primefaces.showcase.view.ajax;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import jakarta.annotation.PostConstruct;
import jakarta.faces.application.FacesMessage;
import jakarta.faces.context.FacesContext;
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Named;
@Named
@ViewScoped
public class BasicView implements Serializable {
    private String text1;
    private String text2;
    private String text3;
    private String text4;
    private String text5;
    private int number;
    private Map<String, Map<String, String>> data = new HashMap<>();
    private String country;
    private String city;
    private Map<String, String> countries;
    private Map<String, String> cities;
    @PostConstruct
    public void init() {
        countries = new HashMap<>();
        countries.put("USA", "USA");
        countries.put("Germany", "Germany");
        countries.put("Brazil", "Brazil");
        Map<String, String> map = new HashMap<>();
        map.put("New York", "New York");
        map.put("San Francisco", "San Francisco");
        map.put("Denver", "Denver");
        data.put("USA", map);
        map = new HashMap<>();
        map.put("Berlin", "Berlin");
        map.put("Munich", "Munich");
        map.put("Frankfurt", "Frankfurt");
        data.put("Germany", map);
        map = new HashMap<>();
        map.put("Sao Paulo", "Sao Paulo");
        map.put("Rio de Janerio", "Rio de Janerio");
        map.put("Salvador", "Salvador");
        data.put("Brazil", map);
    }
    public void increment() {
        number++;
    }
    public void handleKeyEvent() {
        if (text5 != null) {
            text5 = text5.toUpperCase();
        }
    }
    public String getText1() {
        return text1;
    }
    public void setText1(String text1) {
        this.text1 = text1;
    }
    public String getText2() {
        return text2;
    }
    public void setText2(String text2) {
        this.text2 = text2;
    }
    public String getText3() {
        return text3;
    }
    public void setText3(String text3) {
        this.text3 = text3;
    }
    public String getText4() {
        return text4;
    }
    public void setText4(String text4) {
        this.text4 = text4;
    }
    public String getText5() {
        return text5;
    }
    public void setText5(String text5) {
        this.text5 = text5;
    }
    public int getNumber() {
        return number;
    }
    public Map<String, Map<String, String>> getData() {
        return data;
    }
    public String getCountry() {
        return country;
    }
    public void setCountry(String country) {
        this.country = country;
    }
    public String getCity() {
        return city;
    }
    public void setCity(String city) {
        this.city = city;
    }
    public Map<String, String> getCountries() {
        return countries;
    }
    public Map<String, String> getCities() {
        return cities;
    }
    public void onCountryChange() {
        if (country != null && !"".equals(country)) {
            cities = data.get(country);
        }
        else {
            cities = new HashMap<>();
        }
    }
    public void displayLocation() {
        FacesMessage msg;
        if (city != null && country != null) {
            msg = new FacesMessage("Selected", city + " of " + country);
        }
        else {
            msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Invalid", "City is not selected.");
        }
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }
}