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:
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
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
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> |
<form method="post" action="addFavoritePatient.form"> Add a patient <openmrs:fieldGen formFieldName="patient_id" type="org.openmrs.Patient"/> <input type="submit" value="Add"/> </form> |
Now we need a method on the controller to handle that submission.
@Controller public class MyFavoritePatientsController { ... @RequestMapping("module/jspexample/addFavoritePatient") public String addFavoritePatient(@RequestParam("patient_id") Integer patientId) { Patient p = Context.getPatientService().getPatient(patientId); if (p != null) MyFavoritePatientUtil.addFavoritePatient(Context.getAuthenticatedUser(), p); return "redirect:myfavoritepatients.form"; } } |
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:
@Controller public class MyFavoritePatientsController { @InitBinder public void initBinder(WebDataBinder wdb) { wdb.registerCustomEditor(Patient.class, new PatientEditor()); } ... @RequestMapping("module/jspexample/addFavoritePatient") public String addFavoritePatient(@RequestParam(value="patient_id", required=false) Patient patient) { if (patient != null) MyFavoritePatientUtil.addFavoritePatient(Context.getAuthenticatedUser(), patient); return "redirect:myfavoritepatients.form"; } } |
public class MyFavoritePatientsUtil { private static String cohortName(User u) { return "Favorite Patients for User " + u.getUserId(); } private static List<Patient> getPatients(Cohort cohort) { if (cohort == null) return new ArrayList<Patient>(); else return Context.getPatientSetService().getPatients(cohort.getMemberIds()); } public static List<Patient> getFavoritePatients(User u) { Cohort c = Context.getCohortService().getCohort(cohortName(u)); return getPatients(c); } public static void addFavoritePatient(User u, Patient p) { Cohort c = Context.getCohortService().getCohort(cohortName(u)); if (c == null) { c = new Cohort(); c.setName(cohortName(u)); c.setDescription("Automatically generated"); } c.addMember(p.getPatientId()); Context.getCohortService().saveCohort(c); } } |