items from other Events

You may not be aware of this, but the OpenClinica programmers are rewriting the software. You can see this for example when you want to print a StudySubject-casebook: in the URL of your browser you see something like rest/clinicaldata/html/view/ followed by some OID's. REST is another way of requesting data. Just like SOAP it is a web-service. Starting from version 3.4 we can make good use of it if we want to display the values of items that were collected in other Events. We emphasize other, because for items in the same Event we can use an InsertAction.
Take a look at the following CRF, where we collect the Randomisation number of a StudySubject plus his or her length. All this is done in Event Screening.


fig. 1: example of a screening CRF

Now suppose we want to display the RandomisationNumber in the next Event plus we want to measure the weight, but we also would like the length. And again: this can not be done by InsertActions, as the CRF's are in different Events.
Fig. 2 shows what we want:


fig. 2: what we would like

what?! how?

What follows is an explanation how you can get results like that, but if you want to try this for yourself on your own OpenClinica: go ahead with these CRFs. Of course you must edit the javascript in the CRF to use the OIDs of your particular sitation. Here is a page that explains how to find the OIDs.

What we did was adding some javascript to the RightItemText and in it, we requested the data from the Screening-Event for this particular StudySubject. Have look at the javascript for the first Item, where we display the RandomisationNumber in the RightItemText:


<div id="ValueFromOtherEvent"></div>
<script src="includes/jmesa/jquery.min.js"></script>
<script>
$.noConflict();
jQuery(document).ready(function($) { 
	// let the urlStart end with the OID of your Study
	var urlStart = "rest/clinicaldata/xml/view/S_TDS01/";
	// use for urlTail the StudyEventOID
	var urlTail = "/SE_SCREENING/*";
	// put here the OID of the Item you want to display
	var itemOID = "I_TDSSC_RANDONR";
	// now we can compose the url for the REST-request
	var urlComplete = urlStart + "${studySubjectOID}" + urlTail; 
	// make the request
	$.ajax({
		type: "GET",
		url: urlComplete,
		dataType: "xml",
		success: parseXML
		});
	// analyse the response
	function parseXML(xml){
		// set the default to: not available
		var OtherValue = "not available";
		// loop through the nodes called ItemData ...
		$(xml).find("ItemData").each(function(){
			// ... and look for the one with the OID that was set above ...
			if($(this).attr("ItemOID") == itemOID){
				// and store the value
				OtherValue = "Randomisationnumber as set in the Screening visit: " + $(this).attr("Value");
				}
			})
		// write the value in the div
		$("#ValueFromOtherEvent").html(OtherValue);
		}; 
	})
</script>

You can almost read this from the top to the bottom. All you need to know is how we compose the URL for our request for the data. The syntax for this is: rest/clinicaldata/xml/view/StudyOID/StudySubjectOID/StudyEventOID/*
Of this rest/clinicaldata/xml/view/ is standard. The StudyOID, the StudySubjectOID and the StudyEventOID we must supply. The * at the end means 'data from all CRFs'.

In our example we start with the variable var urlStart = "rest/clinicaldata/xml/view/S_TDS01/"; where the last bit is the OID of your Study. Then we define the OID of the StudyEvent: var urlTail = "/SE_SCREENING/*";
Of course we must know the OID of the item that holds our RandomisationNumber and we store that for later use: var itemOID = "I_TDSSC_RANDONR";
Now we are ready to compose our url with the aid of the token for the StudySubjectOID:
var urlComplete = urlStart + "${studySubjectOID}" + urlTail;. This will fill in the StudySubjectOID during the opening of the CRF.
Then we request the clinicaldata with $.ajax and if we get something, we call function parseXML(xml).
If you want to know what that REST-request gets you, type it in your browser and you will see something like fig.3.


fig. 3: the result of the REST-request

Now it is only a small step to lay our hands on RN010: we loop through the nodes called ItemData with $(xml).find("ItemData").each(function() and check if the OID is the one we set at the start of the script: if($(this).attr("ItemOID") == itemOID) and if that is so, we can use it to display it in the RightItemText.

and what about the length?

Displaying a value of an item from another Event seems trivial and not very useful. This is different for Item Length, because there the value entered at Event screening is copied! How?
Well, if you look at the other javascript you see that most of it is exactly the same as the one above

<div id="LengthFromScreening">(As recorded in Event Screening.)</div>
<script src="includes/jmesa/jquery.min.js"></script>
<script>
$.noConflict();
jQuery(document).ready(function($) {
	// define the field to write the value in
	var fieldLength = $("#LengthFromScreening").parent().parent().find("input");
	fieldLength.attr("readonly", true);
	// let the urlStart end with the OID of your Study
	var urlStart = "rest/clinicaldata/xml/view/S_TDS01/";
	// use for urlTail the StudyEventOID
	var urlTail = "/SE_SCREENING/*";
	// put here the OID of the Item you want to display
	var itemOID = "I_TDSSC_LENGTH";
	// now we can compose the url for the REST-request
	var urlComplete = urlStart + "${studySubjectOID}" + urlTail; 
	// make the request
	$.ajax({
		type: "GET",
		url: urlComplete,
		dataType: "xml",
		success: parseXML
		});
	// analyse the response
	function parseXML(xml){
		// loop through the nodes called ItemData ...
		$(xml).find("ItemData").each(function(){
		// ... and look for the one with the OID that was set above ...
		if($(this).attr("ItemOID") == itemOID){
			// and store the value
			OtherValue = $(this).attr("Value");
			}
		 })
		// write the value, if it is not there already
		if (fieldLength.val() != OtherValue){
			fieldLength.val(OtherValue);
			fieldLength.change();
			}; 
	}
	})
</script>

We make a reference to the input field where we want to write the length of Event Screening by taking the parent of the parent of the div that is called 'LengthFromScreening'and then finding the input: var fieldLength = $("#LengthFromScreening").parent().parent().find("input");.
We get our value in the same way as above, and when we have it, we first check if the value is already in place, with if (fieldLength.val() != OtherValue) and if not, we set the value with fieldLength.val(OtherValue);. Note that we also set the status of the item to 'changed', fieldLength.change(); so OpenClinica knows it should store tha data of this CRF.

Other how-to-pages can be found here.

this page was last reviewed October 2014