Home > FAQs > Cookbook > Tabular inputs with HashMap

Intro

I have a need to enter tabular data, like marks from a list of examination candidates.

This is how it's done :

the mark.vm file..

#foreach ( $candidate in $candidateList )
  #tag( TextField "label=" "name=marks['$candidate.id']" "value='$candidate.mark'" "size=3" )
#end

the SaveMarksAction


public class SaveMarksAction extends ActionSupport {
	private Map marks = new HashMap();

	public Map getMarks() {
		return marks;
	}


	public String execute() throws Exception {
		// get list of candidate IDs
		List candidateIds = marks.keySet();

		for (Iterator iter = candidateIds.iterator(); iter.hasNext();) {
			String candidateId = (String) iter.next();
			String mark = parseMap(marks.get(candidateId));

			// process candidates and marks...
		}

	}

	// helper function to parse the map of entries....
	private static String parseMap(String[] map) {
		if (map == null) {
			return null;
		}
		if (map.length != 1) {
			return null;
		}
		return map[0];
	}


}

Explanation

The resulting vm file is rendered as

<input type="text" name="marks[OS:'candidateId1']" value="4" size="3"/>
<input type="text" name="marks[OS:'candidateId2']" value="5" size="3"/>
<input type="text" name="marks[OS:'candidateId3']" value="6" size="3"/>
<input type="text" name="marks[OS:'candidateId4']" value="7" size="3"/>

Webwork will populate the marks into the Map marks via

private Map marks = new HashMap();

public Map getMarks() {
	return marks;
}

whereby you can get the list of candidateIds via

List candidateIds = marks.keySet();

and the individual marks via

for (Iterator iter = candidateIds.iterator(); iter.hasNext();) {
	String candidateId = (String) iter.next();
	String mark = parseMap(marks.get(candidateId));
}

Possible enhancements

Couple tabular inputs with some sortable table component (javascript, client side)

or

DisplayTag (server side)

I believe there's some discussion on the mailing list about using Ognl to handle it automatically. I didn't follow it in detail, but from what I know, (do correct me if I'm wrong) the Ognl method is not available yet. The above works for now.

Conclusion

Feedback, comments and suggestions on better methods to perform the same function are welcome. If there's a simpler way, or a customised component to handle this tabular input automatically, I believe it'll be very useful.