data from other events

Now that we know how to read an xml-file, we can use that to extract information from data that was entered into OpenClinica. To do this, we must have some working material. First of all download this RandoOutcome CRF, upload it to your OpenClinica. Create an event Rand and assign this CRF to it. Now download this CRF, upload it. Create another event named EvF and assign CRF F to it.

When all this is in place, go to your SubjectMatrix and add a new Subject with StudySubjectID "T001". Enter data for the RandoOutcome CRF, for example Arm B. Enter data in two more CRFs. The data of a Subject can be seen in xml-format by using REST (Representational State Transfer). What?!
This may sound new to you, but you've probably used it already when printing a Subject's case-book. Open the Subject-page for T001 and open the node "Subject Casebook". For "Casebook Format" choose "CDISC ODM XML". Uncheck "Notes & Discrepancies" and "Audit Trail". Click on "Get Link" and also on "Open".

The result is a massive page with url http://localhost:8081/oc341/rest/clinicaldata/xml/view/S_TS34/SS_T001/*/* and this means: find Study with StudyOID S_TS34 and of that Study look at Subject with StudySubjectOID SS_T001 and then give me the data of all Events and in these Events, of all CRFs. And if you look at the output, it will take some scrolling, but at the end you will find the actual clinical data of your Subject. Or search for "ClinicalData". You will see the entry you just made: <ItemData ItemOID="I_TDSWO_RANDOOUTCOME" Value="2"/>

can we start writing now?

Enough preparing: we want to write something. And as before, let's build this step-by-step. We start with our CRF F and open it in preview and save it as StaticCRF_F.html. Now we can make our life easy by copying the first bit of our previous workshop CRF, the part where we read an xml-file but we change the url to the url of our rest-call and we make an empty function "parseXML(xml)":

$.ajax({
	type: "GET",
	url: "http://localhost:8081/oc341/rest/clinicaldata/xml/view/S_TS34/SS_T001/*/*",
	dataType: "xml",
	success: parseXML
	});
function parseXML(xml){}

This seems to work OK, so now we can loop through items of our xml-file and the elements we're interested in are of course ItemData. Of such an element we would like to know the attributes "ItemOID" and "Value":

function parseXML(xml){
	$(xml).find("ItemData").each(function(){
		console.log($(this).attr("ItemOID") + " " + $(this).attr("Value"));
		});
}

We must have some patience here, because it takes time to get the data from OpenClinica. Now let's focus on the url that we use in the ajax-call. We can skip the first part, because we're already in http://localhost:8081/oc341/. Then we have a part to start with and then the StudySubjectOID and we finish with the StudyOID and two wildcards for all Events and all CRFs. Let's break the url in these three parts and then give the ajax-call the combined url:

var urlStart = "rest/clinicaldata/xml/view/S_TS34/";
var studySubjectOID = "SS_T001";
var urlEnd = "/*/*";
var urlComplete = urlStart + studySubjectOID + urlEnd;
$.ajax({
	type: "GET",
	url: urlComplete,
	dataType: "xml",
	success: parseXML
});

Of course we're not interested in all these ItemData, but only in the one that is called "I_TDSWO_RANDOOUTCOME" so we modify the script to compare the ItemNames with "I_TDSWO_RANDOOUTCOME" and if it matches, then take the value of this item and store it in a variable "randOutcome" with

		$(xml).find("ItemData").each(function(){
	if($(this).attr("ItemOID") == "I_TDSWO_RANDOOUTCOME")
		randOutcome = $(this).attr("Value"));
	});

what else do we need?

Closer now, but not yet there: we must make a reference to the CRF-item and wait: it is a group of radio-buttons, so we must loop through them if we want to write our randomisation outcome. Let's do that first. The reference we can make with var crfItem = $("#ValueFromOtherEvent").parent().parent().find("input");. Once we have the reference we loop through the radio-buttons and if we find the one that has the same value as the value "randOutcome", then we set this radio to "checked". (And for the others we set the attribute "disabled" to "true".)

for (var i = 0; i < crfItem.length; i++) {
	if ($(crfItem[i]).val() == randOutcome) {
		$(crfItem[i]).prop("checked", true);
	}
	else{
		$(crfItem[i]).prop("disabled", true);
	}
}

can we now at last stick it in the CRF?

We're very, very close now, but the StudySubjectOID is still hard-coded in the script. But this may remind you of part C of the workshop, where we used the StudySubjectID. So we replace var studySubjectOID = "SS_T001"; with var studySubjectOID = "${studySubjectOID}". Go ahead, do that and upload the CRF and test it. It is working but something's missing: what is?

You will probably have noticed that the SimpleConditionalDisplay is not working. The reason is that the radio is set to "checked", but there is no click-event. If we close and re-open the CRF it is OK, but not when we open the CRF for the first time.

The solution is to add one last line that fires the click-event:

<div id="ValueFromOtherEvent"></div>
<script src="includes/jmesa/jquery.min.js"></script>
<script>
$.noConflict();
jQuery(document).ready(function($) { 
	var urlStart = "rest/clinicaldata/xml/view/S_TS34/";
	var studySubjectOID = "${studySubjectOID}";
	var urlEnd = "/*/*";
	var urlComplete = urlStart + studySubjectOID + urlEnd;
	var randOutcome;
	var crfItem = $("#ValueFromOtherEvent").parent().parent().find("input");
	$.ajax({
		type: "GET",
		url: urlComplete,
		dataType: "xml",
		success: parseXML
	});
	function parseXML(xml){
		$(xml).find("ItemData").each(function(){
			if($(this).attr("ItemOID") == "I_TDSWO_RANDOOUTCOME"){
				randOutcome = $(this).attr("Value");
			}
		});
		//write the value to the crf-item
		for (var i = 0; i < crfItem.length; i++) {
			if ($(crfItem[i]).val() == randOutcome) {
				$(crfItem[i]).prop("checked", true);
				$(crfItem[i]).click();
			}
			else{
				$(crfItem[i]).prop("disabled", true);
			}
		}
	}

})
</script>

Start-page of the workshop.

this page was last reviewed July 2015