CINXE.COM
// jQuery check, if it's not present then include it // jQuery check, if it's not present then include it function bpMinVersion(min, actual) { function parseVersionString (str) { if (typeof(str) != 'string') { return false; } var x = str.split('.'); var maj = parseInt(x[0]) || 0; var min = parseInt(x[1]) || 0; var pat = parseInt(x[2]) || 0; return { major: maj, minor: min, patch: pat } } var minParsed = parseVersionString(min); var actualParsed = parseVersionString(actual); if (actualParsed.major > minParsed.major) { return true; } else if (actualParsed.major == minParsed.major && actualParsed.minor > minParsed.minor) { return true; } else if (actualParsed.major == minParsed.major && actualParsed.minor == minParsed.minor && actualParsed.patch > minParsed.patch) { return true; } return false; } if (typeof jQuery == 'undefined') { var jq, jqMigrate, scriptLoc = document.getElementsByTagName('script')[0].parentElement; jq = document.createElement('script'); jqMigrate = document.createElement('script'); jq.type = jqMigrate.type = "text/javascript"; jq.src = "//code.jquery.com/jquery-1.11.2.min.js"; jqMigrate.src = "//code.jquery.com/jquery-migrate-1.2.1.min.js"; jq.onload = function() { jqMigrate.onload = bpQuickJumpOnLoad; scriptLoc.appendChild(jqMigrate); } scriptLoc.appendChild(jq); } else if (bpMinVersion("1.9", $.fn.jquery)) { var jqMigrate = document.createElement('script'); jqMigrate.type = "text/javascript"; jqMigrate.src = "//code.jquery.com/jquery-migrate-1.2.1.min.js"; jqMigrate.onload = bpQuickJumpOnLoad; document.getElementsByTagName('head')[0].appendChild(jqMigrate); } else { bpQuickJumpOnLoad(); } // *********************************** // Widget-specific code // *********************************** // Set the defaults if they haven't been set yet if (typeof BP_SEARCH_SERVER === 'undefined') { var BP_SEARCH_SERVER = "http://bioportal.bioontology.org"; } if (typeof BP_SITE === 'undefined') { var BP_SITE = "BioPortal"; } if (typeof BP_ORG === 'undefined') { var BP_ORG = "NCBO"; } var BP_ORG_SITE = (BP_ORG == "") ? BP_SITE : BP_ORG + " " + BP_SITE; if (BP_ontology_id == undefined || BP_ontology_id == "all") { var BP_ontology_id = "" } if (BP_search_branch == undefined) { var BP_search_branch = "" } if (typeof BP_include_definitions === 'undefined' || BP_include_definitions !== true) { var BP_include_definitions = false; } function determineHTTPS(url) { return url.replace("http:", ('https:' == document.location.protocol ? 'https:' : 'http:')); } BP_SEARCH_SERVER = determineHTTPS(BP_SEARCH_SERVER); var jumpTo_searchBoxID = "BP_search_box", jumpTo_searchBoxSelector = "#" + jumpTo_searchBoxID, jumpTo_searchBox = null; // Process after document is fully loaded function bpQuickJumpOnLoad() { jQuery(document).ready(function() { // Install any CSS we need (check to make sure it hasn't been loaded) if (jQuery('link[href$="' + BP_SEARCH_SERVER + '/javascripts/JqueryPlugins/autocomplete/jquery.autocomplete.css"]')) { jQuery("head").append("<link>"); css = jQuery("head").children(":last"); css.attr({ rel: "stylesheet", type: "text/css", href: BP_SEARCH_SERVER + "/javascripts/JqueryPlugins/autocomplete/jquery.autocomplete.css" }); } jQuery("#bp_quick_jump").append("Jump To: <input type=\"textbox\" id=\"" + jumpTo_searchBoxID + "\" size=\"30\"> <input type=\"button\" value=\"Go to " + BP_SITE + "\" onclick=\"jumpTo_jump_clicked();\">"); jQuery("#bp_quick_jump").append("<input type='hidden' id='jump_to_concept_id'>"); jQuery("#bp_quick_jump").append("<input type='hidden' id='jump_to_ontology_id'>"); // Grab the specific scripts we need and fires it start event getScript(BP_SEARCH_SERVER + "/javascripts/JqueryPlugins/autocomplete/crossdomain_autocomplete.js").then( function() { jumpTo_setup_functions(); }); }); } function getScript(url){ return new Promise((resolve, reject) => { const script = document.createElement('script') script.src = url script.async = true script.onerror = reject script.onload = script.onreadystatechange = function() { const loadState = this.readyState if (loadState && loadState !== 'loaded' && loadState !== 'complete') return script.onload = script.onreadystatechange = null resolve() } document.head.appendChild(script) }) } function jumpTo_jumpToValue(li) { if (jQuery("#jump_to_concept_id") == null && jQuery("#jump_to_ontology_id") == null) { var search = confirm("Class could not be found or is not browsable in " + BP_SITE + ".\n\nPress OK to go to the " + BP_SITE + " Search page or Cancel to try again"); if (search) { document.location = BP_SEARCH_SERVER + "/search/"; return; } } if (jQuery("#jump_to_concept_id") != null && jQuery("#jump_to_ontology_id") != null) { var sValue = jQuery("#jump_to_concept_id").val(); var ontology_id = jQuery("#jump_to_ontology_id").val(); document.location = BP_SEARCH_SERVER + "/ontologies/" + ontology_id + "/?p=classes&conceptid=" + encodeURIComponent(sValue); return; } } // Formats the Jump To search results function jumpTo_formatItem(row) { var specials = new RegExp("[.*+?|()\\[\\]{}\\\\]", "g"), // .*+?|()[]{}\ keywords = jQuery(jumpTo_searchBoxSelector).val().trim().replace(specials, "\\$&").split(' ').join('|'), regex = new RegExp('(' + keywords + ')', 'gi'); var resultTypeSpan = jQuery("<span>"); resultTypeSpan.attr("style","font-size:9px;color:blue;"); if (typeof row[2] !== "undefined" && row[2] !== "") { resultTypeSpan.text(row[2]); } if (row[0].match(regex) == null) { var contents = row[6].split("\t"); var synonym = contents[0] || ""; synonym = synonym.split(";"); if (synonym !== "") { var matchSynonym = jQuery.grep(synonym, function(e) { return e.match(regex) != null; }); row[0] = row[0] + " (synonyms: " + matchSynonym.join(", ") + ")"; } } // Cleanup obsolete class tag before markup for search keywords. if (row[0].indexOf("[obsolete]") != -1) { row[0] = row[0].replace("[obsolete]", ""); obsolete_prefix = "<span class='obsolete_class' title='obsolete class'>"; obsolete_suffix = "</span>"; } else { obsolete_prefix = ""; obsolete_suffix = ""; } // Markup the search keywords. var resultClass = row[0].replace(regex, "<b><span style='color:#006600;'>$1</span></b>"); // Set wider class name column var resultClassWidth = "350px"; if (BP_include_definitions) { resultClassWidth = "150px"; } else if (BP_ontology_id == "") { resultClassWidth = "300px"; } var resultClassDiv = jQuery("<div>"); resultClassDiv.addClass("result_class"); resultClassDiv.attr("style", "width: " + resultClassWidth); resultClassDiv.html(resultClass); // resultClass contains markup, not just text. var resultDiv = jQuery("<div>"); // row[7] is the ontology_id, only included when searching multiple ontologies var result_ont_version = row[3], result_uri = row[4]; if (BP_ontology_id !== "") { if (BP_include_definitions) { resultDiv.append(definitionDiv(result_ont_version, result_uri)); } resultDiv.append(resultClassDiv); resultDiv.append(resultTypeSpan.attr("style", "overflow: hidden; float: none;")); } else { resultDiv.append(resultClassDiv); if (BP_include_definitions) { resultDiv.append(definitionDiv(result_ont_version, result_uri)); } resultDiv.append(resultTypeSpan); var resultOnt = row[7]; var resultOntDiv = jQuery("<div>"); resultOntDiv.addClass("result_ontology"); resultOntDiv.attr("style", "overflow: hidden;"); resultOntDiv.text(truncateText(resultOnt, 30)); resultDiv.append(resultOntDiv); } return obsolete_prefix + resultDiv.html() + obsolete_suffix; } function definitionDiv(ont, concept) { var definitionAjax = jQuery("<a>"); definitionAjax.addClass("get_definition_via_ajax"); definitionAjax.attr("href", BP_SEARCH_SERVER + "/ajax/json_class?callback=?&ontologyid=" + ont + "&conceptid=" + encodeURIComponent(concept)); var definitionDiv = jQuery("<div>"); definitionDiv.addClass('result_definition'); definitionDiv.text("retreiving definitions..."); definitionDiv.append(definitionAjax); return definitionDiv; } function jumpTo_setup_functions() { var extra_params = { subtreerootconceptid: encodeURIComponent(BP_search_branch) }; var result_width = 350; // Add extra space for definition if (BP_include_definitions) { result_width += 300; } // Add space for ontology name if (BP_ontology_id === "") { result_width += 250; } else { result_width += 100; } jQuery(jumpTo_searchBoxSelector).bioportal_autocomplete(BP_SEARCH_SERVER + "/search/json_search/" + BP_ontology_id, { extraParams: extra_params, lineSeparator: "~!~", matchSubset: 0, minChars: 3, maxItemsToShow: 20, onFindValue: jumpTo_jumpToValue, onItemSelect: jumpTo_jumpToSelect, width: result_width, footer: '<div style="color: grey; font-size: 8pt; font-family: Verdana; padding: .8em .5em .3em;">Results provided by <a style="color: grey;" href="' + BP_SEARCH_SERVER + '">' + BP_ORG_SITE + '</a></div>', formatItem: jumpTo_formatItem }); // Setup polling to get definitions if (BP_include_definitions) { getWidgetAjaxContent(); } } // Poll for potential definitions returned with results function getWidgetAjaxContent() { // Look for anchors with a get_via_ajax class and replace the parent with the resulting ajax call $(".get_definition_via_ajax").each(function() { var def_link = $(this); if (typeof def_link.attr("getting_content") === 'undefined') { def_link.attr("getting_content", true); $.getJSON(def_link.attr("href"), function(data) { var definition = (typeof data.definition === 'undefined') ? "" : data.definition.join(" "); def_link.parent().html(truncateText(decodeURIComponent(definition.replace(/\+/g, " ")))); }); } }); setTimeout(getWidgetAjaxContent, 100); } // Sets a hidden form value that records the concept id when a concept is chosen in the jump to // This is a workaround because the default autocomplete search method cannot distinguish between two // concepts that have the same preferred name but different ids. function jumpTo_jumpToSelect(li) { jQuery("#jump_to_concept_id").val(li.extra[0]); jQuery("#jump_to_ontology_id").val(li.extra[2]); } function jumpTo_jump_clicked() { jQuery("#BP_search_box")[0].autocompleter.findValue(); } function truncateText(text, max_length) { if (typeof max_length === 'undefined' || max_length == "") { max_length = 70; } var more = '...'; var content_length = $.trim(text).length; if (content_length <= max_length) return text; // bail early if not overlong var actual_max_length = max_length - more.length; var truncated_node = jQuery("<div>"); var full_node = jQuery("<div>").html(text).hide(); text = text.replace(/^ /, ''); // node had trailing whitespace. var text_short = text.slice(0, max_length); // Ensure HTML entities are encoded // http://debuggable.com/posts/encode-html-entities-with-jquery:480f4dd6-13cc-4ce9-8071-4710cbdd56cb text_short = $('<div/>').text(text_short).html(); var other_text = text.slice(max_length, text.length); text_short += "<span class='expand_icon'><b>" + more + "</b></span>"; text_short += "<span class='long_text'>" + other_text + "</span>"; return text_short; }