forevernewb123
forevernewb123

Reputation: 11

Thymeleaf dropdown not populating

I have a simple Enum which will contain various locales:

public enum LocaleEnum {
en_US,es_MX;

private static EnumMap<LocaleEnum, String> map = new EnumMap<LocaleEnum, String>(LocaleEnum.class);

// Pre-load the descriptive values.  Will pull the descriptive value from a property file later.
static {
    String desc = "English";
    for (LocaleEnum locale : LocaleEnum.values()) {
        map.put(locale, desc);
        desc = "Espanol";
    }
}

public static EnumMap<LocaleEnum, String> getMap() {
    return map;
}

}

I then have a method on a model to pass the EnumMap to the view:

public EnumMap<LocaleEnum, String> getLocales() {
    EnumMap<LocaleEnum, String> map = LocaleEnum.getMap();
    return map;
}

I am now trying to display those values in a dropdown using Thymeleaf:

<select th:field="*{locales}">
    <option value="NONE">---- Select ----</option>
    <option th:each="locale : ${locales}"
            th:value="${locale.key}"
            th:text="${locale.value}">Englishy</option>
</select>

I get the "---- Select ----" in the dropdown. In debug mode, I see the getLocales() method getting called along with the values in the EnumMap.

However, there is nothing else in the dropdown. I keep comparing my implementation to various others, but I'm not seeing my failure. All thoughts are more than welcome. Thanks.

Upvotes: 0

Views: 4203

Answers (3)

forevernewb123
forevernewb123

Reputation: 11

Thanks OhioCowboy & Wundwin I really appreciate your help with this.

I finally figured out what I was doing wrong. All I needed to do was change:

<option th:each="locale : ${locales}"

to

<option th:each="locale : *{locales}"

Which now that I'm getting to understand the markup, makes sense.

Upvotes: 1

Wundwin Born
Wundwin Born

Reputation: 3475

How try map with <String, String> types?

LocaleEnum

public enum LocaleEnum {
    EN_US("en_US", "English"), ES_MX("es_MX", "Espanol");

    private final String locale;
    private final String lang;

    LocaleEnum(String locale, String lang) {
        this.locale = locale;
        this.lang = lang;
    }

    public String getLocale() {
        return locale;
    }
    public String getLang() {
        return lang;
    }

    public static Map<String, String> getLocalesAsMap() {
        Map<String, String> localeMap = new HashMap<String, String>();
        localeMap.put(EN_US.getLocale(), EN_US.getLang());
        localeMap.put(ES_MX.getLocale(), ES_MX.getLang());
        return localeMap;
    }
}

Model to pass enum values to page

public Map<String, String> getLocales() {        
    return LocaleEnum.getLocalesAsMap();
}

Dropdown on Thymeleaf page

In the case Iterable, let's iterate map's entries with locales.entrySet()

<select th:field="*{locales}">
    <option value="NONE">---- Select ----</option>
    <option th:each="locale : ${locales.entrySet()}"
        th:value="${locale.key}"
        th:text="${locale.value}">Englishy</option>
</select>

Upvotes: 1

ndrone
ndrone

Reputation: 3582

Here is a solution that uses your enum more effectively. I see why your using map so you can pass the whole collection, but there is a better way using .values() see below

public enum LocaleEnum
{
    en_US("en_US", "English"), es_MX("es_MX", "Espanol");

    private final String locale;
    private final String desc;

    LocaleEnum(String locale, String desc)
    {
         this.locale = locale;
         this.desc = desc;
    }

    public String getLocale()
    {
        return locale;
    }

    public String getDesc()
    {
        return desc;
    }
}

Then change your method that adds the enum to the model to. Note .values() is a static method for enums that returns an array.

public LocaleEnum getLocales()
{
    return LocaleEnum.values();
}

so then your thymeleaf page then looks like

<select th:field="*{locales}">
    <option value="NONE">---- Select ----</option>
    <option th:each="locale : ${locales}"
            th:value="${locale.getLocale()}"
            th:text="${locale.getDesc()}">Englishy</option>
</select>

Upvotes: 1

Related Questions