Country and State in Vaadin

In my ongoing tinkering with the Vaadin web framework, I had a need to build a country and state/province dropdown, much like you see on almost every e-commerce site out there.

Unlike the typical pair of these fields, however, I wanted mine to work correctly – that is, for the list of provinces or states to reflect the currently selected country automatically.

Simple as this sounds, it’s an exercise I’ve done many many times in too many different frameworks and technologies to count, and it’s never quite as easy it as seems like it ought to be. As you can see, many sites give up, and simply have a combined list of all states and Canadian provinces, or some such hack. I’ve never actually seen one that changes the name of the “State” field to “Province” when Canada is selected as the country, for instance.

So I set out to try this in Vaadin, and was pleasantly surprised.

Let’s assume we’re building a Form object in Vaadin. We can add our “country” drop down select box by saying this:

 <code>
        Select country = new Select("Country:");
        country.addItem("[Unspecified]");
        country.addItem("United States");
        country.addItem("Canada");
        country.addItem("Afganistan");
        form.addField("country", country);
</code>

Of course, we’d probably want our list of countries to come from some other data source, like a property file or static list, but this gives you the idea.

Now we add our “state” drop-down:

 <code>
        final Select state = new Select("State:");
        form.addField("state", state);
</code>

Now we must decide whether to populate the state with actual U.S. States or Canadian provinces….

 <code>
        country.addListener(new Property.ValueChangeListener() {
            public void valueChange(Property.ValueChangeEvent valueChangeEvent) {
                String selectedCountry = valueChangeEvent.getProperty().getValue().toString();
                if (selectedCountry.equals("United States")) {
                    state.setCaption("State:");
                    state.removeAllItems();
                    state.addItem("Alabama");
                    state.addItem("Texas");
                    state.addItem("Idaho");
                } else if (selectedCountry.equals("Canada")) {
                    state.setCaption("Province:");
                    state.removeAllItems();
                    state.addItem("Alberta");
                    state.addItem("Saskatchewan");
                    state.addItem("Manitoba");
                }
                state.requestRepaint();
            }
        });
</code>

So our fields before we select a country look like this:
country state1 Country and State in Vaadin

Now we’ve got a “state” field that will change it’s title to “Province:” if the country we select is Canada, and populate itself with the appropriate list of the provinces.
country state canada selected Country and State in Vaadin

But switch right back to “State” and populate the dropdown accordingly if we change our minds and select United States again…

country state back to state Country and State in Vaadin

Not too difficult, and very easy to understand and extend to other situations (or countries).

As with all Vaadin, it’s pure Java, fully testable (at the Unit level, as well as at the functional level). In fact for the “real” version of this (which reads it’s countries and such from property files), I was even able to easily TDD it, which often isn’t the case in UI technologies.

Principles and Practices

Tired of the Software Development Grind? Know it can be done better? Check out my book: Principles and Practices of Software Craftsmanship or sign up for my Craftsmanship Dispatches newsletter.

Published: November 25 2009