3 * general solGS app wide and misc functions
4 * @author Isaak Y Tecle <iyt2@cornell.edu>
8 JSAN.use("jquery.blockUI");
9 JSAN.use("jquery.form");
11 var solGS = solGS || function solGS() {};
14 waitPage: function (page, args) {
15 var host = window.location.protocol + "//" + window.location.host;
16 page = page.replace(host, "");
20 "|solgs/populations/combined/" +
22 "|solgs/model/combined/trials/" +
23 "|solgs/search/trials/trait//" +
24 "|solgs/selection/\\d+|\\w+_\\d+/model/" +
25 "|solgs/combined/model/\\d+|\\w+_\\d+/selection/" +
26 "|solgs/models/combined/trials/" +
27 "|solgs/traits/all/population/" +
29 "|kinship/analysis/" +
32 if (page.match(matchItems)) {
33 var multiTraitsUrls = "solgs/traits/all/population/" + "|solgs/models/combined/trials/";
35 if (page.match(multiTraitsUrls)) {
36 this.getTraitsSelectionId(page, args);
38 //if (page.match(/list_/)) {
39 // askUser(page, args)
41 this.checkCachedResult(page, args);
45 this.goToPage(page, args);
49 checkCachedResult: function (page, args) {
50 var trainingTraitsIds = solGS.getTrainingTraitsIds();
52 if (trainingTraitsIds) {
54 args = { training_traits_ids: trainingTraitsIds };
56 args["training_traits_ids"] = trainingTraitsIds;
60 args = this.getArgsFromUrl(page, args);
61 args = JSON.stringify(args);
66 data: { page: page, arguments: args },
67 url: "/solgs/check/cached/result/",
68 success: function (response) {
69 if (response.cached) {
70 args = JSON.parse(args);
71 solGS.submitJob.goToPage(page, args);
73 if (document.URL.match(/solgs\/population\/|solgs\/populations\/combined\//)) {
74 solGS.submitJob.checkTrainingPopRequirement(page, args);
76 args = JSON.parse(args);
77 solGS.submitJob.askUser(page, args);
82 alert("Error occured checking for cached output.");
87 checkTrainingPopRequirement: function (page, args) {
92 url: "/solgs/check/training/pop/size/",
93 success: function (res) {
94 var trainingPopSize = res.member_count;
95 if (trainingPopSize >= 20) {
96 args = JSON.parse(args);
97 solGS.submitJob.askUser(page, args);
100 "The training population size (" +
102 ") is too small. Minimum required is 20.";
104 solGS.alertMessage(msg);
110 askUser: function (page, args) {
112 "<p>Since the job takes long time, you can only submit and wait for an email with a link to the results. " +
113 "Do you want to submit it and get an email when it completes?</p>";
115 var jobSubmit = '<div id= "job_submission">' + title + "</div>";
117 jQuery(jobSubmit).appendTo("body");
119 jQuery("#job_submission").dialog({
123 title: "Job submission",
127 class: "btn btn-success",
130 jQuery(this).dialog("close");
132 solGS.submitJob.checkUserLogin(page, args);
136 // text: 'No, I will wait...',
137 // class: 'btn btn-primary',
139 // click: function() {
140 // jQuery(this).dialog("close");
142 // analyzeNow(page, args);
147 class: "btn btn-info",
148 id: "cancel_queue_info",
150 jQuery(this).dialog("close");
157 checkUserLogin: function (page, args) {
158 if (args === undefined) {
165 url: "/solgs/check/user/login/",
166 success: function (res) {
168 var contact = res.contact;
170 args["first_name"] = contact.first_name;
171 args["user_email"] = contact.email;
172 args["user_name"] = contact.user_name;
173 solGS.submitJob.getProfileDialog(page, args);
175 solGS.submitJob.loginAlert();
181 loginAlert: function () {
183 .html("To use this feature, you need to log in and start over the process.")
192 jQuery(this).dialog("close");
193 solGS.submitJob.loginUser();
195 class: "btn btn-success",
201 jQuery(this).dialog("close");
203 class: "btn btn-primary",
210 loginUser: function () {
211 window.location = "/user/login?goto_url=" + window.location.pathname;
214 getTraitsSelectionId: function (page, args) {
215 var traitIds = args.training_traits_ids;
216 var protocolId = solGS.genotypingProtocol.getGenotypingProtocolId();
221 data: { trait_ids: traitIds },
222 url: "/solgs/get/traits/selection/id",
223 success: function (res) {
224 var traitsSelectionId = res.traits_selection_id;
225 page = page + "/traits/" + traitsSelectionId + "/gp/" + protocolId;
227 //if (page.match(/list_/)) {
228 // askUser(page, args)
230 solGS.submitJob.checkCachedResult(page, args);
233 error: function (res, st, error) {
234 alert("error: " + error);
239 goToPage: function (page, args) {
240 jQuery.blockUI.defaults.applyPlatformOpacityRules = false;
241 jQuery.blockUI({ message: "Please wait.." });
244 "solgs/submission/feedback" +
246 "|solgs/traits/all/population/" +
247 "|solgs/models/combined/trials/" +
248 "|solgs/model/combined/trials/" +
250 "|kinship/analysis/" +
251 "|cluster/analysis/";
253 if (page.match(matchItems)) {
254 window.location = page;
255 } else if (page.match(/solgs\/populations\/combined\//)) {
256 solGS.combinedTrials.displayCombinedTrialsTrainingPopPage(args);
257 } else if (page.match(/solgs\/population\//)) {
258 // if (page.match(/solgs\/population\/list_/)) {
259 // var listId = args.list_id;
260 // loadPlotListTypeTrainingPop(listId);
262 window.location = page;
264 } else if (page.match(/solgs\/selection\//)) {
266 "solgs/selection/\\w+_\\d+/model/\\w+_\\d+/" + "|solgs/selection/\\d+/model/\\w+_\\d+/";
268 if (page.match(/listTypePages/)) {
269 loadGenotypesListTypeSelectionPop(args);
271 window.location = page;
274 window.location = window.location.href;
278 submitTraitSelections: function (page, args) {
281 if (args == "undefined") {
282 document.getElementById("traits_selection_form").submit();
283 document.getElementById("traits_selection_form").reset();
285 jQuery("#traits_selection_form").ajaxSubmit();
286 jQuery("#traits_selection_form").resetForm();
290 wrapTraitsForm: function () {
291 var popId = jQuery("#population_id").val();
292 var protocolId = solGS.genotypingProtocol.getGenotypingProtocolId();
294 var formId = ' id="traits_selection_form"';
297 var referer = window.location.href;
299 if (referer.match(/solgs\/populations\/combined\//)) {
300 action = ' action="/solgs/models/combined/trials/' + popId + "/gp/" + protocolId + '"';
303 if (referer.match(/solgs\/population\//)) {
304 action = ' action="/solgs/traits/all/population/' + popId + "/gp/" + protocolId + '"';
307 var method = ' method="POST"';
309 var traitsForm = "<form" + formId + action + method + ">" + "</form>";
311 jQuery("#population_traits_list").wrap(traitsForm);
314 getProfileDialog: function (page, args) {
316 "/solgs/population/" +
318 "|solgs/model/combined/trials/" +
319 "|solgs/combined/model/\\d+|\\w+_\\d+/selection/" +
320 "|solgs/selection/\\d+|\\w+_\\d+/model/";
322 if (page.match(matchItems)) {
323 args = this.getArgsFromUrl(page, args);
326 var form = this.getProfileForm(args);
327 jQuery("<div />", { id: "email-form" })
333 title: "Info about the analysis",
336 click: function (e) {
337 var analysisProfile = solGS.submitJob.structureAnalysisProfile(page, args);
338 solGS.submitJob.validateAnalysisInput(analysisProfile);
341 class: "btn btn-success",
347 jQuery(this).dialog("close");
349 class: "btn btn-primary",
356 structureAnalysisProfile: function (page, args) {
357 var userEmail = jQuery("#user_email").val();
358 var analysisName = jQuery("#analysis_name").val();
359 var analysisType = args.analysis_type;
360 var userName = args.user_name;
361 var dataSetType = args.data_set_type;
363 args["user_email"] = userEmail;
364 args["analysis_name"] = analysisName;
365 args["analysis_page"] = page;
367 var hostname = `${location.protocol}//${location.hostname}`;
368 args['hostname'] = hostname;
370 args = JSON.stringify(args);
372 var analysisProfile = {
374 analysis_name: analysisName,
376 analysis_type: analysisType,
377 data_set_type: dataSetType,
381 return analysisProfile;
384 validateAnalysisInput: function (analysisProfile) {
385 var analysisName = jQuery("#analysis_name").val();
388 jQuery("#form-feedback-analysis-name").text("Analysis name is blank. Please give a name.");
390 var checkName = solGS.submitJob.checkAnalysisName(analysisName);
392 checkName.done(function (res) {
393 if (res.analysis_exists) {
394 jQuery("#analysis_name").css("border", "solid #FF0000");
396 jQuery("#form-feedback-analysis-name").text(
397 "The same name exists for another analysis. Please give a new name."
400 var email = jQuery("#user_email").val();
401 var emailPass = solGS.submitJob.checkEmail(email);
404 jQuery("#email-form").dialog("close");
405 solGS.submitJob.saveAnalysisProfile(analysisProfile);
411 checkName.fail(function (res) {
413 "Error occured submitting the job. Please contact the developers." +
416 solGS.alertMessage(message);
420 checkEmail: function (email) {
422 var emailRegex = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/i;
423 if (!email.match(emailRegex)) {
424 jQuery("#user_email").css("border", "solid #FF0000");
426 jQuery("#form-feedback-user-email").text("Please provide a proper email address.");
436 checkAnalysisName: function (name) {
437 var analysisName = jQuery.ajax({
440 data: { name: name },
441 url: "/solgs/check/analysis/name",
447 getArgsFromUrl: function (url, args) {
448 var referer = document.URL;
449 var host = window.location.protocol + "//" + window.location.host;
450 referer = referer.replace(host, "");
452 if (args === undefined) {
456 if (window.Prototype) {
457 delete Array.prototype.toJSON;
460 if (url.match(/solgs\/trait\//)) {
461 var urlStr = url.split(/\/+/);
463 args["trait_id"] = [urlStr[3]];
464 args["training_pop_id"] = [urlStr[5]];
465 args["analysis_type"] = "training_model";
466 args["data_set_type"] = "single_population";
467 } else if (url.match(/solgs\/model\/combined\/trials\//)) {
468 var urlStr = url.split(/\/+/);
471 var populationId = [];
472 var comboPopsId = [];
475 if (referer.match(/solgs\/search\/trials\/trait\//)) {
476 populationId.push(urlStr[5]);
477 comboPopsId.push(urlStr[5]);
478 traitId.push(urlStr[7]);
479 protocolId = urlStr[9];
480 } else if (referer.match(/solgs\/populations\/combined\//)) {
481 populationId.push(urlStr[5]);
482 comboPopsId.push(urlStr[5]);
483 traitId.push(urlStr[7]);
484 protocolId = urlStr[9];
487 args["trait_id"] = traitId;
488 args["training_pop_id"] = populationId;
489 args["combo_pops_id"] = comboPopsId;
490 args["analysis_type"] = "training_model";
491 args["data_set_type"] = "combined_populations";
492 args["genotyping_protocol_id"] = protocolId;
493 } else if (url.match(/solgs\/population\//)) {
494 var urlStr = url.split(/\/+/);
496 args["training_pop_id"] = [urlStr[3]];
497 args["analysis_type"] = "training_dataset";
498 args["data_set_type"] = "single_population";
499 args["genotyping_protocol_id"] = urlStr[5];
500 } else if (url.match(/solgs\/selection\//)) {
501 var traitId = jQuery("#trait_id").val();
502 var modelId = jQuery("#model_id").val();
503 var urlStr = url.split(/\/+/);
507 if (referer.match(/solgs\/model\/combined\/trials\/|solgs\/models\/combined\//)) {
508 dataSetType = "combined_populations";
509 } else if (referer.match(/solgs\/trait\/|solgs\/traits\/all\/population\//)) {
510 dataSetType = "single_population";
513 args["trait_id"] = [traitId];
514 args["training_pop_id"] = [urlStr[5]];
515 args["selection_pop_id"] = [urlStr[3]];
516 args["analysis_type"] = "selection_prediction";
517 args["data_set_type"] = dataSetType;
518 } else if (url.match(/solgs\/combined\/model\//)) {
519 var urlStr = url.split(/\/+/);
520 //var protocolId = urlStr[10];
521 var dataSetType = "combined_populations";
523 args["training_pop_id"] = [urlStr[4]];
524 args["selection_pop_id"] = [urlStr[6]];
525 args["trait_id"] = [urlStr[8]];
526 args["analysis_type"] = "selection_prediction";
527 args["data_set_type"] = dataSetType;
530 var trainingTraitsIds = jQuery("#training_traits_ids").val();
532 if (trainingTraitsIds) {
533 trainingTraitsIds = trainingTraitsIds.split(",");
534 args["training_traits_ids"] = trainingTraitsIds;
535 args["trait_id"] = trainingTraitsIds;
538 var protocolId = args.genotyping_protocol_id;
540 protocolId = solGS.genotypingProtocol.getGenotypingProtocolId();
543 var popDesc = jQuery("#training_pop_desc").val();
545 args["training_pop_desc"] = jQuery("#training_pop_desc").val();
546 args["selection_pop_desc"] = jQuery("#selection_pop_desc").val();
547 args["genotyping_protocol_id"] = protocolId;
548 args["referer"] = referer;
553 getProfileForm: function (args) {
555 if (args.user_email) {
556 email = args.user_email;
560 if (args.first_name) {
561 firstName = args.first_name;
565 '<form><div class="form-group">' +
566 '<label for="first_name">Name:</label>' +
567 '<input type="text" class="form-control" id="first_name" value="' +
571 '<div class="form-group">' +
572 '<label for="analysis_name">Analysis name:</label>' +
573 '<input type="text" class="form-control" id="analysis_name">' +
574 '<div style="color:red" id="form-feedback-analysis-name"> </div>' +
576 '<div class="form-group">' +
577 '<label for="user_email">Email:</label>' +
578 '<input type="email" class="form-control" id="user_email" value="' +
581 '<div style="color:red" id="form-feedback-user-email"> </div>' +
588 saveAnalysisProfile: function (profile) {
593 url: "/solgs/save/analysis/profile/",
594 success: function (response) {
595 if (response.result) {
596 solGS.submitJob.runAnalysis(profile);
598 var message = "Failed saving your analysis profile.";
599 solGS.alertMessage(message);
603 var message = "Error occured calling the function to save your analysis profile.";
604 solGS.alertMessage(message);
609 runAnalysis: function (profile) {
614 url: "/solgs/run/saved/analysis/",
615 success: function (res) {
616 if (res.result.match(/Submitted/)) {
617 solGS.submitJob.submissionFeedback(res.arguments);
620 "Error occured submitting the job. Please contact the developers." +
623 solGS.alertMessage(message);
626 error: function (response) {
628 "Error occured submitting the job. Please contact the developers." +
631 solGS.alertMessage(message);
636 submissionFeedback: function (args) {
637 args = JSON.parse(args);
638 var analysisType = args.analysis_type;
639 analysisType = analysisType.replace(/\s+|-/g, "_");
641 solGS.submitJob.goToPage("/solgs/submission/feedback/?job=" + analysisType);
644 selectTraitMessage: function () {
646 '<p style="text-align:justify;">' +
647 "Please select one or more traits to build prediction models.</p>";
655 title: "Prediction Modeling Message",
659 class: "btn btn-success",
660 id: "select_trait_message",
662 jQuery(this).dialog("close");
670 solGS.waitPage = function (page, args) {
671 solGS.submitJob.waitPage(page, args);
674 jQuery(document).ready(function () {
675 jQuery("#runGS").on("click", function () {
676 if (window.Prototype) {
677 delete Array.prototype.toJSON;
680 var traitIds = jQuery("#traits_selection_div :checkbox").fieldValue();
681 var popId = jQuery("#training_pop_id").val();
682 var protocolId = solGS.genotypingProtocol.getGenotypingProtocolId();
684 if (traitIds.length) {
689 var referer = window.location.href;
691 if (referer.match(/solgs\/populations\/combined\//)) {
692 dataSetType = "combined_populations";
695 if (referer.match(/solgs\/population\//)) {
696 dataSetType = "single_population";
699 if (traitIds.length == 1) {
700 analysisType = "training_model";
702 if (referer.match(/solgs\/populations\/combined\//)) {
704 "/solgs/model/combined/trials/" + popId + "/trait/" + traitIds[0] + "/gp/" + protocolId;
705 } else if (referer.match(/solgs\/population\//)) {
706 page = "/solgs/trait/" + traitIds[0] + "/population/" + popId + "/gp/" + protocolId;
709 analysisType = "multiple_models";
711 if (referer.match(/solgs\/populations\/combined\//)) {
712 page = "/solgs/models/combined/trials/" + popId;
714 page = "/solgs/traits/all/population/" + popId;
720 training_traits_ids: traitIds,
721 training_pop_id: [popId],
722 analysis_type: analysisType,
723 data_set_type: dataSetType,
726 solGS.submitJob.waitPage(page, args);
728 solGS.submitJob.selectTraitMessage();
733 solGS.alertMessage = function (msg, msgTitle, divId) {
735 msgTitle = "Message";
739 divId = "error_message";
742 jQuery("<div />", { id: divId })
752 jQuery(this).dialog("close");
753 //window.location = window.location.href;
755 class: "btn btn-success",
762 solGS.getTraitDetails = function (traitId) {
764 traitId = jQuery("#trait_id").val();
771 data: { trait_id: traitId },
772 url: "/solgs/details/trait/" + traitId,
773 success: function (trait) {
774 jQuery(document.body).append(
775 '<input type="hidden" id="trait_name" value="' + trait.name + '"></input>'
777 jQuery(document.body).append(
778 '<input type="hidden" id="trait_abbr" value="' + trait.abbr + '"></input>'
785 solGS.getTrainingTraitsIds = function () {
786 var trainingTraitsIds = jQuery("#training_traits_ids").val();
787 var trainingTraitsCode = jQuery("#training_traits_code").val();
788 var traitId = jQuery("#trait_id").val();
790 if (trainingTraitsIds) {
791 trainingTraitsIds = trainingTraitsIds.split(",");
793 } else if (traitId) {
794 trainingTraitsIds = [traitId];
797 return trainingTraitsIds;
800 solGS.getModelArgs = function () {
801 var args = this.getTrainingPopArgs();
802 var trainingTraitsIds = this.getTrainingTraitsIds();
804 if (trainingTraitsIds) {
805 args["training_traits_code"] = jQuery("#training_traits_code").val();
806 args["training_traits_ids"] = trainingTraitsIds;
809 if (trainingTraitsIds.length == 1) {
810 args["trait_id"] = trainingTraitsIds[0];
816 solGS.selectMenuModelArgs = function() {
817 var modelArgs = this.getModelArgs();
820 id: modelArgs.training_pop_id,
821 name: modelArgs.training_pop_name,
822 pop_type: "training",
826 solGS.getSelectionPopArgs = function () {
827 var args = this.getModelArgs();
828 var selPopGenoProtocolId = jQuery("#selection_pop_genotyping_protocol_id").val();
829 var selPopId = jQuery("#selection_pop_id").val();
831 if (!selPopGenoProtocolId) {
832 selPopGenoProtocolId = jQuery("#genotyping_protocol_id").val();
834 if (selPopGenoProtocolId) {
835 args["selection_pop_genotyping_protocol_id"] = selPopGenoProtocolId;
836 args["selection_pop_id"] = selPopId;
842 solGS.getTrainingPopArgs = function () {
844 training_pop_id: jQuery("#training_pop_id").val(),
845 training_pop_name: jQuery("#training_pop_name").val(),
846 genotyping_protocol_id: jQuery("#genotyping_protocol_id").val(),
847 data_set_type: jQuery("#data_set_type").val(),
848 analysis_type: jQuery("#analysis_type").val(),
854 solGS.getPopulationDetails = function () {
855 var trainingPopId = jQuery("#population_id").val();
856 var trainingPopName = jQuery("#population_name").val();
858 if (!trainingPopId) {
859 trainingPopId = jQuery("#training_pop_id").val();
860 trainingPopName = jQuery("#training_pop_name").val();
863 var selectionPopId = jQuery("#selection_pop_id").val();
864 var selectionPopName = jQuery("#selection_pop_name").val();
866 if (!trainingPopId) {
867 trainingPopId = jQuery("#model_id").val();
868 traininPopName = jQuery("#model_name").val();
871 var comboPopsId = jQuery("#combo_pops_id").val();
876 dataSetType = "combined_populations";
877 trainingPopId = comboPopsId;
879 dataSetType = "single_population";
882 var protocolId = jQuery("#genotyping_protocol_id").val();
884 training_pop_id: trainingPopId,
885 population_name: trainingPopName,
886 training_pop_name: trainingPopName,
887 selection_pop_id: selectionPopId,
888 selection_pop_name: selectionPopName,
889 combo_pops_id: comboPopsId,
890 data_set_type: dataSetType,
891 genotyping_protocol_id: protocolId,
895 solGS.showMessage = function (divId, msg) {
896 divId = divId.match(/#/) ? divId : "#" + divId;
898 jQuery(divId).html(msg).show().delay(4000).fadeOut("slow");
901 solGS.checkPageType = function () {
902 var pageType = jQuery.ajax({
905 data: { page: document.URL },
906 url: "/solgs/check/page/type",
913 solGS.blockSolgsSearchInterface = function () {
915 jQuery("#solgs_search_interfaces").hide();
920 //executes two functions alternately
921 jQuery.fn.alternateFunctions = function (a, b) {
922 return this.each(function () {
924 jQuery(this).bind("click", function () {
927 return b.apply(this, arguments);
930 return a.apply(this, arguments);
935 jQuery.fn.doesExist = function () {
936 return jQuery(this).length > 0;
939 jQuery(document).on("keyup", "#user_email", function (e) {
940 jQuery("#user_email").css("border", "solid #96d3ec");
942 jQuery("#form-feedback-user-email").empty();
945 jQuery(document).on("keyup", "#analysis_name", function (e) {
946 jQuery("#analysis_name").css("border", "solid #96d3ec");
948 jQuery("#form-feedback-analysis-name").empty();