We hope you'll join us for our 4/23 webinar on using data tables to apply reference ranges and AE codes in OC4. For more information and to register, visit https://register.gotowebinar.com/register/2882170018956684555

long lists

Dear community,

In one of our most recent crfs we had to create a single-select list with more options than OC would allow. I considered Gerben’s getExternalValue solution, but as I expect people will be using IE and other browsers I came up with an alternative solution which I will share below.

The list we need contains medication (code + description):
A03AE02 – Tegaserod
A03AE04 – Prucalopride
etc.

As OC cannot handle the complete list, we need to store it in an external file. To make parsing easy we decided to store the codes in an XML file (ATC_Codes.xml):
<?xml version="1.0" encoding="utf-8" ?>


A03AE02 - Tegaserod


A03AE04 - Prucalopride

… etc.


First problem is where to store the file. In a previous post when I wrote about CSS there is the nice feature that you can store and access it pretty much anywhere you like. This is not the case when you want to access a file with JavaScript, which does not allow cross-site requests. The easy solution is to store the file on your OC server; in our case we added it to the includes directory.

Second problem is getting the data into OC. Initially, I considered creating a single-select in OC and filling that with the new options. That won’t work however, as OC doesn’t know these options and therefore won’t allow you to save them. The workaround is to create a normal OC text-field and a non-OC select field and the to copy the value from your non-OC field to your OC field.

For this example, I have my left_item_text set to:
textOut
This is a text field in OC which can contain strings. I added the span tag with identifier “myOutput” so that we can reach the textfield itself.

My right_ item_text I set to:

None

This is a simple HTML drop-down with identifier “myList” and it currently contains one item called None.

Now for the code (which I pasted in the right_item_text as well):



jQuery(document).ready(function($) {
var myField = $("#myList")
var myOutputField = $("#myOutput").parent().parent().find("input");
myOutputField.attr("readonly",true);

$.ajax({
type: "GET",
url: "includes/ATC_Codes.xml",
dataType: "xml",
success: parseXml
});

function parseXML(xml){
//find every ATCCode and Description
$(xml).find("ATCCode").each(function(){
myField.append($("").val($(this).attr("Code")).text($(this).find("Description").text()));
});
myField.val(myOutputField.val());
}

myField.change(function(){
myOutputField.val(myField.val());
myOutputField.change();
});

});


I’ll briefly explain the code:

var myField = $("#myList")
var myOutputField = $("#myOutput").parent().parent().find("input");
myOutputField.attr("readonly",true);
First we obtain references to the fields using the identifiers we set. We then set the output field to readonly to prevent people from editing it manually.

$.ajax({
type: "GET",
url: "includes/ATC_Codes.xml",
dataType: "xml",
success: parseXML
});
We then call ajax to load the xml file. If it succeeds it calls the function parseXML

function parseXML(xml){
//find every ATCCode and Description
$(xml).find("ATCCode").each(function(){
myField.append($("").val($(this).attr("Code")).text($(this).find("Description").text()));
});
myField.val(myOutputField.val());
}
The function takes the xml file and finds each instance of ATCCode (which is the name we defined in the XML file). For each ATCCode found, we fill the single-select with the Code and the Description (both defined in the XML file). It sets the value (val) to “Code” and the text to “Description”.
Finally we set the current value of the single-select to the current value of the output field.

myField.change(function(){
myOutputField.val(myField.val());
myOutputField.change();
});
In this last bit, we employ the change event: if our single-select (myField) is changed, we change the output field to the select’s current value (which is the Code). We then call the output field’s change event, to inform OC that it has work to do when the save button is pressed.

It may seem a bit complex, but it is doable. And it works like a charm, except with repeating groups; haven’t given that bit much thought yet.

I am open to comments, questions, suggestions and easier solutions!

Cheers,
Sander de Ridder

Comments

  • sderiddersderidder Posts: 57
    Dear community,

    In one of our most recent crfs we had to create a single-select list with more options than OC would allow. I considered Gerben’s getExternalValue solution, but as I expect people will be using IE and other browsers I came up with an alternative solution which I will share below.

    The list we need contains medication (code + description):
    A03AE02 – Tegaserod
    A03AE04 – Prucalopride
    etc.

    As OC cannot handle the complete list, we need to store it in an external file. To make parsing easy we decided to store the codes in an XML file (ATC_Codes.xml):
    <?xml version="1.0" encoding="utf-8" ?>


    A03AE02 - Tegaserod


    A03AE04 - Prucalopride

    … etc.


    First problem is where to store the file. In a previous post when I wrote about CSS there is the nice feature that you can store and access it pretty much anywhere you like. This is not the case when you want to access a file with JavaScript, which does not allow cross-site requests. The easy solution is to store the file on your OC server; in our case we added it to the includes directory.

    Second problem is getting the data into OC. Initially, I considered creating a single-select in OC and filling that with the new options. That won’t work however, as OC doesn’t know these options and therefore won’t allow you to save them. The workaround is to create a normal OC text-field and a non-OC select field and the to copy the value from your non-OC field to your OC field.

    For this example, I have my left_item_text set to:
    textOut
    This is a text field in OC which can contain strings. I added the span tag with identifier “myOutput” so that we can reach the textfield itself.

    My right_ item_text I set to:

    None

    This is a simple HTML drop-down with identifier “myList” and it currently contains one item called None.

    Now for the code (which I pasted in the right_item_text as well):



    jQuery(document).ready(function($) {
    var myField = $("#myList")
    var myOutputField = $("#myOutput").parent().parent().find("input");
    myOutputField.attr("readonly",true);

    $.ajax({
    type: "GET",
    url: "includes/ATC_Codes.xml",
    dataType: "xml",
    success: parseXml
    });

    function parseXML(xml){
    //find every ATCCode and Description
    $(xml).find("ATCCode").each(function(){
    myField.append($("").val($(this).attr("Code")).text($(this).find("Description").text()));
    });
    myField.val(myOutputField.val());
    }

    myField.change(function(){
    myOutputField.val(myField.val());
    myOutputField.change();
    });

    });


    I’ll briefly explain the code:

    var myField = $("#myList")
    var myOutputField = $("#myOutput").parent().parent().find("input");
    myOutputField.attr("readonly",true);
    First we obtain references to the fields using the identifiers we set. We then set the output field to readonly to prevent people from editing it manually.

    $.ajax({
    type: "GET",
    url: "includes/ATC_Codes.xml",
    dataType: "xml",
    success: parseXML
    });
    We then call ajax to load the xml file. If it succeeds it calls the function parseXML

    function parseXML(xml){
    //find every ATCCode and Description
    $(xml).find("ATCCode").each(function(){
    myField.append($("").val($(this).attr("Code")).text($(this).find("Description").text()));
    });
    myField.val(myOutputField.val());
    }
    The function takes the xml file and finds each instance of ATCCode (which is the name we defined in the XML file). For each ATCCode found, we fill the single-select with the Code and the Description (both defined in the XML file). It sets the value (val) to “Code” and the text to “Description”.
    Finally we set the current value of the single-select to the current value of the output field.

    myField.change(function(){
    myOutputField.val(myField.val());
    myOutputField.change();
    });
    In this last bit, we employ the change event: if our single-select (myField) is changed, we change the output field to the select’s current value (which is the Code). We then call the output field’s change event, to inform OC that it has work to do when the save button is pressed.

    It may seem a bit complex, but it is doable. And it works like a charm, except with repeating groups; haven’t given that bit much thought yet.

    I am open to comments, questions, suggestions and easier solutions!

    Cheers,
    Sander de Ridder
  • bbaumannbbaumann Posts: 105 admin
    Nice job Sander ;)

    What you've written may also work well as a technical post on the OpenClinica blog, and is probably also worthy of putting up on the wiki book. I'll follow-up with you offline.

    - Ben
    Sent: Thursday, July 19, 2012 4:47 AM
    To: [email protected]; [email protected]
    Subject: [Developers] long lists
    Dear community,

    In one of our most recent crfs we had to create a single-select list with more options than OC would allow. I considered Gerben’s getExternalValue solution, but as I expect people will be using IE and other browsers I came up with an alternative solution which I will share below.

    The list we need contains medication (code + description):
    A03AE02 – Tegaserod
    A03AE04 – Prucalopride
    etc.

    As OC cannot handle the complete list, we need to store it in an external file. To make parsing easy we decided to store the codes in an XML file (ATC_Codes.xml):
    <?xml version="1.0" encoding="utf-8" ?>


    A03AE02 - Tegaserod


    A03AE04 - Prucalopride

    … etc.


    First problem is where to store the file. In a previous post when I wrote about CSS there is the nice feature that you can store and access it pretty much anywhere you like. This is not the case when you want to access a file with JavaScript, which does not allow cross-site requests. The easy solution is to store the file on your OC server; in our case we added it to the includes directory.

    Second problem is getting the data into OC. Initially, I considered creating a single-select in OC and filling that with the new options. That won’t work however, as OC doesn’t know these options and therefore won’t allow you to save them. The workaround is to create a normal OC text-field and a non-OC select field and the to copy the value from your non-OC field to your OC field.

    For this example, I have my left_item_text set to:
    textOut
    This is a text field in OC which can contain strings. I added the span tag with identifier “myOutput” so that we can reach the textfield itself.

    My right_ item_text I set to:

    None

    This is a simple HTML drop-down with identifier “myList” and it currently contains one item called None.

    Now for the code (which I pasted in the right_item_text as well):



    jQuery(document).ready(function($) {
    var myField = $("#myList")
    var myOutputField = $("#myOutput").parent().parent().find("input");
    myOutputField.attr("readonly",true);

    $.ajax({
    type: "GET",
    url: "includes/ATC_Codes.xml",
    dataType: "xml",
    success: parseXml
    });

    function parseXML(xml){
    //find every ATCCode and Description
    $(xml).find("ATCCode").each(function(){
    myField.append($("").val($(this).attr("Code")).text($(this).find("Description").text()));
    });
    myField.val(myOutputField.val());
    }

    myField.change(function(){
    myOutputField.val(myField.val());
    myOutputField.change();
    });

    });


    I’ll briefly explain the code:

    var myField = $("#myList")
    var myOutputField = $("#myOutput").parent().parent().find("input");
    myOutputField.attr("readonly",true);
    First we obtain references to the fields using the identifiers we set. We then set the output field to readonly to prevent people from editing it manually.

    $.ajax({
    type: "GET",
    url: "includes/ATC_Codes.xml",
    dataType: "xml",
    success: parseXML
    });
    We then call ajax to load the xml file. If it succeeds it calls the function parseXML

    function parseXML(xml){
    //find every ATCCode and Description
    $(xml).find("ATCCode").each(function(){
    myField.append($("").val($(this).attr("Code")).text($(this).find("Description").text()));
    });
    myField.val(myOutputField.val());
    }
    The function takes the xml file and finds each instance of ATCCode (which is the name we defined in the XML file). For each ATCCode found, we fill the single-select with the Code and the Description (both defined in the XML file). It sets the value (val) to “Code” and the text to “Description”.
    Finally we set the current value of the single-select to the current value of the output field.

    myField.change(function(){
    myOutputField.val(myField.val());
    myOutputField.change();
    });
    In this last bit, we employ the change event: if our single-select (myField) is changed, we change the output field to the select’s current value (which is the Code). We then call the output field’s change event, to inform OC that it has work to do when the save button is pressed.

    It may seem a bit complex, but it is doable. And it works like a charm, except with repeating groups; haven’t given that bit much thought yet.

    I am open to comments, questions, suggestions and easier solutions!

    Cheers,
    Sander de Ridder
  • albelomalbelom Posts: 19
    Hi Sander,
    What is the actual limit? Is it a character limit or options in a single select?

    Thanks,

    Maria R. Albelo, MA
    Data Management Associate
    Molecular NeuroImaging, LLC (MNI)
    Institute for Neurodegenerative Disorders (IND)
    P Please consider the environment before printing this email
    Sent: Thursday, July 19, 2012 4:47 AM
    To: [email protected]; [email protected]
    Subject: [Users] long lists

    Dear community,

    In one of our most recent crfs we had to create a single-select list with more options than OC would allow. I considered Gerben’s getExternalValue solution, but as I expect people will be using IE and other browsers I came up with an alternative solution which I will share below.

    The list we need contains medication (code + description):
    A03AE02 – Tegaserod
    A03AE04 – Prucalopride
    etc.

    As OC cannot handle the complete list, we need to store it in an external file. To make parsing easy we decided to store the codes in an XML file (ATC_Codes.xml):
    <?xml version="1.0" encoding="utf-8" ?>


    A03AE02 - Tegaserod


    A03AE04 - Prucalopride

    … etc.


    First problem is where to store the file. In a previous post when I wrote about CSS there is the nice feature that you can store and access it pretty much anywhere you like. This is not the case when you want to access a file with JavaScript, which does not allow cross-site requests. The easy solution is to store the file on your OC server; in our case we added it to the includes directory.

    Second problem is getting the data into OC. Initially, I considered creating a single-select in OC and filling that with the new options. That won’t work however, as OC doesn’t know these options and therefore won’t allow you to save them. The workaround is to create a normal OC text-field and a non-OC select field and the to copy the value from your non-OC field to your OC field.

    For this example, I have my left_item_text set to:
    textOut
    This is a text field in OC which can contain strings. I added the span tag with identifier “myOutput” so that we can reach the textfield itself.

    My right_ item_text I set to:

    None

    This is a simple HTML drop-down with identifier “myList” and it currently contains one item called None.

    Now for the code (which I pasted in the right_item_text as well):



    jQuery(document).ready(function($) {
    var myField = $("#myList")
    var myOutputField = $("#myOutput").parent().parent().find("input");
    myOutputField.attr("readonly",true);

    $.ajax({
    type: "GET",
    url: "includes/ATC_Codes.xml",
    dataType: "xml",
    success: parseXml
    });

    function parseXML(xml){
    //find every ATCCode and Description
    $(xml).find("ATCCode").each(function(){
    myField.append($("").val($(this).attr("Code")).text($(this).find("Description").text()));
    });
    myField.val(myOutputField.val());
    }

    myField.change(function(){
    myOutputField.val(myField.val());
    myOutputField.change();
    });

    });


    I’ll briefly explain the code:

    var myField = $("#myList")
    var myOutputField = $("#myOutput").parent().parent().find("input");
    myOutputField.attr("readonly",true);
    First we obtain references to the fields using the identifiers we set. We then set the output field to readonly to prevent people from editing it manually.

    $.ajax({
    type: "GET",
    url: "includes/ATC_Codes.xml",
    dataType: "xml",
    success: parseXML
    });
    We then call ajax to load the xml file. If it succeeds it calls the function parseXML

    function parseXML(xml){
    //find every ATCCode and Description
    $(xml).find("ATCCode").each(function(){
    myField.append($("").val($(this).attr("Code")).text($(this).find("Description").text()));
    });
    myField.val(myOutputField.val());
    }
    The function takes the xml file and finds each instance of ATCCode (which is the name we defined in the XML file). For each ATCCode found, we fill the single-select with the Code and the Description (both defined in the XML file). It sets the value (val) to “Code” and the text to “Description”.
    Finally we set the current value of the single-select to the current value of the output field.

    myField.change(function(){
    myOutputField.val(myField.val());
    myOutputField.change();
    });
    In this last bit, we employ the change event: if our single-select (myField) is changed, we change the output field to the select’s current value (which is the Code). We then call the output field’s change event, to inform OC that it has work to do when the save button is pressed.

    It may seem a bit complex, but it is doable. And it works like a charm, except with repeating groups; haven’t given that bit much thought yet.

    I am open to comments, questions, suggestions and easier solutions!

    Cheers,
    Sander de Ridder
    This message contains confidential information and is intended only for the individual(s) named. If you are not an addressee, any dissemination, distribution, or copying of this communication is strictly prohibited. Please notify the sender immediately if you have inadvertently received this message and delete it from your computer system.
  • sderiddersderidder Posts: 57
    Hi Maria,
    It is a character limit: RESPONSE_OPTIONS_TEXT has a max of 4000 characters.
    The number of options allowed in a single-select is unlimited.
    Cheers,
    Sander
  • maryam05maryam05 Posts: 89
    hi
    I extremely happy with sander performance on javascript and jquery with openclinca,it is help us on handling project on openclinca.I appreciate the information and thank you very much Sander.

    I faced the seem with 6000 list medication, and this is help me. I seek if you put print screen for the Crf.
    Thank you
    On Jul 20, 2012 5:50 PM, "Ridder, S. de" wrote:
    Hi Maria,
    It is a character limit: RESPONSE_OPTIONS_TEXT has a max of 4000 characters.
    The number of options allowed in a single-select is unlimited.
    Cheers,
    Sander
  • ccollinsccollins Posts: 379 admin
    Hi Sander,

    Would you be able to document your work in a more accessible and permanent place than the mailing list? I could see it in one of two places:
    - The Community wikibook - http://en.wikibooks.org/wiki/OpenClinica_User_Manual
    - The OpenClinica ‘Tools and tips’ page - https://wiki.openclinica.com/doku.php?id=publicwiki:otherprojects

    Also, I’d love to see a blog post (http://blog.openclinica.com/) on your experience developing this. You can contact me off-list if you are interested.*

    Thanks!
    Cal

    * - The OpenClinica blog is a great place to tell interesting stories, experiences, and ideas related to OpenClinica. So this applies to anyone else who is interested in writing for the blog – just drop me an email.
    Sent: Friday, July 20, 2012 5:44 PM
    To: [email protected]
    Subject: Re: [Users] long lists

    hi
    I extremely happy with sander performance on javascript and jquery with openclinca,it is help us on handling project on openclinca.I appreciate the information and thank you very much Sander.

    I faced the seem with 6000 list medication, and this is help me. I seek if you put print screen for the Crf.
    Thank you
    On Jul 20, 2012 5:50 PM, "Ridder, S. de" wrote:
    Hi Maria,
    It is a character limit: RESPONSE_OPTIONS_TEXT has a max of 4000 characters.
    The number of options allowed in a single-select is unlimited.
    Cheers,
    Sander
  • sderiddersderidder Posts: 57
    Hi everyone,
    Lindsay Stevens asked me whether it was possible to put the single-select in the tooltip instead of on a new page. It is indeed possible and I've updated the user manual with a third method: http://en.wikibooks.org/wiki/OpenClinica_User_Manual/LongLists
    Thanks for providing the ajax variable idea Lindsay.
    Cheers,
    Sander de Ridder
    VUmc
  • sderiddersderidder Posts: 57
    Hi everyone,
    Lindsay Stevens asked me whether it was possible to put the single-select in the tooltip instead of on a new page. It is indeed possible and I've updated the user manual with a third method: http://en.wikibooks.org/wiki/OpenClinica_User_Manual/LongLists
    Thanks for providing the ajax variable idea Lindsay.
    Cheers,
    Sander de Ridder
    VUmc
  • Hi Sander,
    Thanks again for sharing your work on this, the final product and wiki page look fantastic.
    Best regards,
    Lindsay Stevens | Clinical Data Coordinator
    NHMRC Clinical Trials Centre, THE UNIVERSITY OF SYDNEY
    Office: Level 2, 6-10 Mallett St | Camperdown | NSW | 2050
    Mail: Locked Bag 77 | Camperdown | NSW | 1450
    T +61 2 9562 5369 | F +61 2 9562 5094
    E [email protected] | W www.ctc.usyd.edu.au
    -----Original Message-----
    Sent: Tuesday, 28 August 2012 1:42 AM
    To: [email protected]; [email protected]
    Subject: Re: [Users] long lists
    Hi everyone,
    Lindsay Stevens asked me whether it was possible to put the single-select in the tooltip instead of on a new page. It is indeed possible and I've updated the user manual with a third method: http://en.wikibooks.org/wiki/OpenClinica_User_Manual/LongLists
    Thanks for providing the ajax variable idea Lindsay.
    Cheers,
    Sander de Ridder
    VUmc
  • Hi Sander,
    Thanks again for sharing your work on this, the final product and wiki page look fantastic.
    Best regards,
    Lindsay Stevens | Clinical Data Coordinator
    NHMRC Clinical Trials Centre, THE UNIVERSITY OF SYDNEY
    Office: Level 2, 6-10 Mallett St | Camperdown | NSW | 2050
    Mail: Locked Bag 77 | Camperdown | NSW | 1450
    T +61 2 9562 5369 | F +61 2 9562 5094
    E [email protected] | W www.ctc.usyd.edu.au
    -----Original Message-----
    Sent: Tuesday, 28 August 2012 1:42 AM
    To: [email protected]; [email protected]
    Subject: Re: [Users] long lists
    Hi everyone,
    Lindsay Stevens asked me whether it was possible to put the single-select in the tooltip instead of on a new page. It is indeed possible and I've updated the user manual with a third method: http://en.wikibooks.org/wiki/OpenClinica_User_Manual/LongLists
    Thanks for providing the ajax variable idea Lindsay.
    Cheers,
    Sander de Ridder
    VUmc
This discussion has been closed.