0

I am practicing using ajax jsf and I have the following code to build the view.

  <f:view contentType="text/html;charset=UTF-8" encoding="UTF-8">
    <h:head>
        <title>Advances Ajax Effect</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    </h:head>
    <h:body>
        <h1>Advanced</h1>
        <h:form>
            <h:messages id="msgs" class="msgs" showDetail="true" globalOnly="true"/>
            <h:panelGrid columns="2" cellspacing="7">
                <h:outputLabel for="country" value="Country"/>
                <h:selectOneMenu id="country" value="#{basicView.country}" style="width: 12rem;">
                    <f:ajax event="change" execute="@this" render="city" listener="#{basicView.onChangeCountry}"/>
                    <f:selectItem itemLabel="--Select Country--" itemValue="" noSelectionOption="true"/>
                    <f:selectItems value="#{basicView.countries}"/>                 
                </h:selectOneMenu>
                
                <h:outputLabel for="city" value="City"/>
                <h:selectOneMenu id="city" value="#{basicView.city}" style="width: 12rem;">
                    <f:selectItem itemLabel="--Select City--" itemValue="" noSelectionOption="true"/>
                    <f:selectItems value="#{basicView.cities}"/>
                </h:selectOneMenu>
            </h:panelGrid>
            <h:commandButton value="Submit">
                <f:ajax execute="city" render="msgs" listener="#{basicView.displayLocation}"/>
            </h:commandButton>
        </h:form>
    </h:body>
</f:view>

The goal of this code is simple; I am only dynamically and asynchronously filling the content of a selectOneMenu depending on the country that is chosen in the previous selectOneMenu. For example: if the user selects the USA country, the City Menu will be filled automatically with a list of cities belonging to the USA, the same happens if he chooses Germany or Brazil. Once the country and city have been selected, pressing the submit button displays a global message to the user confirming their choice.

enter image description here

as shown in the picture above I also attach the code of the backing bean

public class BasicView {

private String country;
private String city;
private Map<String, String> countries;
private Map<String, String> cities;
private Map<String, Map<String, String>> data;

public BasicView(){}

@PostConstruct
public void init(){
    countries = new HashMap<>();
    cities = new HashMap<>();
    data = new HashMap<>();
    
    countries.put("USA", "USA");
    countries.put("Germany", "Germany");
    countries.put("Brazil", "Brazil");
    
    Map<String, String> map = new HashMap<>();
    map.put("San Francisco", "San Francisco");
    map.put("New York", "New york");
    map.put("Denver", "Denver");
    
    //USA cities added
    data.put("USA", map);
    
    map = new HashMap<>();
    map.put("Frankfurt", "Frankfurt");
    map.put("Berlin", "Berlin");
    map.put("Munich", "Munich");
    
    //Germany cities added
    data.put("Germany", map);
    
    map = new HashMap<>();
    map.put("Sao Paulo", "Sao Paulo");
    map.put("Rio de Janeiro", "Rio de Janeiro");
    map.put("Salvador", "Salvador");
    
    //Brazil cities added
    data.put("Brazil", map);
}

public void onChangeCountry(AjaxBehaviorEvent event){
    if(country != null && !country.equals("")){
        cities = data.get(country);
    }
}

public void displayLocation(AjaxBehaviorEvent event){
    FacesMessage msg;
    if(country != null && city != null){
        msg = new FacesMessage("Selected", city + " of " + country);
        //add styles to the component that will display the aproval message
    }
    else{
        msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Invalid", "City is not Selected.");
        //add styles to the component that will display the error message
    }
    
    FacesContext.getCurrentInstance().addMessage(null, msg);
}

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 void setCountries(Map<String, String> countries) {
    this.countries = countries;
}

public Map<String, String> getCities() {
    return cities;
}

public void setCities(Map<String, String> cities) {
    this.cities = cities;
}

public Map<String, Map<String, String>> getData() {
    return data;
}

public void setData(Map<String, Map<String, String>> data) {
    this.data = data;
}
 
}

What I'm looking to do is that when the displayLocation method is executed and the message that the user will see is created, I can somehow modify the classes of my <h: messages> component. If the message is confirmation, add the confirmation class "<h: messages class = 'confirm'>" to the component, but if the message is an error message, you can add the error class "<h: message class =" error "> and in this way to be able to assign a specific style for each particular message.

Does anyone know the way to be able to modify the attributes of any component in jsf from a backing bean? I appreciate any help

Jasper de Vries
  • 16,868
  • 6
  • 60
  • 93
  • Does this answer your question? [Showing the JSF Error Messages](https://stackoverflow.com/questions/3186659/showing-the-jsf-error-messages) – Jasper de Vries Dec 25 '21 at 08:59

0 Answers0