Annotation MVC Example for Cape Town

Step 1: Create a module

Step 2: Add moduleApplicationContext.xml (See Module Creator's Cheat Sheet)

Step 3: Add a controller and a view:

Controller

Note: I have edited this since what was projected on the screen at the end of my presentation. I removed the thing that doesn't work. (The reason it didn't work is that @SessionAttributes is only usable when you put something in the session on an initial GET, and keep it there through subsequent POSTs. It cannot be used for keeping something in the session across multiple visits to a form.)

package org.openmrs.module.capetownexample.web;

import java.util.List;
import java.util.Vector;

import org.openmrs.Location;
import org.openmrs.api.context.Context;
import org.openmrs.propertyeditor.LocationEditor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.context.request.WebRequest;

@Controller
public class ExampleController {

	private static final String SESSION_ATTRIBUTE = "MY_FAVORITE_LOCATIONS";

	@InitBinder
	public void initBinder(WebDataBinder wdb) {
		wdb.registerCustomEditor(Location.class, new LocationEditor());
	}


	@ModelAttribute("locations")
	public List<Location> populateLocations() {
		return Context.getLocationService().getAllLocations();
	}


	@RequestMapping(value="/module/capetownexample/example", method=RequestMethod.GET)
	public void showLocations(ModelMap model,
	                          WebRequest request) {
		List<Location> favorites = getFavorites(request);

		model.addAttribute("favorites", favorites);
	}


	@RequestMapping(value="/module/capetownexample/exampleRemoveFavorite")
	public String removeFromFavorites(WebRequest request,
	                                  @RequestParam("location") List<Location> locations) {

		List<Location> favorites = getFavorites(request);

		favorites.removeAll(locations);
		return "redirect:example.form";
	}


	@RequestMapping(value="/module/capetownexample/example", method=RequestMethod.POST, params="formAction=ADD")
	public String addToFavorites(WebRequest request,
	                             @RequestParam("location") List<Location> locations) {
		List<Location> favorites = getFavorites(request);

		favorites.addAll(locations);
		return "redirect:example.form";
	}


	@SuppressWarnings("unchecked")
    private List<Location> getFavorites(WebRequest request) {
		List<Location> favorites = null;
		try {
			favorites = (List<Location>) request.getAttribute(SESSION_ATTRIBUTE, WebRequest.SCOPE_SESSION);
		} catch (ClassCastException ex) { }
		if (favorites == null) {
			favorites = new Vector<Location>();
			request.setAttribute(SESSION_ATTRIBUTE, favorites, WebRequest.SCOPE_SESSION);
		}
		return favorites;
    }


}

View

<%@ include file="/WEB-INF/template/include.jsp"%>

<%@ include file="/WEB-INF/template/header.jsp"%>

<div class="boxHeader">
	Favorite locations
</div>
<div class="box">
	<ul>
		<c:forEach var="l" items="${favorites}">
			<li>
				${l.name}
				<a href="exampleRemoveFavorite.form?location=${l.locationId}">[x]</a>
			</li>
		</c:forEach>
	</ul>
</div>


<div class="boxHeader">
	All locations
</div>
<div class="box">
	<form method="post">
		<input type="hidden" name="formAction" value="ADD"/>
		<ul>
			<c:forEach var="l" items="${locations}">
				<li><input type="checkbox" name="location" value="${l.locationId}"/>${l.name}</li>
			</c:forEach>
		</ul>
		<input type="submit" value="Add to favorites"/>
	</form>
</div>

<%@ include file="/WEB-INF/template/footer.jsp"%>