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