...
Code Block | ||
---|---|---|
| ||
/**
* Controller for the PatientIdentifiers fragment.
* Displays a table of PatientIdentifiers, and allow the user to add another (via a short popup form),
* or delete one (with confirmation) as long as it isn't the last one.
*/
public class PatientIdentifiersFragmentController {
/**
* Controller method when the fragment is included on a page
*/
public void controller(PageModel sharedPageModel, FragmentConfiguration config, FragmentModel model) {
model.addAttribute("patient", FragmentUtil.getPatient(sharedPageModel, config));
}
}
|
...
Code Block | ||
---|---|---|
| ||
<%
def id = config.id ?: ui.randomId("patientIdentifiers")
%>
<div id="${ id }">
${ ui.includeFragment("widgets/table", [
columns: [
[ property: "identifierType", heading: ui.message("PatientIdentifier.type") ],
[ property: "identifier", userEntered: true, heading: ui.message("PatientIdentifier.identifier") ],
[ property: "location", heading: ui.message("PatientIdentifier.location") ]
],
rows: patient.activeIdentifiers,
ifNoRowsMessage: ui.message("general.none")
]) }
</div>
|
It would be easy to write the html for the table ourselves, and this would be fine for a quick first pass, but in later steps we're going to want some more sophisticated behavior that we can get for free from the standard OpenMRS "table" widget, so we use that instead. (TODO: the ifNoRowsMessage functionality isn't implemented yet - TRUNK-2173)
Note:
- for localization, we always use the ui.message() function instead of hardcoding user-visible messages in our views.
- for security, we always display user-entered data with appropriate escaping
- in this case we use that's the userEntered setting on the table column, but if we were displaying data ourselves we'd use ui.escapeHtml() or ui.escapeJs()
- for UI consistency, we should always display standard OpenMRS classes with the ui.format() function. (That's taken care of here by the table widget.)
...
Code Block | ||
---|---|---|
| ||
/** * Controller for the PatientIdentifiers fragment. * Displays a table of PatientIdentifiers, and allow the user to add another (via a short popup form), * or delete one (with confirmation) as long as it isn't the last one. */ public class PatientIdentifiersFragmentController { /** * Controller method when the fragment is included on a page */ public void controller(PageModel sharedPageModel, FragmentConfiguration config, FragmentModel model) { model.addAttribute("patient", FragmentUtil.getPatient(sharedPageModel, config)); } /** * Fragment Action for fetching list of active patient identifiers */ public ObjectResult getActiveIdentifiers(UiUtils ui, @RequestParam("patientId") Patient patient) { return ObjectResult.build(ui, patient.getActiveIdentifiers(), "patientIdentifierId", "identifierType", "identifier", "location"); } } |
...
Code Block | ||
---|---|---|
| ||
<%
def id = config.id ?: ui.randomId("patientIdentifiers")
%>
<script>
function refreshPatientIdentifierTable(divId, patientId) {
jq('#' + divId + '_table > tbody').empty();
jq.getJSON('${ ui.actionLink("getActiveIdentifiers", [returnFormat: "json"]) }', { patientId: patientId },
function(data) {
publish(divId + "_table.show-data", data);
});
}
</script>
<div id="${ id }">
<a href="javascript:refreshPatientIdentifierTable('${ id }', ${ patient.patientId })">test the refresh</a>
${ ui.includeFragment("widgets/table", [
id: id + "_table",
columns: [
[ property: "identifierType", heading: ui.message("PatientIdentifier.type") ],
[ property: "identifier", userEntered: true, heading: ui.message("PatientIdentifier.identifier") ],
[ property: "location", heading: ui.message("PatientIdentifier.location") ]
],
rows: patient.activeIdentifiers,
ifNoRowsMessage: ui.message("general.none")
]) }
</div>
|
...
Code Block | ||
---|---|---|
| ||
<% def id = config.id ?: ui.randomId("patientIdentifiers") %> <script> function refreshPatientIdentifierTable(divId, patientId) { jq('#' + divId + '_table > tbody').empty(); jq.getJSON('${ ui.actionLink("getActiveIdentifiers", [returnFormat: "json"]) }', { patientId: patientId }, function(data) { publish(divId + "_table.show-data", data); }); } function refreshPatientIdentifiers${ id }(message, data) { if (data) publish("${ id }_table.show-data", data.activeIdentifiers); else refreshPatientIdentifierTable('${ id }', ${ patient.patientId }); } subscribe('${ id }.refresh', refreshPatientIdentifiers${ id }); subscribe('patient/${ patient.patientId }.changed', refreshPatientIdentifiers${ id }); subscribe('patient/${ patient.patientId }/identifiers.changed', refreshPatientIdentifiers${ id }); </script> <div id="${ id }"> <a href="javascript:publish('${ id }.refresh')">div id refresh</a> <a href="javascript:patientChanged(${ patient.patientId })">patient changed</a> <a href="javascript:patientChanged(${ patient.patientId }, 'identifiers')">identifiers changed</a> ${ ui.includeFragment("widgets/table", [ id: id + "_table", columns: [ [ property: "identifierType", heading: ui.message("PatientIdentifier.type") ], [ property: "identifier", userEntered: true, heading: ui.message("PatientIdentifier.identifier") ], [ property: "location", heading: ui.message("PatientIdentifier.location") ] ], rows: patient.activeIdentifiers, ifNoRowsMessage: ui.message("general.none") ]) } </div> |
...
Code Block | ||
---|---|---|
| ||
/**
* Fragment Action for adding a new identifier
*/
public FragmentActionResult addIdentifier(UiUtils ui,
@RequestParam("patientId") Patient patient,
@RequestParam("identifierType") PatientIdentifierType idType,
@RequestParam("identifier") String identifier,
@RequestParam("location") Location location) {
patient.addIdentifier(new PatientIdentifier(identifier, idType, location));
Context.getPatientService().savePatient(patient);
return new SuccessResult(ui.message("patientIdentifier.added"));
}
|
...
Code Block | ||
---|---|---|
| ||
<% def id = config.id ?: ui.randomId("patientIdentifiers") %> <script> function refreshPatientIdentifierTable(divId, patientId) { jq('#' + divId + '_table > tbody').empty(); jq.getJSON('${ ui.actionLink("getActiveIdentifiers", [returnFormat: "json"]) }', { patientId: patientId }, function(data) { publish(divId + "_table.show-data", data); }); } function refreshPatientIdentifiers${ id }(message, data) { if (data) publish("${ id }_table.show-data", data.activeIdentifiers); else refreshPatientIdentifierTable('${ id }', ${ patient.patientId }); } subscribe('${ id }.refresh', refreshPatientIdentifiers${ id }); subscribe('patient/${ patient.patientId }.changed', refreshPatientIdentifiers${ id }); subscribe('patient/${ patient.patientId }/identifiers.changed', refreshPatientIdentifiers${ id }); </script> <div id="${ id }"> ${ ui.includeFragment("widgets/table", [ id: id + "_table", columns: [ [ property: "identifierType", heading: ui.message("PatientIdentifier.identifierType") ], [ property: "identifier", userEntered: true, heading: ui.message("PatientIdentifier.identifier") ], [ property: "location", heading: ui.message("PatientIdentifier.location") ] ], rows: patient.activeIdentifiers, ifNoRowsMessage: ui.message("general.none") ]) } ${ ui.includeFragment("widgets/popupForm", [ id: id + "_add", buttonLabel: ui.message("general.add"), popupTitle: ui.message("patientIdentifier.add"), fragment: "patientIdentifiers", action: "addIdentifier", submitLabel: ui.message("general.save"), cancelLabel: ui.message("general.cancel"), fields: [ [ hiddenInputName: "patientId", value: patient.patientId ], [ label: ui.message("PatientIdentifier.identifierType"), formFieldName: "identifierType", class: org.openmrs.PatientIdentifierType ], [ label: ui.message("PatientIdentifier.identifier"), formFieldName: "identifier", class: java.lang.String ], [ label: ui.message("PatientIdentifier.location"), formFieldName: "location", class: org.openmrs.Location ] ] ]) } </div> |
...
Code Block | ||
---|---|---|
| ||
/**
* Fragment Action for deleting an existing identifier
*/
public FragmentActionResult deleteIdentifier(UiUtils ui,
@RequestParam("patientIdentifierId") Integer id) {
PatientService ps = Context.getPatientService();
PatientIdentifier pid = ps.getPatientIdentifier(id);
ps.voidPatientIdentifier(pid, "user interface");
return new SuccessResult(ui.message("PatientIdentifier.deleted"));
}
|
...
Code Block | ||
---|---|---|
| ||
<% def id = config.id ?: ui.randomId("patientIdentifiers") %> <script> function refreshPatientIdentifierTable(divId, patientId) { jq('#' + divId + '_table > tbody').empty(); jq.getJSON('${ ui.actionLink("getActiveIdentifiers", [returnFormat: "json"]) }', { patientId: patientId }, function(data) { publish(divId + "_table.show-data", data); }); } function refreshPatientIdentifiers${ id }(message, data) { if (data) publish("${ id }_table.show-data", data.activeIdentifiers); else refreshPatientIdentifierTable('${ id }', ${ patient.patientId }); } subscribe('${ id }.refresh', refreshPatientIdentifiers${ id }); subscribe('patient/${ patient.patientId }.changed', refreshPatientIdentifiers${ id }); subscribe('patient/${ patient.patientId }/identifiers.changed', refreshPatientIdentifiers${ id }); subscribe('${ id }_table.delete-button-clicked', function(message, data) { if (prettyConfirm('${ ui.message("general.confirm") }')) { jq.post('${ ui.actionLink("deleteIdentifier") }', { returnFormat: 'json', patientIdentifierId: data }, function(data) { location.reload(true); }) .error(function() { flashError("Programmer error: delete identifier failed"); }) } }); </script> <div id="${ id }"> ${ ui.includeFragment("widgets/table", [ id: id + "_table", columns: [ [ property: "identifierType", heading: ui.message("PatientIdentifier.identifierType") ], [ property: "identifier", userEntered: true, heading: ui.message("PatientIdentifier.identifier") ], [ property: "location", heading: ui.message("PatientIdentifier.location") ], [ actions: [ [ action: "event", icon: "delete24.png", tooltip: ui.message("PatientIdentifier.delete"), event: "delete-button-clicked", eventPrefix: id, property: "patientIdentifierId" ] ] ] ], rows: patient.activeIdentifiers, ifNoRowsMessage: ui.message("general.none") ]) } ${ ui.includeFragment("widgets/popupForm", [ id: id + "_add", buttonLabel: ui.message("general.add"), popupTitle: ui.message("PatientIdentifier.add"), fragment: "patientIdentifiers", action: "addIdentifier", submitLabel: ui.message("general.save"), cancelLabel: ui.message("general.cancel"), fields: [ [ hiddenInputName: "patientId", value: patient.patientId ], [ label: ui.message("PatientIdentifier.identifierType"), formFieldName: "identifierType", class: org.openmrs.PatientIdentifierType ], [ label: ui.message("PatientIdentifier.identifier"), formFieldName: "identifier", class: java.lang.String ], [ label: ui.message("PatientIdentifier.location"), formFieldName: "location", class: org.openmrs.Location ] ] ]) } </div> |
...
Code Block | ||
---|---|---|
| ||
/** * Controller for the PatientIdentifiers fragment. * Displays a table of PatientIdentifiers, and allow the user to add another (via a short popup form), * or delete one (with confirmation) as long as it isn't the last one. */ public class PatientIdentifiersFragmentController { /** * Controller method when the fragment is included on a page */ public void controller(PageModel sharedPageModel, FragmentConfiguration config, FragmentModel model) { model.addAttribute("patient", FragmentUtil.getPatient(sharedPageModel, config)); } /** * Fragment Action for fetching list of active patient identifiers */ public ObjectResult getActiveIdentifiers(UiUtils ui, @RequestParam("patientId") Patient patient) { return ObjectResult.build(ui, patient.getActiveIdentifiers(), "patientIdentifierId", "identifierType", "identifier", "location"); } /** * Fragment Action for adding a new identifier */ public FragmentActionResult addIdentifier(UiUtils ui, @RequestParam("patientId") Patient patient, @RequestParam("identifierType") PatientIdentifierType idType, @RequestParam("identifier") String identifier, @RequestParam("location") Location location) { patient.addIdentifier(new PatientIdentifier(identifier, idType, location)); Context.getPatientService().savePatient(patient); return FragmentUtil.standardPatientObject(ui, patient); } /** * Fragment Action for deleting an existing identifier */ public FragmentActionResult deleteIdentifier(UiUtils ui, @RequestParam("patientIdentifierId") Integer id) { PatientService ps = Context.getPatientService(); PatientIdentifier pid = ps.getPatientIdentifier(id); ps.voidPatientIdentifier(pid, "user interface"); return FragmentUtil.standardPatientObject(ui, pid.getPatient()); } } |
The only change we've made is to return a ObjectResult representing a standard patient, instead of a SuccessResult.
...
Code Block | ||
---|---|---|
| ||
<% def id = config.id ?: ui.randomId("patientIdentifiers") %> <script> function refreshPatientIdentifierTable(divId, patientId) { jq('#' + divId + '_table > tbody').empty(); jq.getJSON('${ ui.actionLink("getActiveIdentifiers", [returnFormat: "json"]) }', { patientId: patientId }, function(data) { publish(divId + "_table.show-data", data); }); } function refreshPatientIdentifiers${ id }(message, data) { if (data) publish("${ id }_table.show-data", data.activeIdentifiers); else refreshPatientIdentifierTable('${ id }', ${ patient.patientId }); } subscribe('${ id }.refresh', refreshPatientIdentifiers${ id }); subscribe('patient/${ patient.patientId }.changed', refreshPatientIdentifiers${ id }); subscribe('patient/${ patient.patientId }/identifiers.changed', refreshPatientIdentifiers${ id }); subscribe('${ id }_table.delete-button-clicked', function(message, data) { if (openmrsConfirm('${ ui.message("general.confirm") }')) { jq.post('${ ui.actionLink("deleteIdentifier") }', { returnFormat: 'json', patientIdentifierId: data }, function(data) { flashSuccess('${ ui.escapeJs(ui.message("PatientIdentifier.deleted")) }'); publish('patient/${ patient.patientId }/identifiers.changed', data); }, 'json') .error(function() { flashError("Programmer error: delete identifier failed"); }) } }); </script> <div id="${ id }"> ${ ui.includeFragment("widgets/table", [ id: id + "_table", columns: [ [ property: "identifierType", heading: ui.message("PatientIdentifier.identifierType") ], [ property: "identifier", userEntered: true, heading: ui.message("PatientIdentifier.identifier") ], [ property: "location", heading: ui.message("PatientIdentifier.location") ], [ actions: [ [ action: "event", icon: "delete24.png", tooltip: ui.message("PatientIdentifier.delete"), event: "delete-button-clicked", eventPrefix: id, property: "patientIdentifierId" ] ] ] ], rows: patient.activeIdentifiers, ifNoRowsMessage: ui.message("general.none") ]) } ${ ui.includeFragment("widgets/popupForm", [ id: id + "_add", buttonLabel: ui.message("general.add"), popupTitle: ui.message("PatientIdentifier.add"), fragment: "patientIdentifiers", action: "addIdentifier", submitLabel: ui.message("general.save"), cancelLabel: ui.message("general.cancel"), fields: [ [ hiddenInputName: "patientId", value: patient.patientId ], [ label: ui.message("PatientIdentifier.identifierType"), formFieldName: "identifierType", class: org.openmrs.PatientIdentifierType ], [ label: ui.message("PatientIdentifier.identifier"), formFieldName: "identifier", class: java.lang.String ], [ label: ui.message("PatientIdentifier.location"), formFieldName: "location", class: org.openmrs.Location ] ], successEvent: "patient/" + patient.patientId + "/identifiers.changed" ]) } </div> |
...