My Favorite Patients MVC Example
The Goal
We're going to add a "My Favorite Patients" feature in our module. We'll add a link in the OpenMRS header that says "My Favorite Patients" and that page will show a list of the currently logged-in user's favorite patients. We will store these using the existing "Cohort" object, rather than creating our own domain object:
Initial Setup
We're going to do this within the jspexample module. If we were doing this for real, we'd create a new module, and add the webModuleApplicationContext.xml file as described here
Create a page to show My Favorite Patients
Note that we're going to delegate the actual work to a MyFavoritePatientUtil class. In real life we would make a service for this.
@Controller
class MyFavoritePatientsController {
@RequestMapping("/module/jspexample/myfavoritepatients")
public void showFavoritePatients(ModelMap model) {
model.put("favorites", MyFavoritePatientUtil.getFavoritePatients(Context.getAuthenticatedUser()));
model.put("me", Context.getAuthenticatedUser());
}
}
Next we need a JSP to display this, in the standard location of /web/module/myfavoritepatients.jsp:
<%@ include file="/WEB-INF/template/include.jsp" %>
<%@ include file="/WEB-INF/template/header.jsp" %>
<h1>My ${fn:length(favorites)} favorite patient(s) (for ${me.username})</h1>
<ul>
<c:forEach var="p" items="${favorites}">
<li>
${p.personName}
<c:choose>
<c:when test="${p.gender == 'F'}">
Female
</c:when>
<c:otherwise>
Male
</c:otherwise>
</c:choose>
</li>
</c:forEach>
</ul>
<%@ include file="/WEB-INF/template/footer.jsp" %>
The only problem is that this list is empty. Let's make a hacky form that allows us to add a patient
A hacky way to add new favorite patients
First we add this to the JSP page
<form method="post" action="addFavoritePatient.form">
Add a patient by primary key: <input type="text" name="patient_id"/>
<input type="submit" value="Add"/>
</form>
Better widget for picking a Patient
Now we need a method on the controller to handle that submission.
You can use the @RequestParam annotation to have Spring automatically bind a parameter in the request to an argument to your method. It automatically converts from String (which all HTTP request parameters are by nature) to the specified class.
If you return a String that starts with "redirect:" then Spring MVC does the appropriate response.setRedirect(...) call for you.
There's a nicer way to do this, though. OpenMRS provides a bunch of editor classes that know how to convert between a String (in an HTTP request) and our domain objects. In this case org.openmrs.propertyeditor.PatientEditor.
By default, Spring will only automatically convert a small number of parameter types that it knows: Integers, Doubles, Booleans, and a few more. In our controller we need to tell it about other types it should automatically convert: