diff --git a/js-i2b2/cells/plugins/MedCo/MedCo_ctrlr.js b/js-i2b2/cells/plugins/MedCo/MedCo_ctrlr.js index 6e14646..b523682 100644 --- a/js-i2b2/cells/plugins/MedCo/MedCo_ctrlr.js +++ b/js-i2b2/cells/plugins/MedCo/MedCo_ctrlr.js @@ -1,344 +1,273 @@ /*********************** * @ProjectDescription Secure count query for sensitive genomic and clinical data with strong privacy guarantees. * @inherits i2b2 * @namespace i2b2.MedCo * @author LCA1 EPFL * @version 0.1 * -------------------------------------------------------------------------------------------------------------------- * This plugin is based on Tutorial plugin and examples on the webclient plugin development guide. */ function tryMedCoQuery() { var query = "\\\\CLINICAL_NON_SENSITIVE\\medco\\clinical\\nonsensitive\\GENDER\\Male\\ OR " + "\\\\CLINICAL_NON_SENSITIVE\\medco\\clinical\\nonsensitive\\GENDER\\Female\\" + " AND " + "\\\\SENSITIVE_TAGGED\\medco\\encrypted\\/98y5inj97O+26HXW8fJnbHDH0CCohmlCYNgMfgJ2mzufKVl8PBffruVGm1C05tqWxrXKPNF9AMghe8ELmNmzA==\\"; } function tryPHP() { var success = function (responseText) { alert(responseText); }; var error = function (err) { alert("Error when trying to retrieve the variants from the database: " + err) }; var phpQuery = 'js-i2b2/cells/plugins/MedCo/php/just_a_check.php'; i2b2.MedCo.ctrlr.phpGETRequest(success, error, phpQuery); } i2b2.MedCo.Init = function(loadedDiv) { // setup model variables for this plugin // i2b2.MedCo.model.responseXML = ''; // i2b2.MedCo.model.responseString = ''; // i2b2.MedCo.model.requestQuery = ''; // i2b2.MedCo.model.requestPSet = ''; // i2b2.MedCo.model.requestQueryType = ''; // i2b2.MedCo.model.requestQueryName = ''; // i2b2.MedCo.model.prsRecord = undefined; // i2b2.MedCo.model.infoType = true; // i2b2.MedCo.model.varType = true; // i2b2.MedCo.view.tabId = 0; // set drag and drop // i2b2.sdx.Master.AttachType("medco-pset", "PRS", {dropTarget: true}); // i2b2.sdx.Master.setHandlerCustom("medco-pset", "PRS", "DropHandler", i2b2.MedCo.ctrlr.prsDropped); // register handlers for the medco query tool panels var panels = ["medcoQryToolPanel1", "medcoQryToolPanel2", "medcoQryToolPanel3"]; var eventRouterFunc = [ function (sdxData) {i2b2.MedCo.doDrop(sdxData, 0);}, function (sdxData) {i2b2.MedCo.doDrop(sdxData, 1);}, function (sdxData) {i2b2.MedCo.doDrop(sdxData, 2);}]; for (var i = 0; i < panels.length; i++) { var op_trgt = {dropTarget: true}; i2b2.sdx.Master.AttachType(panels[i], 'CONCPT', op_trgt); // i2b2.sdx.Master.AttachType(panels[i], 'QM', op_trgt); // i2b2.sdx.Master.AttachType(panels[i], 'QI', op_trgt); // i2b2.sdx.Master.AttachType(panels[i], 'PRS', op_trgt); // i2b2.sdx.Master.AttachType(panels[i], 'PRC', op_trgt); // i2b2.sdx.Master.AttachType(panels[i], 'PR', op_trgt); // i2b2.sdx.Master.AttachType(panels[i], 'QDEF', op_trgt); // i2b2.sdx.Master.AttachType(panels[i], 'QGDEF', op_trgt); // i2b2.sdx.Master.AttachType(panels[i], 'XML', op_trgt); // register drop event handler i2b2.sdx.Master.setHandlerCustom(panels[i], 'CONCPT', 'DropHandler', eventRouterFunc[i]); // i2b2.sdx.Master.setHandlerCustom(panels[i], 'QM', 'DropHandler', eventRouterFunc[i]); // i2b2.sdx.Master.setHandlerCustom(panels[i], 'QI', 'DropHandler', eventRouterFunc[i]); // i2b2.sdx.Master.setHandlerCustom(panels[i], 'PRS', 'DropHandler', eventRouterFunc[i]); // i2b2.sdx.Master.setHandlerCustom(panels[i], 'PRC', 'DropHandler', eventRouterFunc[i]); // i2b2.sdx.Master.setHandlerCustom(panels[i], 'PR', 'DropHandler', eventRouterFunc[i]); // i2b2.sdx.Master.setHandlerCustom(panels[i], 'QDEF', 'DropHandler', eventRouterFunc[i]); // i2b2.sdx.Master.setHandlerCustom(panels[i], 'QGDEF', 'DropHandler', eventRouterFunc[i]); // i2b2.sdx.Master.setHandlerCustom(panels[i], 'XML', 'DropHandler', eventRouterFunc[i]); } // manage YUI tabs i2b2.MedCo.view.yuiTabs = new YAHOO.widget.TabView("MedCo-TABS", {activeIndex: 0}); // put in an array all the (three) panels for easier access i2b2.MedCo.view.panels = document.getElementsByClassName("medcoQryToolPanel"); for (var i = 0 ; i < 3; i++){ i2b2.MedCo.view.panels[i].innerHTML = "" } // initialize empty parameter for the query (no panels content) i2b2.MedCo.model.panels = [[], [], []]; // three panels - // POPUP init - // i2b2.MedCo.ctrlr.PopupInit(); todo delete (old popup initialization) - // POPUPS - i2b2.MedCo.ctrlr.genePopup.init(); - i2b2.MedCo.ctrlr.variantNamePopup.init(); + // POPUPS initialization + i2b2.MedCo.ctrlr.popups.ByVariantName.init(); + i2b2.MedCo.ctrlr.popups.ByGene.init(); // store how many responses I am waiting for (I have to wait to receive all the variants before sending the query) - i2b2.MedCo.ctrlr.variantsQueryCounter = 0; + // This variable is incremented by a popup when sending a query to retrieve some variants and is decremented every + // time it receives the response. + i2b2.MedCo.ctrlr.pendingVariantsQueries = 0; }; i2b2.MedCo.Unload = function() { // purge old data i2b2.MedCo.model = {}; i2b2.MedCo.view = {}; return true; }; i2b2.MedCo.doDrop = function(sdxData, nPanel) { sdxData = sdxData[0]; // only interested in first record // save the info to our local data model i2b2.MedCo.model.panels[nPanel].push(sdxData); // show the info to the user i2b2.MedCo.view.panels[nPanel].innerHTML += sdxData.sdxInfo.sdxDisplayName + "<br>"; // CHECK: some usefull functions: // alert(i2b2.h.getXNodeVal(sdxData.origData.xmlOrig, "level")) // alert(Object.getOwnPropertyNames(sdxData.origData)); // optimization to prevent requerying the hive for new results if the input dataset has not changed // i2b2.ExampTabs.model.dirtyResultsData = true; // TODO if is "Genomic annotations" then open a popup to insert the annotations - if (sdxData.sdxInfo.sdxDisplayName == "Laboratory Tests"){ - i2b2.MedCo.popupShow(nPanel); - }; + // if (sdxData.sdxInfo.sdxDisplayName == "Laboratory Tests"){ + // i2b2.MedCo.popupShow(nPanel); + // }; }; i2b2.MedCo.ctrlr.clear = function(){ - for (i = 0; i < i2b2.MedCo.view.panels.length; i++){ + for (var i = 0; i < i2b2.MedCo.view.panels.length; i++){ i2b2.MedCo.view.panels[i].innerHTML = ""; }; i2b2.MedCo.model.panels = [[], [], []]; }; i2b2.MedCo.ctrlr.run = function(){ // show the loading gif document.getElementById("MED-plainResult").innerHTML = "<img id=\"MED-loadingGif\" width=\"20px\" src=\"assets/images/spin.gif\">"; document.getElementById("MED-loadingGif").style.display = 'block'; // wait until you receive all the variants you requested - while (i2b2.MedCo.popup.variantsQueryCounter != 0) { + while (i2b2.MedCo.ctrlr.pendingVariantsQueries != 0) { // try again later to run the query setTimeout(i2b2.MedCo.ctrlr.run, 500); return } // todo delete. just checking the variables correspond with the ones in the panels // for (var i = 0; i<3; i++){ // alert(i2b2.MedCo.model.panels[i].map(function(e) { // if (typeof e === 'object'){ // return e.sdxInfo.sdxDisplayName // }else{ // return e // } // } // ) // ); // } // callback processor to run the query from definition this.MedCocallback = new i2b2_scopedCallback(); this.MedCocallback.scope = this; this.MedCocallback.callback = function(results) { try{ // alert("full message" + JSON.stringify(results)); if (results.error) { alert(results.errorMsg); return; } else { // // "results" object contains the following attributes: // // refXML: xmlDomObject <--- for data processing // // msgRequest: xml (string) // // msgResponse: xml (string) // // error: boolean // // errorStatus: string [only with error=true] // // errorMsg: string [only with error=true] // alert("response" + JSON.stringify(results.msgResponse)); // hide the loading gif document.getElementById("MED-loadingGif").style.display = 'none'; + + // print the whole response + var logdiv = document.getElementById("mylog"); + logdiv.innerHTML += "<br><br>RESPONSE:<br>" + i2b2.h.Escape(results.msgResponse); + // show the patient count var qi_list = results.refXML.getElementsByTagName('query_result_instance'); - patientCount = i2b2.h.getXNodeVal(qi_list[0], 'set_size'); + var patientCount = i2b2.h.getXNodeVal(qi_list[0], 'set_size'); document.getElementById("MED-plainResult").innerHTML = patientCount; } } catch(e){ alert("exception") } }; this.MedCoparams = {}; this.MedCoparams.result_wait_time = 180; this.MedCoparams.psm_query_definition = i2b2.MedCo.ctrlr.QueryDefinition("MedCo_query"); // chose a name for the query - // show the query - logdiv = document.getElementById("mylog"); - logdiv.innerHTML= i2b2.h.Escape(this.MedCoparams.psm_query_definition); + + // // print the query + // var logdiv = document.getElementById("mylog"); + // logdiv.innerHTML = i2b2.h.Escape(this.MedCoparams.psm_query_definition); + // sent the query this.MedCoparams.psm_result_output = i2b2.MedCo.ctrlr.ResultOutput; i2b2.CRC.ajax.runQueryInstance_fromQueryDefinition("PLUGIN:MedCo", this.MedCoparams, this.MedCocallback); }; i2b2.MedCo.ctrlr.ResultOutput = "<result_output_list><result_output priority_index=\"9\" name=\"patient_count_xml\"/>\n</result_output_list>\n"; // return the query xml i2b2.MedCo.ctrlr.QueryDefinition = function (name){ //"<query_definition>\n\t<query_name>undefined</query_name>\n\t<query_timing>ANY</query_timing>\n\t<specificity_scale>0</specificity_scale>\n\t<panel>\n\t\t<panel_number>1</panel_number>\n\t\t<panel_accuracy_scale>100</panel_accuracy_scale>\n\t\t<invert>0</invert>\n\t\t<panel_timing>ANY</panel_timing>\n\t\t<total_item_occurrences>1</total_item_occurrences>\n\t\t<item>\n\t\t\t<hlevel>1</hlevel>\n\t\t\t<item_name>Procedures</item_name>\n\t\t\t<item_key>\\\\i2b2_PROC\\i2b2\\Procedures\\</item_key>\n\t\t\t<tooltip>Procedures</tooltip>\n\t\t\t<class>ENC</class>\n\t\t\t<item_icon>FA</item_icon>\n\t\t\t<item_is_synonym>false</item_is_synonym>\n\t\t</item>\n\t</panel>\n</query_definition>\n" // get the time of the query var d = new Date(); var time = d.getHours().toString() + ":" + d.getMinutes().toString() + ":" + d.getSeconds().toString(); var queryxml = "<query_definition>\n\t<query_name>" + name + "@" + time + "</query_name>\n\t<query_timing>ANY</query_timing>\n\t<specificity_scale>0</specificity_scale>\n\t"; // hardcoded query1 (result should be 102) - // queryxml += "<panel>\n\t\t<panel_number>1</panel_number>\n\t\t<panel_accuracy_scale>100</panel_accuracy_scale>\n\t\t<invert>0</invert>\n\t\t<panel_timing>ANY</panel_timing>\n\t\t<total_item_occurrences>1</total_item_occurrences>\n\t\t<item>\n\t\t\t<hlevel>1</hlevel>\n\t\t\t<item_name>Procedures</item_name>\n\t\t\t<item_key>\\\\i2b2_PROC\\i2b2\\Procedures\\</item_key>\n\t\t\t<tooltip>Procedures</tooltip>\n\t\t\t<class>ENC</class>\n\t\t\t<item_icon>FA</item_icon>\n\t\t\t<item_is_synonym>false</item_is_synonym>\n\t\t</item>\n\t</panel>"; + //queryxml += "<panel>\n\t\t<panel_number>1</panel_number>\n\t\t<panel_accuracy_scale>100</panel_accuracy_scale>\n\t\t<invert>0</invert>\n\t\t<panel_timing>ANY</panel_timing>\n\t\t<total_item_occurrences>1</total_item_occurrences>\n\t\t<item>\n\t\t\t<hlevel>1</hlevel>\n\t\t\t<item_name>Procedures</item_name>\n\t\t\t<item_key>\\\\i2b2_PROC\\i2b2\\Procedures\\</item_key>\n\t\t\t<tooltip>Procedures</tooltip>\n\t\t\t<class>ENC</class>\n\t\t\t<item_icon>FA</item_icon>\n\t\t\t<item_is_synonym>false</item_is_synonym>\n\t\t</item>\n\t</panel>"; // hardcoded query2 (result should be 36) // queryxml += "<panel>\n\t\t<panel_number>1</panel_number>\n\t\t<panel_accuracy_scale>100</panel_accuracy_scale>\n\t\t<invert>0</invert>\n\t\t<panel_timing>ANY</panel_timing>\n\t\t<total_item_occurrences>1</total_item_occurrences>\n\t\t<item>\n\t\t\t<hlevel>2</hlevel>\n\t\t\t<item_name>Circulatory system</item_name>\n\t\t\t<item_key>\\\\i2b2_DIAG\\i2b2\\Diagnoses\\Circulatory system (390-459)\\</item_key>\n\t\t\t<tooltip>Diagnoses \\ Circulatory system</tooltip>\n\t\t\t<class>ENC</class>\n\t\t\t<item_icon>FA</item_icon>\n\t\t\t<item_is_synonym>false</item_is_synonym>\n\t\t</item>\n\t</panel>\n\t"; // queryxml += "<panel>\n\t\t<panel_number>2</panel_number>\n\t\t<panel_accuracy_scale>100</panel_accuracy_scale>\n\t\t<invert>0</invert>\n\t\t<panel_timing>ANY</panel_timing>\n\t\t<total_item_occurrences>1</total_item_occurrences>\n\t\t<item>\n\t\t\t<hlevel>2</hlevel>\n\t\t\t<item_name>Affymetrix HG-U133</item_name>\n\t\t\t<item_key>\\\\i2b2_EXPR\\i2b2\\Expression Profiles Data\\Affymetrix HG-U133\\</item_key>\n\t\t\t<tooltip>Expression Profiles Data\\Affymetrix HG-U133</tooltip>\n\t\t\t<class>ENC</class>\n\t\t\t<item_icon>FA</item_icon>\n\t\t\t<item_is_synonym>false</item_is_synonym>\n\t\t</item>\n\t\t<item>\n\t\t\t<hlevel>2</hlevel>\n\t\t\t<item_name>Skin diseases</item_name>\n\t\t\t<item_key>\\\\i2b2_DIAG\\i2b2\\Diagnoses\\Skin diseases (680-709)\\</item_key>\n\t\t\t<tooltip>Diagnoses \\ Skin diseases</tooltip>\n\t\t\t<class>ENC</class>\n\t\t\t<item_icon>FA</item_icon>\n\t\t\t<item_is_synonym>false</item_is_synonym>\n\t\t</item>\n\t</panel>\n\t"; // queryxml += "<panel>\n\t\t<panel_number>3</panel_number>\n\t\t<panel_accuracy_scale>100</panel_accuracy_scale>\n\t\t<invert>0</invert>\n\t\t<panel_timing>ANY</panel_timing>\n\t\t<total_item_occurrences>1</total_item_occurrences>\n\t\t<item>\n\t\t\t<hlevel>3</hlevel>\n\t\t\t<item_name>Diagnostic and nonsurgical procedures</item_name>\n\t\t\t<item_key>\\\\i2b2_PROC\\i2b2\\Procedures\\PRC\\ICD9 (Inpatient)\\(87-99) Diagnostic and nonsurgical procedures\\</item_key>\n\t\t\t<tooltip>Procedures \\ ICD9 (Inpatient) \\ Diagnostic and nonsurgical procedures</tooltip>\n\t\t\t<class>ENC</class>\n\t\t\t<item_icon>FA</item_icon>\n\t\t\t<item_is_synonym>false</item_is_synonym>\n\t\t</item>\n\t</panel>\n" // hardcoded query2 it run even if there is only the key for the concepts // queryxml += "<panel>\n\t\t<panel_number>1</panel_number>\n\t\t<panel_accuracy_scale>100</panel_accuracy_scale>\n\t\t<invert>0</invert>\n\t\t<panel_timing>ANY</panel_timing>\n\t\t<total_item_occurrences>1</total_item_occurrences>\n\t\t<item>\n\t\t\t<item_key>\\\\i2b2_DIAG\\i2b2\\Diagnoses\\Circulatory system (390-459)\\</item_key>\n\t\t</item>\n\t</panel>\n\t"; // queryxml += "<panel>\n\t\t<panel_number>2</panel_number>\n\t\t<panel_accuracy_scale>100</panel_accuracy_scale>\n\t\t<invert>0</invert>\n\t\t<panel_timing>ANY</panel_timing>\n\t\t<total_item_occurrences>1</total_item_occurrences>\n\t\t<item>\n\t\t\t<item_key>\\\\i2b2_EXPR\\i2b2\\Expression Profiles Data\\Affymetrix HG-U133\\</item_key>\n\t\t</item>\n\t\t<item>\n\t\t\t<item_key>\\\\i2b2_DIAG\\i2b2\\Diagnoses\\Skin diseases (680-709)\\</item_key>\n\t\t</item>\n\t</panel>\n\t"; // queryxml += "<panel>\n\t\t<panel_number>3</panel_number>\n\t\t<panel_accuracy_scale>100</panel_accuracy_scale>\n\t\t<invert>0</invert>\n\t\t<panel_timing>ANY</panel_timing>\n\t\t<total_item_occurrences>1</total_item_occurrences>\n\t\t<item>\n\t\t\t<item_key>\\\\i2b2_PROC\\i2b2\\Procedures\\PRC\\ICD9 (Inpatient)\\(87-99) Diagnostic and nonsurgical procedures\\</item_key>\n\t\t</item>\n\t</panel>\n" - for (i = 0 ; i < 3; i++){ // there are 3 panels - params = i2b2.MedCo.model.panels[i]; - nparams = params.length; + for (var i = 0 ; i < 3; i++){ // there are 3 panels + var params = i2b2.MedCo.model.panels[i]; + var nparams = params.length; if (nparams != 0) { // if in the panel there are no parameters the go to the next panel // open a panel object in which we put all its concepts queryxml += "<panel>\n\t\t<panel_number>" + i + "</panel_number>\n\t\t<panel_accuracy_scale>100</panel_accuracy_scale>\n\t\t<invert>0</invert>\n\t\t<panel_timing>ANY</panel_timing>\n\t\t<total_item_occurrences>1</total_item_occurrences>\n\t\t"; - for (j = 0; j < nparams; j++){ + for (var j = 0; j < nparams; j++){ // inters an item object for every concept queryxml += "\t\t<item>\n"; - sdxData = params[j]; - switch(sdxData.sdxInfo.sdxType) { // copied from js-i2b2/cells/CRC/CRC_ctrlr_QryTool.js - case "QM": - if(sdxData.origData.id.startsWith("masterid")) // BUG FIX: WEBCLIENT-149 - queryxml += '\t\t\t<item_key>' + sdxData.origData.id + '</item_key>\n'; - else - queryxml += '\t\t\t<item_key>masterid:' + sdxData.origData.id + '</item_key>\n'; - queryxml += '\t\t\t<item_name>' + i2b2.h.Escape(sdxData.origData.title) + '</item_name>\n'; - queryxml += '\t\t\t<tooltip>' + i2b2.h.Escape(sdxData.origData.name) + '</tooltip>\n'; - queryxml += '\t\t\t<item_is_synonym>false</item_is_synonym>\n'; - queryxml += '\t\t\t<hlevel>0</hlevel>\n'; - break; - case "PRS": - queryxml += '\t\t\t<item_key>patient_set_coll_id:' + sdxData.sdxInfo.sdxKeyValue + '</item_key>\n'; - queryxml += '\t\t\t<item_name>' + i2b2.h.Escape(sdxData.sdxInfo.sdxDisplayName) + '</item_name>\n'; - queryxml += '\t\t\t<tooltip>' + i2b2.h.Escape(sdxData.sdxInfo.sdxDisplayName) + '</tooltip>\n'; - queryxml += '\t\t\t<item_is_synonym>false</item_is_synonym>\n'; - queryxml += '\t\t\t<hlevel>0</hlevel>\n'; - break; - case "ENS": - queryxml += '\t\t\t<item_key>patient_set_enc_id:' + sdxData.sdxInfo.sdxKeyValue + '</item_key>\n'; - queryxml += '\t\t\t<item_name>' + i2b2.h.Escape(sdxData.sdxInfo.sdxDisplayName) + '</item_name>\n'; - queryxml += '\t\t\t<tooltip>' + i2b2.h.Escape(sdxData.sdxInfo.sdxDisplayName) + '</tooltip>\n'; - queryxml += '\t\t\t<item_is_synonym>false</item_is_synonym>\n'; - queryxml += '\t\t\t<hlevel>0</hlevel>\n'; - break; - default: - if (sdxData.origData.isModifier) { - var modParent = sdxData.origData.parent; - var level = sdxData.origData.level; - var key = sdxData.origData.parent.key; - var name = (sdxData.origData.parent.name != null ? i2b2.h.Escape(sdxData.origData.parent.name) : i2b2.h.Escape(sdxData.origData.name)) ; - var tooltip = sdxData.origData.tooltip; - var itemicon = sdxData.origData.hasChildren; - while (modParent != null) - { - if (modParent.isModifier) - { - modParent = modParent.parent; - } else { - level = modParent.level; - key = modParent.key; - name = modParent.name; - tooltip = modParent.tooltip; - itemicon = modParent.hasChildren; - break; - } - } - - // queryxml += '\t\t\t<hlevel>' + level + '</hlevel>\n'; - queryxml += '\t\t\t<item_key>' + key + '</item_key>\n'; - // queryxml += '\t\t\t<item_name>' + i2b2.h.Escape(name) + '</item_name>\n'; - // // (sdxData.origData.newName != null ? sdxData.origData.newName : sdxData.origData.name) + '</item_name>\n'; - // queryxml += '\t\t\t<tooltip>' + i2b2.h.Escape(tooltip) + '</tooltip>\n'; - // queryxml += '\t\t\t<item_icon>' + itemicon + '</item_icon>\n'; - // queryxml += '\t\t\t<class>ENC</class>\n'; - - queryxml += '\t\t\t\t<constrain_by_modifier>\n'; - queryxml += '\t\t\t\t\t<modifier_name>' + sdxData.origData.name + '</modifier_name>\n'; - queryxml += '\t\t\t\t\t<applied_path>' + sdxData.origData.applied_path + '</applied_path>\n'; - queryxml += '\t\t\t\t\t<modifier_key>' + sdxData.origData.key + '</modifier_key>\n'; - if (sdxData.ModValues) - { - queryxml += i2b2.CRC.view.modLabvaluesCtlr.getModLabValuesForXML(sdxData.ModValues); - } - - queryxml += '\t\t\t\t</constrain_by_modifier>\n'; - } else { - sdxData.origData.key = (sdxData.origData.key).replace(/</g,"<"); - // sdxData.origData.name = (sdxData.origData.name).replace(/</g,"<"); - // if (undefined != sdxData.origData.tooltip) - // sdxData.origData.tooltip = (sdxData.origData.tooltip).replace(/</g,"<"); - // queryxml += '\t\t\t<hlevel>' + sdxData.origData.level + '</hlevel>\n'; - // //s += '\t\t\t<item_name>' + (sdxData.origData.newName != null ? i2b2.h.Escape(sdxData.origData.newName) : i2b2.h.Escape(sdxData.origData.name)) + '</item_name>\n'; - // queryxml += '\t\t\t<item_name>' + (sdxData.origData.name != null ? i2b2.h.Escape(sdxData.origData.name) : i2b2.h.Escape(sdxData.origData.newName)) + '</item_name>\n'; - queryxml += '\t\t\t<item_key>' + sdxData.origData.key + '</item_key>\n'; - // queryxml += '\t\t\t<tooltip>' + i2b2.h.Escape(sdxData.origData.tooltip) + '</tooltip>\n'; // BUG FIX: WEBCLIENT-135 (Escape tooltip) - // queryxml += '\t\t\t<class>ENC</class>\n'; - // queryxml += '\t\t\t<item_icon>' + sdxData.origData.hasChildren + '</item_icon>\n'; - } - try { - var t = i2b2.h.XPath(sdxData.origData.xmlOrig,'descendant::synonym_cd/text()'); - t = (t[0].nodeValue=="Y"); - } catch(e) { - var t = "false"; - } - queryxml += '\t\t\t<item_is_synonym>'+t+'</item_is_synonym>\n'; - - if (sdxData.LabValues && !jQuery.isEmptyObject(sdxData.LabValues)) { - queryxml += i2b2.CRC.view.modLabvaluesCtlr.getModLabValuesForXML(sdxData.LabValues); - } - break; + var sdxData = params[j]; + + sdxData.origData.key = (sdxData.origData.key).replace(/</g,"<"); + queryxml += '\t\t\t<item_key>' + sdxData.origData.key + '</item_key>\n'; + + try { + var t = i2b2.h.XPath(sdxData.origData.xmlOrig,'descendant::synonym_cd/text()'); + t = (t[0].nodeValue=="Y"); + } catch(e) { + var t = "false"; } + // lab values ?? + // if (sdxData.LabValues && !jQuery.isEmptyObject(sdxData.LabValues)) { + // queryxml += i2b2.CRC.view.modLabvaluesCtlr.getModLabValuesForXML(sdxData.LabValues); + // } queryxml += '\t\t</item>\n'; } queryxml +="\n\t</panel>\n" } } queryxml += "\n</query_definition>\n"; return queryxml }; function backslashX2(str) { return str.replace("\\", "\\\\"); } // whole harcoded query, should return 13 // <query_definition> <query_name>query3@9:47:2</query_name> <query_timing>ANY</query_timing> <specificity_scale>0</specificity_scale> <panel> <panel_number>0</panel_number> <panel_accuracy_scale>100</panel_accuracy_scale> <invert>0</invert> <panel_timing>ANY</panel_timing> <total_item_occurrences>1</total_item_occurrences> <item> <item_key>\\i2b2_PROC\i2b2\Procedures\PRC\ICD9 (Inpatient)\(87-99) Diagnostic and nonsurgical procedures\</item_key> <item_is_synonym>false</item_is_synonym> </item> </panel> <panel> <panel_number>1</panel_number> <panel_accuracy_scale>100</panel_accuracy_scale> <invert>0</invert> <panel_timing>ANY</panel_timing> <total_item_occurrences>1</total_item_occurrences> <item> <item_key>\\i2b2_PROV\i2b2\Providers\Emergency\</item_key> <item_is_synonym>false</item_is_synonym> </item> </panel> </query_definition> \ No newline at end of file diff --git a/js-i2b2/cells/plugins/MedCo/assets/injected_screens.html b/js-i2b2/cells/plugins/MedCo/assets/injected_screens.html index 9bd1d78..3f20cab 100644 --- a/js-i2b2/cells/plugins/MedCo/assets/injected_screens.html +++ b/js-i2b2/cells/plugins/MedCo/assets/injected_screens.html @@ -1,256 +1,256 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <body> <div id='MedCo-mainDiv'> <div id="MedCo-TABS" class="yui-navset"> <!--tabs definitions--> <ul class="yui-nav"> <li id="MedCo-TAB0" class="selected"><a href="#MedCo-TAB0"><em>Secure Query Dashboard</em></a></li> <!--<li id="MedCo-TAB1"><a href="#MedCo-TAB1"><em>Genomic Annotations Attributes</em></a></li>--> <!--<li id="MedCo-TAB2"><a href="#MedCo-TAB2"><em>Clinical Ontology Attributes</em></a></li>--> <li id="MedCo-TAB3"><a href="#MedCo-TAB3"><em>Plugin Help</em></a></li> </ul> <!-- tabs definition --> <div class="yui-content" id="MedCo-CONTENT"> <!-- Secure Query DashBoard tab --> <div class="MedCo-Dashboard"> <!-- run - reset - drop patient set - query for query status - decrypt result --> <div class="MedCo-ControlButtons"> <!-- old popup todo delete <!– Popup –>--> <!--<div id="annoMessage" class="popupMessage">--> <!--<div>--> <!--<h1>Annotations</h1>--> <!--<div style="margin: 5px 10px 10px 10px">--> <!--<label>--> <!--Select an annotation:--> <!--<input type="search" id="searchAnnotationBox">--> <!--<select id="annotationList" onchange="i2b2.MedCo.ctrlr.loadAnnotationValues()">--> <!--</select>--> <!--</label>--> <!--<br>--> <!--<label>--> <!--Select a value:--> <!--<input type="search" id="searchAnnotationValueBox">--> <!--<!–<div id="MED-loadingValues" style="float:left;"></div>–>--> <!--<!–todo often too many values (20 000) the select is useless and slow–>--> <!--<!–<select id="annotationValueList">–>--> <!--<!–</select>–>--> <!--<!–use span for inline text–>--> <!--<span id="selectedAnnotationValue"></span>--> <!--</label>--> <!--<!–<br>–>--> <!--<!–a textbox to write down annotations–>--> <!--<!–<label>–>--> <!--<!–Write the annotations separated by a ';':–>--> <!--<!–<input–>--> <!--<!–id="written_annotations"–>--> <!--<!–type="text"–>--> <!--<!–value="annotation x"–>--> <!--<!–onkeypress="i2b2.MedCo.popupEnterPressed(event)">–>--> <!--<!–</label>–>--> <!--<div>--> <!--<input type="button" value="Ok" onclick="i2b2.MedCo.popupOk()" style="float: left">--> <!--<input type="button" value="Cancel" onclick="i2b2.MedCo.popupHide()" style="float: right">--> <!--</div>--> <!--</div>--> <!--</div>--> <!--</div>--> <!--<!– –>--> - <input type="button" onclick="i2b2.MedCo.ctrlr.genePopup.show(1);" value="show gene popup"/> - <input type="button" onclick="i2b2.MedCo.ctrlr.variantNamePopup.show(1);" value="show variant name popup"/> + <input type="button" onclick="i2b2.MedCo.ctrlr.popups.ByGene.show(1);" value="show gene popup"/> + <input type="button" onclick="i2b2.MedCo.ctrlr.popups.ByVariantName.show(1);" value="show variant name popup"/> <input type="button" onclick="tryPHP();" value="check php"/> <input type="button" onclick="tryMedCoQuery();" value="hardcoded query"/> <h2 class="medcoQryToolTitle">Drop concepts here</h2> <div class="medcoQryToolPanels"> <div> <!--<div class="droptrgtlbl">Drop concepts here</div>--> <div id="medcoQryToolPanel1" class="medcoQryToolPanel droptrgt SDX-PRS"> <p id="panel1content"> </p> </div> <div id="medcoQryToolPanel2" class="medcoQryToolPanel droptrgt SDX-PRS"> <p id="panel2content"> </p> </div> <div id="medcoQryToolPanel3" class="medcoQryToolPanel droptrgt SDX-PRS"> <p id="panel3content"> </p> </div> <!--<!–Show chosen annotations–>--> <!--<div style="background-color: aliceblue; height: 100%; " class="medcoQryToolPanel">--> <!--<h3>Chosen annotations: </h3>--> <!--<p id="chosen_annotations"> </p>--> <!--<input type="button" value="Clear" onclick="i2b2.MedCo.Clear()">--> <!--</div>--> <!--<!– –>--> </div> </div> <div> <div style="padding-top: 10px"> <div class="MED-Buttons"> <div class="runButton"><a href="JavaScript:i2b2.MedCo.ctrlr.run()">Run Query</a></div> <div class="resetButton"><a href="JavaScript:i2b2.MedCo.ctrlr.clear()">Clear</a></div> </div> <table class="MED-resultTable"> <tbody> <tr> <td>Number of patients</td> </tr> <tr> <td id="MED-plainResult"> - </td> </tr> </tbody> </table> <!--<div class="statusBox"><a href="JavaScript:i2b2.MedCo.ctrlr.queryStatus()">Query Status</a></div>--> <!-- status info goes into lower status div in i2b2 --> </div> </div> - <div id="mylog" style="overflow: scroll; width: 100%; height: 100%;"> + <pre id="mylog" style="overflow: scroll; width: 100%; height: 100%;"> - </div> + </pre> </div> </div> <!-- Genomic Annotations Attributes tab --> <!--<div>--> <!--<div id="byGene" style="disply:block;">--> <!--<div class="label">Genomic Annotations Search</div>--> <!--<input type="string" name="gene_input" id="gene_input" class="medco-input"/>--> <!--</div>--> <!--<div id="annotations_display">--> <!--<!– dynamically inserted annotations text –>--> <!--<!– TODO: autocompletion in text bow –>--> <!--</div>--> <!--</div>--> <!-- Clinical Ontology Attributes tab --> <!--<div>--> <!--<div id="secure_ontology_selector">--> <!--<!– dynamically inserted ontology query builder –>--> <!--</div>--> <!--</div>--> <!-- Plugin Help tab --> <div> <div class="MedCo-MainContent"> <div class="MedCo-MainContentPad"> </div> </div> </div> <!-- gene popup --> <div id="MedCo_genePopup" style="visibility: collapse;"> <div class="hd">Search by Gene</div> <div class="bd"> <p> Use the gene name box to specify the variant for which to search. When you begin typing in the search box below, the dropdown list will be populated with some matching options. Regular expressions are accepted. </p> <table class="MedCo_popupTable"> <tr> <th> Gene Name* </th> <td> <input type="search" id="searchGeneInputBox"> </td> <td> <!-- todo I should update too when the user clicks the already selected option --> <select id="geneList" onchange=" document.querySelector('#searchGeneInputBox').value = this.options[this.selectedIndex].text;"> </select> </td> </tr> <tr> <th>Zygosity*</th> <td colspan="2"> <div id="zygosityListGenePopup"> <label><input type="checkbox" id="heterozygousGenePopup">Heterozygous</label> <label><input type="checkbox" id="homozygousGenePopup">Homozygous</label> <label><input type="checkbox" id="unknownGenePopup">Unknown</label> </div> </td> </tr> </table> </div> </div> <!-- --> <!-- variant name popup --> <div id="MedCo_variantNamePopup" style="visibility: collapse;"> <div class="hd">Search by variant name</div> <div class="bd"> <p> Use the variant name box to specify the variant for which to search. When you begin typing in the search box below, the dropdown list will be populated with some matching options. Regular expressions are accepted. </p> <table class="MedCo_popupTable"> <tr> <th> Variant Name* </th> <td> <input type="search" id="searchVariantNameInputBox"> </td> <td> <!-- todo I should update too when the user clicks the already selected option --> <select id="variantNameList" onchange=" document.querySelector('#searchVariantNameInputBox').value = this.options[this.selectedIndex].text;"> </select> </td> </tr> <tr> <th>Zygosity*</th> <td colspan="2"> <div id="zygosityListVariantNamePopup"> <label><input type="checkbox" id="heterozygousVariantNamePopup">Heterozygous</label> <label><input type="checkbox" id="homozygousVariantNamePopup">Homozygous</label> <label><input type="checkbox" id="unknownVariantNamePopup">Unknown</label> </div> </td> </tr> </table> </div> </div> <!-- --> </div> </div> </div> </body> </html> diff --git a/js-i2b2/cells/plugins/MedCo/php/just_a_check.php b/js-i2b2/cells/plugins/MedCo/php/just_a_check.php index 4090b02..09cbc7f 100644 --- a/js-i2b2/cells/plugins/MedCo/php/just_a_check.php +++ b/js-i2b2/cells/plugins/MedCo/php/just_a_check.php @@ -1,28 +1,28 @@ <?php //$conn = pg_connect("host=localhost port=5432 dbname=i2b2 user=postgres password=admin"); -$conn = pg_connect("host=localhost port=5432 dbname=i2b2demo user=shrine_ont password=demouser"); +$conn = pg_connect("host=localhost port=5432 dbname=i2b2 user=shrine_ont password=demouser"); if (!$conn) { echo "Error while connecting to the postgres database"; exit; } $query = "SELECT variant_annotations FROM shrine_ont.genomic_annotations WHERE variant_id = -8935125523235860480"; $result = pg_query($conn, $query); if (!$result) { echo "An error occurred.\n"; exit; } // In json format return the list of genes $geneList = ""; while ($row = pg_fetch_row($result)) { $geneList .= "\"$row[0]\","; } // drop the last comma and concatenate in json format echo "[" . substr($geneList, 0, -1) . "]"; \ No newline at end of file diff --git a/js-i2b2/cells/plugins/MedCo/popup_ctrlr.js b/js-i2b2/cells/plugins/MedCo/popup_ctrlr.js index 7bcbf48..fcd55cb 100644 --- a/js-i2b2/cells/plugins/MedCo/popup_ctrlr.js +++ b/js-i2b2/cells/plugins/MedCo/popup_ctrlr.js @@ -1,936 +1,940 @@ -i2b2.MedCo.popup = {}; // // check the paths are correct // i2b2.MedCo.popup.getAnnotationPath = 'js-i2b2/cells/plugins/MedCo/getAnnotations.php'; // // in getAnnotationValuesPath append a variable called 'annotation_name' to specify the annotation // i2b2.MedCo.popup.getAnnotationValuesPath = 'js-i2b2/cells/plugins/MedCo/getAnnotationValues.php'; // // in getVariantsPath append two variables 'annotation_name' and 'annotation_value' to respectively specify // // the name and the value fo the annotation. Moreover, a variable 'panel_number' is needed too so to know // // to which panel correspond the received response. // i2b2.MedCo.popup.getVariantsPath = 'js-i2b2/cells/plugins/MedCo/getVariants.php'; +i2b2.MedCo.ctrlr.popups = {}; + // GENE POPUP -i2b2.MedCo.ctrlr.genePopup = { +i2b2.MedCo.ctrlr.popups.ByGene = { dialog: null, // variable to access easily the popup - popup: $("MedCo_genePopup"), + window: $("MedCo_genePopup"), // input box in which the user will write. It is an <input type="search"> element geneInputBox: document.querySelector("#searchGeneInputBox"), // selection list to display the matching genes. It is a <select> element geneList: document.querySelector("#geneList"), // selection list with the 4 predefined options zygosityList: { heterozygousCheckbox:null, homozygousCheckbox:null, unknownCheckbox:null }, // variable used for the popup to know to which panel it is bound panelNumber: 0, // todo set this when opening the popup (at the drag) // initialize the gene popup init: function(){ - var context = i2b2.MedCo.ctrlr.genePopup; + var context = i2b2.MedCo.ctrlr.popups.ByGene; - context.popup = $("MedCo_genePopup"); + context.window = $("MedCo_genePopup"); context.geneInputBox = document.querySelector("#searchGeneInputBox"); context.geneList = document.querySelector("#geneList"); // the three checkboxes context.zygosityList.heterozygousCheckbox = document.querySelector("#heterozygousGenePopup"); context.zygosityList.homozygousCheckbox = document.querySelector("#homozygousGenePopup"); context.zygosityList.unknownCheckbox = document.querySelector("#unknownGenePopup"); // update the scrolldown list every time the user digits chars context.geneInputBox .addEventListener("keyup", context.getGenes.run); context.panelNumber = 0; context.getGenes.path = 'js-i2b2/cells/plugins/MedCo/php/getGenes.php'; context.getVariants.path = 'js-i2b2/cells/plugins/MedCo/php/getVariants.php'; var handleCancel = function() { this.cancel(); }; var handleOk = function() { - var context = i2b2.MedCo.ctrlr.genePopup; + var context = i2b2.MedCo.ctrlr.popups.ByGene; // validate the fields if (context.geneList.options.length < 1){ // todo: can the user not put any gene name and just search by zygosity? (most probably too many variants) // if the drop down list is empty then alert("Please, write down a gene name and pick one choice form the dropdown list."); return; } if (context.zygosityList.heterozygousCheckbox.checked == false && context.zygosityList.homozygousCheckbox.checked == false && context.zygosityList.unknownCheckbox.checked == false) { alert("Please, select at least one zygosity option."); return; } if (context.geneInputBox.value.toLowerCase() != context.geneList.options[context.geneList.selectedIndex].text.toLowerCase()){ // if it is different then the user has still to pick one from the dropdown list alert("Please, pick a gene name from the dropdown list."); return; } // run the query to retrieve all the annotations with the specified gene and zygosyty - i2b2.MedCo.ctrlr.genePopup.getVariants.run(); + i2b2.MedCo.ctrlr.popups.ByGene.getVariants.run(); this.hide() }; context.dialog = new YAHOO.widget.SimpleDialog("MedCo_genePopup", { draggable: true, zindex: 10000, width: "500px", // height: "200px", autofillheight: "body", constraintoviewport: true, context: ["showbtn", "tl", "bl"], fixedcenter: true, modal: true, buttons: [{ text: "OK", handler: handleOk, isDefault: true }, { text: "Cancel", handler: handleCancel }] }); }, // show the popup // panelNumber: specifies with which panel is the popup related show: function(panelNumber) { - var context = i2b2.MedCo.ctrlr.genePopup; + var context = i2b2.MedCo.ctrlr.popups.ByGene; context.panelNumber = panelNumber; // context.clear(); - context.popup.show(); + context.window.show(); context.dialog.render(document.body); context.dialog.show(); }, // // hide the popup, not needed (events already registered to the various buttons) // hide: function(){ // i2b2.MedCo.ctrlr.genePopup.popup.hide(); // i2b2.MedCo.ctrlr.genePopup.dialog.cancel(); // }, // clear (empty) all the elements clear: function(){ // i2b2.MedCo.ctrlr.genePopup.geneInputBox.value = ""; // var list = i2b2.MedCo.ctrlr.genePopup.geneList; // while (list.hasChildNodes()) { // list.removeChild(list.lastChild); // } // todo clear fields? }, // get the genes names from the database getGenes: { // Store some variables I need to efficiently manage the request // path for the php request to retrieve the genes path: 'js-i2b2/cells/plugins/MedCo/getGenes.php', // if previousGene (which stores the "old" geneInputBox content) stays the same for a certain period // of time then the user stopped writing => I retrieve from the database the matching genes previousGene: "", // here I store the last executed query so to avoid repeating it lastGeneQueried: "", // here I store the current timeout (so that I can stop it when I want) timeoutGene: null, run: function () { - var context = i2b2.MedCo.ctrlr.genePopup.getGenes; + var context = i2b2.MedCo.ctrlr.popups.ByGene.getGenes; // (call run until the user stops writing) // stop the previous call (every new digits trigger a getGenes() call) clearTimeout(context.timeoutGene); // take the current value and check if it is equal to the previous one - var currGene = i2b2.MedCo.ctrlr.genePopup.geneInputBox.value.replace(/\s/g, ''); // remove whitespaces + var currGene = i2b2.MedCo.ctrlr.popups.ByGene.geneInputBox.value.replace(/\s/g, ''); // remove whitespaces if (currGene == ""){ // if it is empty then just empty the dropdown list - var list = i2b2.MedCo.ctrlr.genePopup.geneList; + var list = i2b2.MedCo.ctrlr.popups.ByGene.geneList; while (list.hasChildNodes()) { list.removeChild(list.lastChild); } context.lastGeneQueried = ""; return; } if (currGene == context.lastGeneQueried) { // if it is equal to the previous queried then I already have all the matching ones => do nothing return; } if (currGene != context.previousGene) { // if they were different then wait for the user to finish to write context.previousGene = currGene; context.timeoutGene = setTimeout(context.run, 500); return; } // If you ended up here then the user stopped writing and we can execute the query context.lastGeneQueried = currGene; // store the current query so to avoid repeating it var success = function (responseText) { - var list = i2b2.MedCo.ctrlr.genePopup.geneList; + var list = i2b2.MedCo.ctrlr.popups.ByGene.geneList; // remove all the previous genes from the dropdown list while (list.hasChildNodes()) { list.removeChild(list.lastChild); } // todo sort the genes var receivedGenes = JSON.parse(responseText); for (var i = 0; i < receivedGenes.length; i++) { var opt = document.createElement("option"); opt.value = receivedGenes[i]; opt.innerHTML = receivedGenes[i]; list.appendChild(opt); } // if there was only one match the copy that in the text box if (receivedGenes.length == 1) { - i2b2.MedCo.ctrlr.genePopup.geneInputBox.value = receivedGenes[0]; + i2b2.MedCo.ctrlr.popups.ByGene.geneInputBox.value = receivedGenes[0]; } }; var error = function (err) { alert("Error when trying to retrieve the gene values from the database: " + err) }; var phpQuery = context.path + "?gene=" + currGene + "&limit=20"; // todo is it ok 20? i2b2.MedCo.ctrlr.phpGETRequest(success, error, phpQuery); } }, // run the query to retrieve the id of the variants getVariants: { path: 'js-i2b2/cells/plugins/MedCo/getVariants.php', run: function () { - var context = i2b2.MedCo.ctrlr.genePopup; + var context = i2b2.MedCo.ctrlr.popups.ByGene; var geneName = context.geneInputBox.value; var zygosyty = []; if (context.zygosityList.heterozygousCheckbox.checked == true) { zygosyty.push("Heterozygous") } if (context.zygosityList.homozygousCheckbox.checked == true) { zygosyty.push("Homozygous") } if (context.zygosityList.unknownCheckbox.checked == true) { zygosyty.push("Unknown") } var queryType = "gene_and_zygosity"; // used at the server side to know how to build the query var success = function (responseText) { alert(responseText) var response = JSON.parse(responseText); for(var i=0; i<response.variants.length; i++) { i2b2.MedCo.model.panels[response.panel_number].push(response.variants[i]); } // I received the response so decrease the counter - i2b2.MedCo.popup.variantsQueryCounter -= 1; + i2b2.MedCo.popups.variantsQueryCounter -= 1; }; var error = function (err) { alert("Error when trying to retrieve the variants from the database: " + err) }; // increase the number of responses I should wait for i2b2.MedCo.ctrlr.variantsQueryCounter += 1; // better pass the panel number too. It will be returned with the response so that I bind it to a // specific panel. (if the query is very slow it could happen that the user starts two queries in parallel // which are related to two different panels). var phpQuery = context.getVariants.path + "?query_type=" + queryType + "&panel_number=" + context.panelNumber + "&gene_name=" + geneName + "&zygosity[]=" + zygosyty.join("&zygosity[]="); // build an array of zygosity options i2b2.MedCo.ctrlr.phpGETRequest(success, error, phpQuery); } } }; // VARIANT NAME POPUP -i2b2.MedCo.ctrlr.variantNamePopup = { +i2b2.MedCo.ctrlr.popups.ByVariantName = { dialog: null, - // variable to access easily the popup - popup: $("MedCo_variantNamePopup"), + // variable to access easily the popup's window + window: $("MedCo_variantNamePopup"), // input box in which the user will write. It is an <input type="search"> element variantNameInputBox: document.querySelector("#searchVariantNameInputBox"), // selection list to display the matching VARIANT NAMES. It is a <select> element variantNameList: document.querySelector("#variantNameList"), + // + + // selection list with the 4 predefined options zygosityList: { heterozygousCheckbox:null, homozygousCheckbox:null, unknownCheckbox:null }, // variable used for the popup to know to which panel it is bound panelNumber: 0, // todo set this when opening the popup (at the drag) // initialize the variant popup init: function(){ - var context = i2b2.MedCo.ctrlr.variantNamePopup; + var context = i2b2.MedCo.ctrlr.popups.ByVariantName; - context.popup = $("MedCo_variantNamePopup"); + context.window = $("MedCo_variantNamePopup"); context.variantNameInputBox = document.querySelector("#searchVariantNameInputBox"); context.variantNameList = document.querySelector("#variantNameList"); // the three checkboxes context.zygosityList.heterozygousCheckbox = document.querySelector("#heterozygousVariantNamePopup"); context.zygosityList.homozygousCheckbox = document.querySelector("#homozygousVariantNamePopup"); context.zygosityList.unknownCheckbox = document.querySelector("#unknownVariantNamePopup"); // update the scrolldown list every time the user digits chars context.variantNameInputBox .addEventListener("keyup", context.getVariantNames.run ); context.panelNumber = 0; context.getVariantNames.path = 'js-i2b2/cells/plugins/MedCo/php/getVariantNames.php'; context.getVariants.path = 'js-i2b2/cells/plugins/MedCo/php/getVariants.php'; var handleCancel = function() { this.cancel(); }; var handleOk = function() { - var context = i2b2.MedCo.ctrlr.variantNamePopup; + var context = i2b2.MedCo.ctrlr.popups.ByVariantName; // validate the fields if (context.variantNameList.options.length < 1){ // if the drop down list is empty then alert("Please, write down a variant name and pick one choice form the dropdown list."); return; } if (context.variantNameInputBox.value.toLowerCase() != context.variantNameList.options[context.variantNameList.selectedIndex].text.toLowerCase()){ // if it is different then the user has still to pick one from the dropdown list alert("Please, pick a variant name from the dropdown list."); return; } if (context.zygosityList.heterozygousCheckbox.checked == false && context.zygosityList.homozygousCheckbox.checked == false && context.zygosityList.unknownCheckbox.checked == false) { alert("Please, select at least one zygosity option."); return; } // run the query to retrieve all the annotations with the specified variant name and zygosyty - i2b2.MedCo.ctrlr.variantNamePopup.getVariants.run(); + i2b2.MedCo.ctrlr.popups.ByVariantName.getVariants.run(); this.hide() }; context.dialog = new YAHOO.widget.SimpleDialog("MedCo_variantNamePopup", { draggable: true, zindex: 10000, width: "500px", // height: "200px", autofillheight: "body", constraintoviewport: true, context: ["showbtn", "tl", "bl"], fixedcenter: true, modal: true, buttons: [{ text: "OK", handler: handleOk, isDefault: true }, { text: "Cancel", handler: handleCancel }] }); }, // show the popup // panelNumber: specifies with which panel is the popup related show: function(panelNumber) { - var context = i2b2.MedCo.ctrlr.variantNamePopup; + var context = i2b2.MedCo.ctrlr.popups.ByVariantName; context.panelNumber = panelNumber; // context.clear(); - context.popup.show(); + context.window.show(); context.dialog.render(document.body); context.dialog.show(); }, // // hide the popup, not needed (events already registered to the various buttons) // hide: function(){ - // i2b2.MedCo.ctrlr.variantNamePopup.popup.hide(); + // i2b2.MedCo.ctrlr.variantNamePopup.popups.hide(); // i2b2.MedCo.ctrlr.variantNamePopup.dialog.cancel(); // }, // clear (empty) all the elements clear: function(){ // i2b2.MedCo.ctrlr.variantNamePopup.variantNameInputBox.value = ""; // var list = i2b2.MedCo.ctrlr.variantNamePopup.variantNameList; // while (list.hasChildNodes()) { // list.removeChild(list.lastChild); // } // todo clear fields? }, // get the variant names from the database getVariantNames: { // Store some variables I need to efficiently manage the request // path for the php request to retrieve the variant names path: 'js-i2b2/cells/plugins/MedCo/php/getVariantNames.php', // if previousVariant (which stores the "old" variantNameInputBox content) stays the same for a certain period // of time then the user stopped writing => I retrieve from the database the matching variant names previousVariantName: "", // here I store the last executed query so to avoid repeating it lastVariantQueried: "", // here I store the current timeout (so that I can stop it when I want) timeoutVariant: null, run: function () { - var context = i2b2.MedCo.ctrlr.variantNamePopup.getVariantNames; + var context = i2b2.MedCo.ctrlr.popups.ByVariantName.getVariantNames; // (call run until the user stops writing) // stop the previous call (every new digits trigger a getVariantNames() call) clearTimeout(context.timeoutVariant); // take the current value and check if it is equal to the previous one - var currVariantName = i2b2.MedCo.ctrlr.variantNamePopup.variantNameInputBox.value.replace(/\s/g, ''); // remove whitespaces + var currVariantName = i2b2.MedCo.ctrlr.popups.ByVariantName.variantNameInputBox.value.replace(/\s/g, ''); // remove whitespaces if (currVariantName == ""){ // if it is empty then just empty the dropdown list - var list = i2b2.MedCo.ctrlr.variantNamePopup.variantNameList; + var list = i2b2.MedCo.ctrlr.popups.ByVariantName.variantNameList; while (list.hasChildNodes()) { list.removeChild(list.lastChild); } context.lastVariantQueried = ""; return; } if (currVariantName == context.lastVariantQueried) { // if it is equal to the previous query then do nothing return; } if (currVariantName != context.previousVariantName) { // if they are different then wait for the user to finish to write context.previousVariantName = currVariantName; context.timeoutVariant = setTimeout(context.run, 500); return; } // If you ended up here then the user stopped writing and we can execute the query context.lastVariantQueried = currVariantName; // store the current query so to avoid repeating it var success = function (responseText) { - var list = i2b2.MedCo.ctrlr.variantNamePopup.variantNameList; + var list = i2b2.MedCo.ctrlr.popups.ByVariantName.variantNameList; // remove all the previous variant names from the dropdown list while (list.hasChildNodes()) { list.removeChild(list.lastChild); } // todo sort the variant names var receivedVariantNames= JSON.parse(responseText); for (var i = 0; i < receivedVariantNames.length; i++) { var opt = document.createElement("option"); opt.value = receivedVariantNames[i]; opt.innerHTML = receivedVariantNames[i]; list.appendChild(opt); } // if there was only one match the copy that in the text box if (receivedVariantNames.length == 1) { - i2b2.MedCo.ctrlr.variantNamePopup.variantNameInputBox.value = receivedVariantNames[0]; + i2b2.MedCo.ctrlr.popups.ByVariantName.variantNameInputBox.value = receivedVariantNames[0]; } }; var error = function (err) { alert("Error when trying to retrieve the variant names from the database: " + err) }; var phpQuery = context.path + "?variant_name=" + currVariantName + "&limit=20"; // todo is it ok 20? i2b2.MedCo.ctrlr.phpGETRequest(success, error, phpQuery); } }, // run the query to retrieve the id of the variants getVariants: { path: 'js-i2b2/cells/plugins/MedCo/php/getVariants.php', run: function () { - var context = i2b2.MedCo.ctrlr.variantNamePopup; + var context = i2b2.MedCo.ctrlr.popups.ByVariantName; var variantName = context.variantNameInputBox.value; var zygosyty = []; if (context.zygosityList.heterozygousCheckbox.checked == true) { zygosyty.push("Heterozygous") } if (context.zygosityList.homozygousCheckbox.checked == true) { zygosyty.push("Homozygous") } if (context.zygosityList.unknownCheckbox.checked == true) { zygosyty.push("Unknown") } var queryType = "variantName_and_zygosity"; // used at the server side to know how to build the query var success = function (responseText) { alert(responseText); // todo delete var response = JSON.parse(responseText); for(var i=0; i<response.variants.length; i++) { i2b2.MedCo.model.panels[response.panel_number].push(response.variants[i]); } // I received the response so decrease the counter - i2b2.MedCo.popup.variantsQueryCounter -= 1; + i2b2.MedCo.popups.variantsQueryCounter -= 1; }; var error = function (err) { alert("Error when trying to retrieve the variants from the database: " + err) }; // increase the number of responses I should wait for i2b2.MedCo.ctrlr.variantsQueryCounter += 1; // better pass the panel number too. It will be returned with the response so that I bind it to a // specific panel. (if the query is very slow it could happen that the user starts two queries in parallel // which are related to two different panels). var phpQuery = context.getVariants.path + "?query_type=" + queryType + "&panel_number=" + context.panelNumber + "&variant_name=" + variantName + "&zygosity[]=" + zygosyty.join("&zygosity[]="); // build an array of zygosity options i2b2.MedCo.ctrlr.phpGETRequest(success, error, phpQuery); } } }; // Manage the php requests. // success: function that takes as input the response form the server // error: function that takes as input the error code returned by the server // phpQuery: string that contains the path and the parameters of the request i2b2.MedCo.ctrlr.phpGETRequest = function (success, error, phpQuery) { // create the request object to send the request and manage the response var req = false; try { // most browsers req = new XMLHttpRequest(); } catch (e) { // IE try { req = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { // try an older version try { req = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { return false; } } } // if the http request obj has not been created then return if (!req) return false; // update the request object to act when receiving the response req.onreadystatechange = function () { if (req.readyState == 4) { return req.status === 200 ? success(req.responseText) : error(req.status); } }; req.open("GET", phpQuery, true); req.send(null); return req; }; // OLD POPUP, TODO DELETE // // initialize the popup: load the names of the annotations and register handlers to manage the automatic completion // i2b2.MedCo.ctrlr.PopupInit = function (){ // // get the element to register the event handler (auto completion) // var searchAnnotationBox = document.querySelector("#searchAnnotationBox"); // var annotations = document.querySelector("#annotationList"); // this will be loaded with all the annotations // // var searchAnnotationValueBox = document.querySelector("#searchAnnotationValueBox"); // var selectedAnnotationValue = document.querySelector("#selectedAnnotationValue"); // // (inefficient) var annotationValues = document.querySelector("#annotationValueList"); // this will be loaded with all the values an annotation can assume // // // load annotations from database (that will be shown when opening the popup) // // the annotations name are loaded immediately (they are not too many) while the values of an annotation // // are loaded only when that annotation is selected // i2b2.MedCo.ctrlr.loadAnnotations(); // // // autocompletion function, e is an <input type="search"> object, list is a <select> object // function autoCompletionAnnotation (e, list) { // var text = e.target.value; // var lowerText = text.toLowerCase(); // var options = list.options; // var initialOption = options[list.selectedIndex].text; // var goodMatch = false; // for (var i = 0; i < options.length; i++) { // var option = options[i]; // var optionText = option.text; // var regex = new RegExp("^" + text, "i"); // var match = optionText.match(regex); // // best match // if (match){ // if it starts the same the select this one // option.selected = true; // break; // } // // good match (still looking for a best match) // var contains = optionText.indexOf(text) != -1; // if(contains) { // option.selected = true; // goodMatch = true; // } // if (!goodMatch) { // if no good match was found then try this too // // worse match (still looking for a good or best match) // var lowerOptionText = optionText.toLowerCase(); // contains = lowerOptionText.indexOf(lowerText) != -1; // if (contains) { // it contains the string select this one but go on with looking for a better match // option.selected = true; // } // } // option.selectedIndex = 0; // } // // if the selected annotation changed then reload its values // var currOption = options[list.selectedIndex].text; // if (initialOption != currOption) { // // want to reduce the number of "loadAnnotationValues", if after some time the option didn't changed // // then I suppose the user stopped typing // setTimeout( // function(){ // if(currOption == list.options[list.selectedIndex].text) // i2b2.MedCo.ctrlr.loadAnnotationValues() // }, 500); // } // } // // // showValue is an html object in which we will show the value // function autoCompletionAnnotationValue (e, showValue) { // var text = e.target.value; // var lowerText = text.toLowerCase(); // var values = i2b2.MedCo.popup.annotationValues; // list of possible values []string // var goodMatch = false; // for (var i = 0; i < values.length; i++) { // var valueText = values[i]; // var regex = new RegExp("^" + text, "i"); // var match = valueText.match(regex); // // best match // if (match){ // if it starts the same the select this one // showValue.innerHTML = valueText; // break; // } // // good match (still looking for a best match) // var contains = valueText.indexOf(text) != -1; // if(contains) { // showValue.innerHTML = valueText; // goodMatch = true; // } // if (!goodMatch) { // if no good match was found then try this too // // worse match (still looking for a good or best match) // var lowerValueText = valueText.toLowerCase(); // contains = lowerValueText.indexOf(lowerText) != -1; // if (contains) { // it contains the string select this one but go on with looking for a better match // showValue.innerHTML = valueText; // // } // } // } // } // // // autocomplete the annotation name when entered // searchAnnotationBox.addEventListener("keyup", function (e) {autoCompletionAnnotation(e, annotations)}); // // // autocomplete the annotation value when entered // searchAnnotationValueBox.addEventListener("keyup", function (e) {autoCompletionAnnotationValue(e, selectedAnnotationValue)}); // // // // variable used for the popup to know to which panel it is bound // i2b2.MedCo.popup.panelNumber = 0; // //variable to know which is the latest pending request sent for annotation values retrieval (the previous ones will be dropped) // i2b2.MedCo.popup.latestAnnotationRequest = ""; // // // store the current loaded annotation values // i2b2.MedCo.popup.annotationValues = []; // // // a counter used to count how many queries the client sent and is still waiting for a response. // // while this counter is > 0 the query cannot be built // i2b2.MedCo.popup.variantsQueryCounter = 0; // }; // // i2b2.MedCo.popupShow = function (panelNumber) { // i2b2.MedCo.popup.panelNumber = panelNumber; // var messageBox=document.getElementById("annoMessage"); // // Center the messageBox // // alert(messageBox.style.clientWidth) // // messageBox.style.marginTop=-messageBox.style.height/2; // // messageBox.style.marginLeft=-messageBox.style.width/2; // // // Show message box (and background) // document.getElementById("MedCo_popupBackground").style.display="block"; // messageBox.style.display="block"; // }; // // i2b2.MedCo.popupHide = function (){ // document.getElementById("MedCo_popupBackground").style.display="none"; // document.getElementById("annoMessage").style.display="none"; // }; // // // i2b2.MedCo.popupEnterPressed = function (e) { // // e = e || window.event; // // if (e.keyCode == 13) // if enter is pressed ... // // { // // i2b2.MedCo.popupOk() // // } // // }; // // i2b2.MedCo.popupOk = function(){ // // chosenAnnotationsElem = document.getElementById("chosen_annotations"); // // chosenAnnotationsElem.innerHTML = ""; // // // var annotations = document.querySelector("#annotationList"); // // var selectedAnnotation = annotations.options[annotations.selectedIndex].text; // // // // var selectedAnnotationValue = document.querySelector("#selectedAnnotationValue").innerHTML; // // var annotationValues = document.querySelector("#annotationValueList"); // // var selectedAnnotationValue = annotationValues.options[annotationValues.selectedIndex].text; // // // // var annoVal = selectedAnnotation+":"+selectedAnnotationValue; // // // i2b2.MedCo.model.chosenAnnotations[i2b2.MedCo.popup.panelNumber].push(annoVal); // // // i2b2.MedCo.view.panels[i2b2.MedCo.popup.panelNumber].innerHTML += annoVal + "<br>"; // // // i2b2.MedCo.ctrlr.loadVariants(); // send php request // i2b2.MedCo.popupHide(); // }; // // // MANAGE PHP REQUEST // // // load the annotations from the database (done only when initializing the popup!) // i2b2.MedCo.ctrlr.loadAnnotations = function () { // // create the request object to send the request and manage the response // var req = false; // try{ // // most browsers // req = new XMLHttpRequest(); // } catch (e){ // // IE // try{ // req = new ActiveXObject("Msxml2.XMLHTTP"); // } catch(e) { // // try an older version // try{ // req = new ActiveXObject("Microsoft.XMLHTTP"); // } catch(e) { // return false; // } // } // } // // if the http request obj has not been created then return // if (!req) return false; // // // define two functions to manage the result received by the server // var success = function (responseText) { // // load the popup with the annotation names (you receive a json list of strings) // var annotations = document.querySelector("#annotationList"); // // // remove all children // while (annotations.hasChildNodes()) { // annotations.removeChild(annotations.lastChild); // } // // todo sort the annotations // var receivedAnnotations = JSON.parse(responseText); // for(var i=0; i<receivedAnnotations.length; i++) // { // var opt = document.createElement("option"); // opt.value = receivedAnnotations[i]; // opt.innerHTML = receivedAnnotations[i]; // annotations.appendChild(opt); // } // i2b2.MedCo.ctrlr.loadAnnotationValues(); // }; // var error = function (err) { // alert("Error when trying to retrieve the annotations from the database." + err) // }; // // // update the request object to act when receiving the response // req.onreadystatechange = function(){ // if(req.readyState == 4) { // return req.status === 200 ? // success(req.responseText) : error(req.status); // } // }; // // req.open("GET", i2b2.MedCo.popup.getAnnotationPath, true); // req.send(null); // return req; // }; // // i2b2.MedCo.ctrlr.loadAnnotationValues = function (){ // // just reset the two elements relative to the annotation value // var selectedAnnotationValue = document.querySelector("#selectedAnnotationValue"); // selectedAnnotationValue.innerHTML = ""; // var searchAnnotationValueBox = document.querySelector("#searchAnnotationValueBox"); // searchAnnotationValueBox.innerHTML = ""; // // // don't use the select anymore // // var annotationValues = document.querySelector("#annotationValueList"); // // // remove all options // // while (annotationValues.firstChild) { // // annotationValues.removeChild(annotationValues.firstChild); // // } // // // show that we are loading the values // // document.getElementById("MED-loadingValues").innerHTML = "<img id=\"MED-LoadingValuesGif\" width=\"15px\" src=\"assets/images/spin.gif\">"; // // document.getElementById("MED-LoadingValuesGif").style.display = 'block'; // // // create the request object to send the request and manage the response // var req = false; // try{ // // most browsers // req = new XMLHttpRequest(); // } catch (e){ // // IE // try{ // req = new ActiveXObject("Msxml2.XMLHTTP"); // } catch(e) { // // try an older version // try{ // req = new ActiveXObject("Microsoft.XMLHTTP"); // } catch(e) { // return false; // } // } // } // // if the http request obj has not been created then return // if (!req) return false; // // // define two functions to manage the result received by the server // var success = function (responseText) { // // $%$ is used as delimeter (AnnotationName$%$[val1,...,valn]) // var response = responseText.split("$%$"); // if (response[0] != i2b2.MedCo.popup.latestAnnotationRequest){ // // if I received an old response just ignore it // return // } // // var receivedValues = JSON.parse(response[1].slice(1, -1)); // // load the annotation values in the popup // // var annotationValues = document.querySelector("#annotationValueList"); // don't use anymore the select // i2b2.MedCo.popup.annotationValues = []; // for(var i = 0; i < receivedValues.length; i++) // { // i2b2.MedCo.popup.annotationValues.push(receivedValues[i].toString()); // // var opt = document.createElement("option"); // // opt.value = receivedValues[i]; // // opt.innerHTML = receivedValues[i]; // // annotationValues.appendChild(opt); // } // // hide the loading gif // // document.getElementById("MED-LoadingValuesGif").style.display = 'none'; // }; // var error = function (err) { // alert("Error when trying to retrieve the values of the annotation from the database."+err) // }; // // // update the request object to act when receiving the response // req.onreadystatechange = function(){ // if(req.readyState == 4) { // return req.status === 200 ? // success(req.responseText) : error(req.status); // } // }; // // // get the selected annotation // var annotations = document.querySelector("#annotationList"); // var selectedAnnotation = annotations.options[annotations.selectedIndex].value; // // store it so that I will know if the answer is the most recent // i2b2.MedCo.popup.latestAnnotationRequest = selectedAnnotation; // // req.open("GET", i2b2.MedCo.popup.getAnnotationValuesPath + "?annotation_name=" + selectedAnnotation , true); // req.send(null); // return req; // }; // // // i2b2.MedCo.ctrlr.loadVariants = function (){ // // create the request object to send the request and manage the response // var req = false; // try{ // // most browsers // req = new XMLHttpRequest(); // } catch (e){ // // IE // try{ // req = new ActiveXObject("Msxml2.XMLHTTP"); // } catch(e) { // // try an older version // try{ // req = new ActiveXObject("Microsoft.XMLHTTP"); // } catch(e) { // return false; // } // } // } // // if the http request obj has not been created then return // if (!req) return false; // // // define two functions to manage the result received by the server // var success = function (responseText) { // var response = JSON.parse(responseText); // for(var i=0; i<response.variants.length; i++) // { // i2b2.MedCo.model.panels[response.panel_number].push(response.variants[i]); // } // // I received the response so decrease the counter // i2b2.MedCo.popup.variantsQueryCounter -= 1; // }; // var error = function (err) { // alert("Error when trying to retrieve the variants from the database."+err) // }; // // // update the request object to act when receiving the response // req.onreadystatechange = function(){ // if(req.readyState == 4) { // return req.status === 200 ? // success(req.responseText) : error(req.status); // } // }; // // // just write down that there is one more response we are waiting for // i2b2.MedCo.popup.variantsQueryCounter += 1; // // var annotations = document.querySelector("#annotationList"); // var selectedAnnotation = annotations.options[annotations.selectedIndex].value; // // var selectedValue = document.querySelector("#selectedAnnotationValue").innerHTML; // // req.open("GET", i2b2.MedCo.popup.getVariantsPath + // "?annotation_name=" + selectedAnnotation + // "&annotation_value=" + selectedValue + // "&panel_number=" + i2b2.MedCo.popup.panelNumber, true); // req.send(null); // return req; // }; \ No newline at end of file diff --git a/js-i2b2/hive/i2b2_cell_communicator.js b/js-i2b2/hive/i2b2_cell_communicator.js index 59d70db..e2be9b8 100755 --- a/js-i2b2/hive/i2b2_cell_communicator.js +++ b/js-i2b2/hive/i2b2_cell_communicator.js @@ -1,412 +1,420 @@ i2b2.hive.communicatorFactory = function(cellCode){ try { var cellURL = i2b2[cellCode].cfg.cellURL; // if (cellCode== "MedCo") { // alert(cellURL) // } } catch (e) {} if (!cellURL) { console.warn("communicatorFactory: '"+cellCode+"' does not have a cellURL specified"); } function i2b2Base_communicator(){} var retCommObj = new i2b2Base_communicator; retCommObj.ParentCell = cellCode; retCommObj.globalParams = new Hash; retCommObj.cellParams = new Hash; retCommObj._commData = {}; // setup for sniffer message retCommObj._SniffMsg = new YAHOO.util.CustomEvent('CellCommMessage'); retCommObj._addFunctionCall = function(name, url_string, xmlmsg, escapeless_params, parseFunc){ var protectedNames = ["ParentCell", "globalParams", "cellParams", "_commMsgs", "_addFunctionCall", "_doSendMsg", "_defaultCallbackOK", "_defaultCallbackFAIL"]; if (protectedNames.indexOf(name) != -1) { console.error("Attempt to build communicator call [" + name + "] failed because it is a protected name"); return false; } if (!Object.isArray(escapeless_params)) { escapeless_params = []; } escapeless_params.push("proxy_info"); escapeless_params.push("sec_pass_node"); this._commData[name] = { msg: xmlmsg, url: url_string, dont_escape_params: escapeless_params }; // create a named redirector function on the main communicator object this[name] = new Function("return this._doSendMsg.call(this, '"+name+"', arguments[0], arguments[1], arguments[2], arguments[3]);"); // save the passed parse() function if (parseFunc) { // - the parse() function will be passed the communicator packet and is expected to return the reference to the communicator packet. // - the parse() function is responsible for creating and populating the "model" namespace withing the communicator packet. this._commData[name].parser = parseFunc; } // register with the sniffer subsystem // channelName: "CELLNAME", // channelActions: ["the names", "of the", "Cell's server calls"], // channelSniffEvent: {yui custom event} var msg = { channelName: this.ParentCell, channelActions: Object.keys(this._commData), channelSniffEvent: this._SniffMsg }; i2b2.hive.MsgSniffer.RegisterMessageSource(msg); } retCommObj._doSendMsg = function(funcName, originName, parameters, callback, transportOptions){ if (!this._commData[funcName]) { console.error("Requested function does not exist [" +this.ParentCell+"->"+funcName+"] called by "+originName); return false; } var commOptions = { contentType: 'text/xml', method: 'post', asynchronous: true, evalJS: false, evalJSON: false }; var execBubble = { self: this, reqOrigin: originName, cellName: this.ParentCell, funcName: funcName, callback: callback, params: parameters }; // mix in our transport options from the originator call Object.extend(commOptions, transportOptions); // if no callback is set then we want to make this interaction synchronous if (!callback) { commOptions.asynchronous = false; } // collect message values var sMsgValues = {}; Object.extend(sMsgValues, parameters); // proxy server data sMsgValues.proxy_info = '' if (commOptions.url !== undefined) { var sUrl = commOptions.url; } else { var sUrl = i2b2[this.ParentCell].cfg.cellURL; } // CHECK which url is used when sending the message // alert(sUrl) sUrl = i2b2.h.Escape(sUrl); var syntax = /(^|.|\r|\n)(\{{{\s*(\w+)\s*}}})/; //matches symbols like '{{{ field }}}' var t = new Template(this._commData[funcName].url, syntax); sUrl = t.evaluate({URL: sUrl}); execBubble.funcURL = sUrl; var sProxy_Url = i2b2.h.getProxy(); if (sProxy_Url) { sMsgValues.proxy_info = '<proxy>\n <redirect_url>' + sUrl + '</redirect_url>\n </proxy>\n'; } else { sProxy_Url = sUrl; } execBubble.proxyURL = sProxy_Url; // PM + security info if (commOptions.user !== undefined) { sMsgValues.sec_user = commOptions.user; } else { sMsgValues.sec_user = i2b2.h.getUser(); } if (commOptions.password !== undefined) { sMsgValues.sec_pass_node = commOptions.password; } else { sMsgValues.sec_pass_node = i2b2.h.getPass(); } if (commOptions.password !== undefined) { sMsgValues.sec_domain = commOptions.domain; } else { sMsgValues.sec_domain = i2b2.h.getDomain(); } if (commOptions.project !== undefined) { sMsgValues.sec_project = commOptions.project; } else { sMsgValues.sec_project = i2b2.h.getProject(); } if (commOptions.msg_id !== undefined) { sMsgValues.header_msg_id = commOptions.msg_id; } else { sMsgValues.header_msg_id = i2b2.h.GenerateAlphaNumId(20); } if (commOptions.msg_datetime !== undefined) { sMsgValues.header_msg_datetime = commOptions.msg_datetime; } else { sMsgValues.header_msg_datetime = i2b2.h.GenerateISO8601DateTime(); } if (parameters == undefined) { parameters = {}; } if (commOptions.result_wait_time !== undefined || parameters.result_wait_time !== undefined) { if (commOptions.result_wait_time !== undefined) { sMsgValues.result_wait_time = commOptions.result_wait_time; } if (parameters.result_wait_time !== undefined) { sMsgValues.result_wait_time = parameters.result_wait_time; } } else { sMsgValues.result_wait_time = 180; // default to 180 second timeout within the cell if a specific timeout period was not passed } // apply message values to message template i2b2.h.EscapeTemplateVars(sMsgValues, this._commData[funcName].dont_escape_params); execBubble.params = sMsgValues; var syntax = /(^|.|\r|\n)(\{{{\s*(\w+)\s*}}})/; //matches symbols like '{{{ field }}}' var t = new Template(this._commData[funcName].msg, syntax); var sMessage = t.evaluate(sMsgValues); var sMessageNoPWD = new String(sMessage); if (execBubble.funcName == 'getUserAuth') { sMessageNoPWD = sMessageNoPWD.replace(/<password>.*<\/password>/gi,"<password></password>"); } execBubble.msgSent = sMessageNoPWD; var verify = i2b2.h.parseXml(sMessage); var verify_status = verify.getElementsByTagName('proxy')[0]; if (!verify_status) { sMessage = sMessage.replace(/\&/g,'&'); sMessage = sMessage.replace(/\&/g, '\&'); } commOptions.postBody = sMessage; //if (commOptions.asynchronous) { commOptions.onSuccess = this._defaultCallbackOK; commOptions.onFailure = this._defaultCallbackFAIL; //} var tmp = Object.keys(commOptions); tmp = tmp.without("asynchronous"); tmp = tmp.without("contentType"); tmp = tmp.without("encoding"); tmp = tmp.without("method"); tmp = tmp.without("parameters"); tmp = tmp.without("postBody"); tmp = tmp.without("requestHeaders"); tmp = tmp.without("evalJS"); tmp = tmp.without("evalJSON"); tmp = tmp.without("sanitizeJSON"); tmp = tmp.without("onCreate"); tmp = tmp.without("onComplete"); tmp = tmp.without("onException"); tmp = tmp.without("onFailure"); tmp = tmp.without("onInteractive"); tmp = tmp.without("onLoaded"); tmp = tmp.without("onLoading"); tmp = tmp.without("onSuccess"); tmp = tmp.without("onUninitialized"); for (var i = 0; i < tmp.length; i++) { // only delete if it's not a HTTP response code handler ex:on404 if (!/^on\d\d\d$/.match(tmp[i])) { delete commOptions[tmp[i]]; } } console.groupEnd(); execBubble.timeSent = new Date(); commOptions.i2b2_execBubble = execBubble; var myCallback = { success: function(o) { o.request = {}; o.request.options = {} o.request.options.i2b2_execBubble = commOptions.i2b2_execBubble; retCommObj._defaultCallbackOK(o); var t = 1; /* success handler code */}, failure: function(o) { o.request = {}; o.request.options = {} o.request.options.i2b2_execBubble = commOptions.i2b2_execBubble; retCommObj._defaultCallbackFAIL(o); /* failure handler code */}, }; //BG commenting out next command as it makes extra web service call in wrong place // var transaction = YAHOO.util.Connect.asyncRequest( // 'POST', sProxy_Url, myCallback, commOptions.postBody); - + + ////////// TODO delete + if (funcName == "runQueryInstance_fromQueryDefinition") { + var logdiv = document.getElementById("mylog"); + logdiv.innerHTML = "REQUEST:<br>"; + logdiv.innerHTML += i2b2.h.Escape(sMessage); + } + ///////// + if (commOptions.asynchronous) { // perform an ASYNC query // new Ajax.Request(sProxy_Url, commOptions); //BG adding next command as it makes required web service call in right place var transaction = YAHOO.util.Connect.asyncRequest( 'POST', sProxy_Url, myCallback, commOptions.postBody); return true; } else { // perform a SYNC query var ajaxresult = new Ajax.Request(sProxy_Url, commOptions); var transport = ajaxresult.transport; // create our data message to return from the function var cbMsg = { msgRequest: sMessage, msgResponse: transport.responseText, msgUrl: sUrl, msgUrlProxy: sProxy_Url, error: false }; // check the status from the message var xmlRecv = transport.responseXML; if ((!xmlRecv)&&(transport.responseText.length)) { xmlRecv = i2b2.h.parseXml(transport.responseText); } if (!xmlRecv) { cbMsg.error = true; cbMsg.errorStatus = transport.status; cbMsg.errorMsg = "The cell's message could not be interpreted as valid XML."; console.error(transport.responseText); } else { cbMsg.refXML = xmlRecv; var result_status = xmlRecv.getElementsByTagName('result_status')[0]; var s = xmlRecv.getElementsByTagName('status')[0]; if (undefined == s || s.getAttribute('type') != 'DONE') { cbMsg.error = true; cbMsg.errorStatus = transport.status; cbMsg.errorMsg = "The cell's message status could not understood."; console.error(transport.responseText); } } //BG commenting out next if block as it adds extra log entry in the xml debug window // send the result message to the callback function // if (i2b2.PM.login_debugging === undefined || (i2b2.PM.login_debugging && !i2b2.PM.login_debugging_suspend)){ // // broadcast a debug message to any sniffers/tools // var sniffPackage = i2b2.h.BuildSniffPack(execBubble.cellName, execBubble.funcName, cbMsg, execBubble.reqOrigin); // execBubble.self._SniffMsg.fire(sniffPackage); // } // attach the parse() function if (cbMsg.error || !execBubble.self._commData[execBubble.funcName]) { cbMsg.parse = function(){ this.model = false; return this; } } else { cbMsg.parse = execBubble.self._commData[execBubble.funcName].parser; } console.groupEnd(); return cbMsg; } }; retCommObj._defaultCallbackOK = function(transport){ var execBubble = transport.request.options.i2b2_execBubble; execBubble.timeRecv = new Date(); var origCallback = execBubble.callback; //update timeout i2b2.PM.model.IdleTimer.updateTimer(); // debug messages if (i2b2.PM.login_debugging === undefined || (i2b2.PM.login_debugging && !i2b2.PM.login_debugging_suspend)) { console.group("[AJAX RESULT i2b2." + execBubble.cellName + ".ajax." + execBubble.funcName + "]"); console.info("AJAX Transport SUCCESS"); console.dir(transport); } // create our data message to send to the callback function var cbMsg = { msgParams: execBubble.params, msgRequest: execBubble.msgSent, msgResponse: transport.responseText, timeStart: execBubble.timeSent, timeEnd: execBubble.timeRecv, msgUrl: execBubble.funcURL, proxyUrl: execBubble.proxyURL, error: false }; // check the status from the message var xmlRecv = null; //transport.responseXML; if ((!xmlRecv)&&(transport.responseText.length)) { xmlRecv = i2b2.h.parseXml(transport.responseText); } if (!xmlRecv) { cbMsg.error = true; cbMsg.errorStatus = transport.status; cbMsg.errorMsg = "The cell's message could not be interpreted as valid XML."; console.error(transport.responseText); } else { cbMsg.refXML = xmlRecv; var result_status = xmlRecv.getElementsByTagName('result_status'); if (!result_status[0]) { var has_error = true; } else { var s = xmlRecv.getElementsByTagName('status')[0]; } if (has_error || s.getAttribute('type') != 'DONE') { cbMsg.error = true; cbMsg.errorStatus = transport.status; cbMsg.errorMsg = "The cell's status message could not be understood."; console.error(transport.responseText); } } // attach the parse() function if (cbMsg.error || !execBubble.self._commData[execBubble.funcName]) { cbMsg.parse = function(){ this.model = false; return this; } } else { cbMsg.parse = execBubble.self._commData[execBubble.funcName].parser; } console.groupEnd(); // send the result message to the callback function if (i2b2.PM.login_debugging === undefined || (i2b2.PM.login_debugging && !i2b2.PM.login_debugging_suspend)){ // broadcast a debug message to any sniffers/tools var sniffPackage = i2b2.h.BuildSniffPack(execBubble.cellName, execBubble.funcName, cbMsg, execBubble.reqOrigin); execBubble.self._SniffMsg.fire(sniffPackage); } // return results to caller if (origCallback !== undefined ) if (getObjectClass(origCallback)=='i2b2_scopedCallback') { origCallback.callback.call(origCallback.scope, cbMsg); } else { origCallback(cbMsg); } }; retCommObj._defaultCallbackFAIL = function(transport) { var execBubble = transport.request.options.i2b2_execBubble; execBubble.timeRecv = new Date(); var origCallback = execBubble.callback; console.group("[AJAX RESULT i2b2." + execBubble.cellName + ".ajax." + execBubble.funcName + "]"); console.error("AJAX Transport FAILURE"); console.dir(transport); // create our data message to send to the callback fuction var cbMsg = { msgParams: execBubble.params, msgRequest: execBubble.msgSent, msgResponse: transport.responseText, timeStart: execBubble.timeSent, timeEnd: execBubble.timeRecv, msgUrl: execBubble.funcURL, proxyUrl: execBubble.proxyURL, error: true }; // broadcast a debug message to any sniffers/tools // send the result message to the callback function if (i2b2.PM.login_debugging === undefined || (i2b2.PM.login_debugging && !i2b2.PM.login_debugging_suspend)){ // broadcast a debug message to any sniffers/tools var sniffPackage = i2b2.h.BuildSniffPack(execBubble.cellName, execBubble.funcName, cbMsg, execBubble.reqOrigin); execBubble.self._SniffMsg.fire(sniffPackage); } // return results to caller if (origCallback !== undefined) if (getObjectClass(origCallback)=='i2b2_scopedCallback') { origCallback.callback.call(origCallback.scope, cbMsg); } else { origCallback(cbMsg); } }; return retCommObj; } diff --git a/tools/gopherjsCrypto/example.html b/tools/gopherjsCrypto/example.html new file mode 100644 index 0000000..38f2447 --- /dev/null +++ b/tools/gopherjsCrypto/example.html @@ -0,0 +1,29 @@ +<head> + <title>JS encryption tests</title> + <script type="text/javascript" src="test-medco-crypto-web.js"></script> + <script> + var pk,sk; + var cipher, plain; + + function genkey(){ + [sk, pk] = GenKey() + alert("Secret key: " + sk + "\nPrivate key: " + pk) + } + + function encrypt(){ + cipher = EncryptInt(pk, 5000) + alert("Cipher: " + cipher) + } + function decrypt() { + plain = DecryptInt(cipher, sk) + alert("Plaintext: " + plain) + } + </script> +</head> +<body> + <input type="button" onclick="genkey()" value="gen key"> + <input type="button" onclick="encrypt()" value="encrypt 5000"> + <input type="button" onclick="decrypt()" value="decrypt"> + +</body> +</html> diff --git a/tools/gopherjsCrypto/test.html b/tools/gopherjsCrypto/test.html new file mode 100644 index 0000000..b39f971 --- /dev/null +++ b/tools/gopherjsCrypto/test.html @@ -0,0 +1,15 @@ +<head> + <title>JS encryption tests</title> + <script type="text/javascript" src="test-medco-crypto-web.js"></script> + <script> + function myfunc() { + plain = DecryptInt("F43RC98qfZJp9ClCz4UY9PhZ/jSTnjbN6+K00rH7MEc3jrenGWZsnvv/PYbp3uAnW2Yh0cZQzs3+O76MT2Kt7w==", "U/MCDDfD63GSZiP26OrCU3HIkvqHdyReYV/vEk8oZQM=") + alert(plain) + } + </script> +</head> +<body> + <input type="button" onclick="myfunc()" value="CLICK ME"> + +</body> +</html>