Wednesday, October 1, 2003

Using a reusable code approach to HTML select option lists: part II


By Jeff Chilton

"It is best to do things systematically, since we are only human, and disorder is our worst enemy."
-- Hesiod (ancient Greek poet, circa 850 B.C.)

In the first installment of this series, we created a simple framework for the purpose of obtaining an ArrayList of Struts LabelValueBeans to support an html:options tag. To continue with this little microcosm of framework concepts, we're going to go back and tinker with what we've already created and then add another flavor of an implementing class to our portfolio. Finally, we will modify our core components to add some additional functionality that both our original implementing class and our new implementing class will be able to inherit without any further modification to either.

Incremental improvement #1: enhancing what we have

In the final phase of Part I, we created our SimpleOptionListSource class, which took as a data source a String containing a comma-separated list of values. This class extended our abstract OptionListSourceBase class, which implemented our OptionListSource interface. One of the assumptions that we made at the time, in order to keep things as simple as possible, was that both the label and the value would be the same. With just a slight modification and the adoption of a specific syntax, we can enhance this module to accept label/value pairs instead of just values, yet still retain the original functionality for those utilizations that only pass a single value.

Listing 1 contains our new and improved SimpleOptionListSource class, which will now accept both single values and label/value pairs separated by the colon (":") character.

package step.two;

import java.util.ArrayList;
import java.util.StringTokenizer;

import org.apache.struts.util.LabelValueBean;

 * Returns the name/value pairs for the options related to an HTML
 * "select" tag.
 * Source data for this implementation is obtained directly from the
 * option list string provided.
public class SimpleOptionListSource extends OptionListSourceBase {
        private String optionList = null;

         * Constructs a new "SimpleOptionListSource" object using the parameters
         * provided.
         * @param optionList a String containing the comma separated values for
         * the option list
        public SimpleOptionListSource(String optionList) {
                this.optionList = optionList;

         * Loads the list of available options from the optionList
         * String passed to the constructor.
        protected void loadOptions() {
                ArrayList list = new ArrayList();

                StringTokenizer tokens = new StringTokenizer (optionList, ",");
                for (int i = 0; i < tokens.countTokens(); i++) {
                        String thisItem = tokens.nextToken();
                        LabelValueBean thisOption = new LabelValueBean(thisItem, thisItem);
                        int x = thisItem.indexOf(":");
                        if (x > -1) {
                                String label = thisItem.substring(0, x);
                                String value = thisItem.substring(x + 1);
                                thisOption = new LabelValueBean(label, value);