diff --git a/js/search_results.js b/js/search_results.js index 59fbe2c5..26f75e42 100644 --- a/js/search_results.js +++ b/js/search_results.js @@ -1,148 +1,122 @@ // searchResults is an array //console.log(searchResults); - $( document ).ready(function() { - // variable searchTerm is available to use directly here - $('#search').val(searchTerm); - - // store filter for each group - var filters = {category: [], taxon_label: []}; - var pageNum = 1; - - $('.filters').on( 'click', '.search-results-button', function() { - // Show loading indicator - $('#loading-indicator').show(); - - var $this = $(this); - - // Always set pageNum to 1 - pageNum = 1; - - // get group key - var $buttonGroup = $this.parents('.search-results-button-group'); - var filterGroup = $buttonGroup.attr('data-filter-group'); - - if (filterGroup === 'category') { - if ($this.attr('data-filter') === '') { - filters.category = []; - } else { - filters.category = [$this.attr('data-filter')]; - } - } - - if (filterGroup === 'taxon_label') { - if ($this.attr('data-filter') === '') { - filters.taxon_label = []; - } else { - filters.taxon_label = [$this.attr('data-filter')]; - } - } - - // Convert object to JSON string - // E.g. {"category": ["gene"], "taxon_label": ["Danio rerio"]} - // Must use "/" at the beginning of the URL - var url = '/searchfiltering/' + searchTerm + '/' + JSON.stringify(filters) + '/' + pageNum; - //console.log(url); - - // fire the new search call and update table - // Separate the ajax request with callbacks - var jqxhr = $.ajax({ - url: url, - method: 'GET', - async : true, - dataType : 'json' - }); - - jqxhr.done(function(data) { - //console.log(data); - - // Hide the loading indicator - $('#loading-indicator').hide(); - - if (typeof(data) !== 'undefined') { - // update the table with this new table content - $('.search-results-rows').html(data.table); - // Update the total count number - $('#totalCount').html(data.count); - - if (data.loadMoreBtn === false) { - // Hide the load mroe button - $('#more').hide(); + var vueapp = new Vue({ + delimiters: ['{[{', '}]}'], // ugly, but otherwise it'll clash with puptent template mechanism + el: '#vue-app', + data: { + facets: [], + user_facets: {}, + results: [], + highlight: {}, + suggestions: {}, + page: 0, + numFound: 0, + numRowsDisplayed: 0 + }, + methods: { + fetchResults: function () { + //console.log("=== FETCH " + this.page + " " + JSON.stringify(this.user_facets)); + var anchor = this; + axios.get('/searchapi/'+searchTerm, {params: this.user_facets}) + .then(function (response) { + anchor.numFound = response.data.response.numFound; + anchor.numRowsDisplayed = response.data.response.docs.length; + anchor.results = response.data.response.docs; + anchor.highlight = {}; + if(anchor.numFound == 0) { + anchor.fetchSuggestions(); + } + // Take the first highilited field and massage it in a more convenient data structure + Object.keys(response.data.highlighting).forEach(function(key) { + var firstKey = Object.keys(response.data.highlighting[key])[0]; + anchor.highlight[key] = response.data.highlighting[key][firstKey][0]; + }); + var facets_fields = response.data.facet_counts.facet_fields; + if(anchor.facets.length == 0) { // for initial visit of the search page + Object.keys(facets_fields).forEach(function(key) { + var json = {}; + json[key] = facets_fields[key]; + anchor.facets.push(json); + }); + } else { // user used facets, just update the numbers + anchor.facets.forEach(function(facet) { + var key = Object.keys(facet)[0]; + var filters = facet[key]; + + // make an inventory of newly fetched facets + var newFacets = {}; + facets_fields[key].forEach(function(facets_field) { + newFacets[facets_field[0]] = facets_field[1]; + }); + + // Update the existing filters, with new number if exists, or 0 + filters.forEach(function(filter) { + if(newFacets.hasOwnProperty(filter[0])) { + filter[1] = newFacets[filter[0]]; + } else { + filter[1] = 0; + } + }); + + }); + } + }) + .catch(function (error) { + console.log(error); + }); + }, + fetchMore: function() { + this.page += 1; + var anchor = this; + //console.log("=== FETCH MORE " + this.page + " " + JSON.stringify(this.user_facets)); + var params = jQuery.extend(true, {}, this.user_facetst); // deep copy + params['p'] = this.page; + axios.get('/searchapi/'+searchTerm, {params: params}) + .then(function (response) { + anchor.numRowsDisplayed += response.data.response.docs.length; + anchor.results = anchor.results.concat(response.data.response.docs); + Object.keys(response.data.highlighting).forEach(function(key) { + var firstKey = Object.keys(response.data.highlighting[key])[0]; + anchor.highlight[key] = response.data.highlighting[key][firstKey][0]; + }); + }) + .catch(function (error) { + console.log(error); + }); + }, + updateFacets: function(event, category, item) { + if(item == "all") { + delete this.user_facets[category]; } else { - $('#more').show(); + this.user_facets[category] = item; } - - // Scroll to top - $(window).scrollTop(0); + this.page = 0; + this.fetchResults(); + }, + beautifyFacetTitle: function(title) { + // taxon_label => Taxon + // category => Category + var cleanTitle = title.split('_')[0]; + return cleanTitle.charAt(0).toUpperCase() + cleanTitle.slice(1); + }, + fetchSuggestions: function() { + //console.log("=== FETCH SUGGESTIONS"); + var anchor = this; + axios.get('/suggestapi/'+searchTerm) + .then(function (response) { + anchor.suggestions = response.data; + }) + .catch(function (error) { + console.log(error); + }); } - }); - - jqxhr.fail(function () { - console.log('Ajax error!') - }); - - }); - - - // Load more content - $('#more').click(function(){ - // Show loading spinner - $('#more-spinner').show(); - - // Increase the page number - pageNum++; - //console.log(pageNum); - - // Convert object to JSON string - // E.g. {"category": ["gene"], "taxon_label": ["Danio rerio"]} - // Must use "/" at the beginning of the URL - var url = '/searchfiltering/' + searchTerm + '/' + JSON.stringify(filters) + '/' + pageNum; - - // fire the new search call and update table - // Separate the ajax request with callbacks - var jqxhr = $.ajax({ - url: url, - method: 'GET', - async : true, - dataType : 'json' - }); - - jqxhr.done(function(data) { - //console.log(data); - - // Hide more spinner - $('#more-spinner').hide(); - - if (typeof(data) !== 'undefined') { - // append new table content - $('.search-results-rows').append(data.table); - } - - if (data.loadMoreBtn === false) { - // Hide the load mroe button - $('#more').hide(); - } else { - $('#more').show(); - } - }); - - jqxhr.fail(function () { - console.log('Ajax error to fetch more results!') - }); - }); - + } + }) - // change is-checked class on buttons - $('.search-results-button-group').each(function(i, buttonGroup) { - var $buttonGroup = $( buttonGroup ); - $buttonGroup.on('click', 'li', function() { - // Highlight selected button - $buttonGroup.find('.is-checked').removeClass('is-checked'); - $(this).addClass('is-checked'); - }); - }); + // initial call + vueapp.fetchResults(); }); - diff --git a/lib/monarch/api.js b/lib/monarch/api.js index c7ec3124..c86a8695 100644 --- a/lib/monarch/api.js +++ b/lib/monarch/api.js @@ -1445,11 +1445,11 @@ bbop.monarch.Engine.prototype.getCategories = function(id) { bbop.monarch.Engine.prototype.resolveIdToType = function(id) { var engine = this; var type = false; //Return false if no type is found - + if (id.indexOf(":") === -1) { id = ':' + id; } - + var nodeByID = engine.getGraphNodeByID(id, engine.config.scigraph_data_url); var graph = new bbop.model.graph(); graph.load_json(nodeByID); @@ -2730,7 +2730,7 @@ bbop.monarch.Engine.prototype.annotateText = function(txt, opts) { r.token.taxon = ''; } }); - + // Fetch taxon var id_list = results.filter(function(i) { return (i.token.categories.indexOf('gene') > -1); }) .map( function(i) { return (i.token.id); }); @@ -2825,7 +2825,7 @@ bbop.monarch.Engine.prototype.golrHackForSearch = function(golrManager) { * facets: wanted facets, as array * rows: number of docs to return * start: offset of starting row - * + * * Returns: JSON structure */ bbop.monarch.Engine.prototype.search = function(term, filters, facets, rows, start) { @@ -2894,12 +2894,12 @@ bbop.monarch.Engine.prototype.search = function(term, filters, facets, rows, sta * Arguments: term : search term * category: term category * limit: number of results to return - * + * * Returns: JSON structure */ bbop.monarch.Engine.prototype.autocomplete = function(term, category, limit) { var engine = this; - + // TODO return only fields of interest var searchGolrManager = engine.initializeGolrManager("monarch_search", this.config.search_url); @@ -2907,7 +2907,7 @@ bbop.monarch.Engine.prototype.search = function(term, filters, facets, rows, sta searchGolrManager.set_query(term); - // TODO DELETE THIS WHEN #XXX is done + // TODO DELETE THIS WHEN #1387 is done engine.golrHackForSearch(searchGolrManager); // END OF DELETE @@ -4107,7 +4107,7 @@ bbop.monarch.Engine.prototype.querySciGraphDynamicServices = function(path,param * * Below are a number of functions, partially tested, that are developed * to work with scigraph and solr/golr services. Unit tests in apitests.js - * + * */ bbop.monarch.Engine.prototype.initializeGolrManager = function(personality, golrServer) { var golr_response = require('bbop-response-golr'); @@ -4167,10 +4167,10 @@ bbop.monarch.Engine.prototype.fetchAssociations = function(filters, limit, perso } golrManager.lite(true); //only return fields in results in the conf file - + golrManager.set_results_count(limit); golrManager.set_facet_limit(-1); //unlimited - + // Add AND filters if (filters != null && filters instanceof Array && filters.length > 0){ filters.forEach( function (val) { @@ -4181,7 +4181,7 @@ bbop.monarch.Engine.prototype.fetchAssociations = function(filters, limit, perso } }); } - + // Add OR filters if (orFilter != null && orFilter instanceof Array && orFilter.length > 0){ var orFilters = orFilter.map( function (val) { @@ -4190,9 +4190,9 @@ bbop.monarch.Engine.prototype.fetchAssociations = function(filters, limit, perso var orFilterString = orFilters.join(" OR "); golrManager.add_query_filter_as_string(orFilterString); } - + //Add OR filters - + if (logFetchTimes) { var timeDelta = Date.now(); this.log("FETCHING: " + "GET" + " " + golrManager.get_state_url()); @@ -4207,7 +4207,7 @@ bbop.monarch.Engine.prototype.fetchAssociations = function(filters, limit, perso // TODO remove this bbop.monarch.Engine.prototype.fetchSolrDocuments = function (query, filters, personality, limit) { var engine = this; - + var golrManager = engine.initializeGolrManager(personality); golrManager.set_query(query); @@ -4221,12 +4221,12 @@ bbop.monarch.Engine.prototype.fetchSolrDocuments = function (query, filters, per if (typeof limit !== 'undefined'){ golrManager.set_results_count(limit); } - + if (logFetchTimes) { var timeDelta = Date.now(); this.log("FETCHING: " + "GET" + " " + golrManager.get_state_url()); } - + return golrManager.search(); }; diff --git a/lib/monarch/web/webapp.js b/lib/monarch/web/webapp.js index 2db21dbb..576b872f 100644 --- a/lib/monarch/web/webapp.js +++ b/lib/monarch/web/webapp.js @@ -718,7 +718,7 @@ function addPhenogridView(info, view) { var suffix = bbop.core.uuid().replace(replacer, ''); var viewID = "view" + suffix; - + info.pup_tent_js_variables.push({name: viewID, value: view}); info.monarch_launchable.push( 'loadPhenogrid(global_phenogrid_conf, ' + viewID + ')'); @@ -730,7 +730,7 @@ function addPhenogridViewToAnalyze(info, view) { var suffix = bbop.core.uuid().replace(replacer, ''); var viewID = "view" + suffix; - + info.pup_tent_js_variables.push({name: viewID, value: view}); info.monarch_launchable.push( 'AnalyzeInit(global_phenogrid_conf, ' + viewID + ')'); @@ -1074,132 +1074,71 @@ web.wrapRouteGet(app, '/node_modules/phenogrid/:filename', '/node_modules/phenog ); -// Method: search +// Method: search API // -// searches over ontology terms via SciGraph +// searches over Solr // // Path: -// - /search/:term +// - /search/:term?p=3&category='gene'&taxon_label='Homo sapiens' // // Formats: -// - html // - json // // // Returns: -// All classes with :term as a substring - -function searchFilteringHandler(request, term, filters, pageNum) { - console.log('searchHandler: term: ', term); - console.log('searchHandler: filters: ', filters); - console.log('searchHandler: pageNum: ', pageNum); - - try { - // Only display 30 results per page start from row 1, index 0 - // This can be used for paging - var resultsCountPerPage = 25; - //var results = engine.autocomplete(term, null, resultsCount); - - // Only faceting with category and taxon_label - Zhou - // Remember to convert JSON string to JSON object - var golrResults = engine.search(term, JSON.parse(filters), ["category", "taxon_label"], resultsCountPerPage, (pageNum - 1)*resultsCountPerPage); - - // Default to 0 - var count = 0; - - var resultsOutput = ''; - - // Default to true to show the load more button - var loadMoreBtn = true; - - // Handle the golr JSON using bbop-response-golr - var bgr = new bbop_response_golr(golrResults); - - // object with rendering functions - if (bgr.documents().length > 0) { - count = bgr.total_documents(); - - // Decide whether to show the load more button - loadMoreBtn = true; - if (resultsCountPerPage*pageNum >= count) { - loadMoreBtn = false; - } - - // Display rows of results that are showing - var startRow = (pageNum - 1)*resultsCountPerPage + 1; - var endRow = (pageNum - 1)*resultsCountPerPage + resultsCountPerPage; - if (endRow > count) { - endRow = count; - } - // Create the new output format - Zhou - resultsOutput = '' - + '' - + '' - + ''; - - // This is an array - //var highlighted_docs = bgr.highlighted_documents(); - // use documents() as tmp hack - according to Jeremy - var highlighted_docs = bgr.documents(); - //console.log(highlighted_docs); - - for (var i = 0; i < highlighted_docs.length; i++) { - // Temp workaround since some results don't have taxon info - Zhou - var taxonText; - - if (typeof(highlighted_docs[i].taxon_label) !== 'undefined') { - taxonText = highlighted_docs[i].taxon_label; - } else { - taxonText = ''; - } - - // Use the first highlighted string since no better/simplier approach - // after discussion with Jeremy and Seth- Zhou - var matchingStr = ''; - if (typeof(highlighted_docs[i].synonym) !== 'undefined') { - matchingStr = highlighted_docs[i].synonym[0]; - } else if (typeof(highlighted_docs[i].definition) !== 'undefined') { - matchingStr = highlighted_docs[i].definition[0]; - } else { - // Just use the label if highlighted? - matchingStr = highlighted_docs[i].label; - } +// Highlited matches with facets and paging +web.wrapRouteGet(app, '/searchapi/:term', '/searchapi/{term}', ['term'], searchApiHandler, errorResponse); +function searchApiHandler(request, term) { + var params = request.query; + + var rowsPerPage = 25; + var page = 0; + if(params.hasOwnProperty('p')) { + page = params['p']; + // remove page from params + delete params['p']; + } + var start = page * rowsPerPage; + + // ensure that values are arrays + Object.keys(params).forEach(function(key) { + if (params[key].constructor !== Array) { + params[key] = [params[key]]; + } + }); + return formattedResults(engine.search(term, request.query, ["category", "taxon_label"], rowsPerPage, start), 'json'); +} - // Convert all category elements to lowercase since genObjectHref() doesn't render "Phenotype" - // correctly in the URL - Zhou - var categoryArr = highlighted_docs[i].category.map(function(val) { - return val.toLowerCase(); - }); +// Method: suggest API +// +// suggest over SciGraph data graph +// +// Path: +// - /suggest/:term +// +// Formats: +// - json +// +// +// Returns: +// suggestions for the input +// +// TODO Use SOLR instead of SciGraph, it makes more sense since the search results come from SOLR. +web.wrapRouteGet(app, '/suggestapi/:term', '/suggestapi/{term}', ['term'], suggestApiHandler, errorResponse); +function suggestApiHandler(request, term) { + var suggestionArray = []; - // Only use label_searchable for now - Zhou - resultsOutput += '' - + '' - + '' - + '' - + '' - + ''; - } + // Show users some suggestions if possible + var suggestions = engine.getSciGraphSuggestions(term, 5); - resultsOutput += '
showing ' + startRow + ' - ' + endRow + ' of ' + count + ' results for "' + term + '"
TermCategoryTaxonMatching String
' + genObjectHref(categoryArr, highlighted_docs[i]) +'' + categoryArr.join(',') + '' + taxonText + '' + matchingStr + '
'; - } else { - resultsOutput = 'No results found.'; - count = 0; - loadMoreBtn = false; - } + suggestions.forEach( function (suggestion) { + var encodedSuggestion = encodeURI(suggestion); + suggestionArray.push([suggestion, encodedSuggestion]); + }); - var obj = new Object(); - obj.count = count; - obj.table = resultsOutput; - obj.loadMoreBtn = loadMoreBtn; - - return formattedResults(obj, 'json');; - } - catch(err) { - return errorResponseWithObject(err); - } + return formattedResults(suggestionArray, 'json'); } -web.wrapRouteGet(app, '/searchfiltering/:term/:filters/:pageNum', '/searchfiltering/{term}/{filters}/{pageNum}', ['term', 'filters', 'pageNum'], searchFilteringHandler, errorResponse); // Method: search @@ -1211,7 +1150,6 @@ web.wrapRouteGet(app, '/searchfiltering/:term/:filters/:pageNum', '/searchfilter // // Formats: // - html -// - json // // // Returns: @@ -1221,16 +1159,6 @@ function searchHandler(request, term) { console.log('searchHandler: term: ', term); try { - // if (/^\s*\S+:\S+\s*$/.test(term)) { - // var url; - // engine.log("Redirecting " + term); - // var resultObj = engine.getVocabularyTermByID(term); - // //Taking the first result - // var type = engine.resolveIdToType(term); - // url = genURL(type,term); - // return web.wrapRedirect(url); - // } - // check if a format is specified var match = /^.+(.json|.jsonp|.text|.rdf|.nt)$/i.exec(term); var fmt = null; @@ -1239,178 +1167,10 @@ function searchHandler(request, term) { term = term.replace(match[1], ""); } - // TODO delete that? - // temporary fix: need to properly figure out when to encode/decode - // See: https://github.com/monarch-initiative/monarch-app/issues/287 - //term = term.replace(/'/g, "'"); - - // Only display 30 results per page start from row 1, index 0 - // This can be used for paging - var resultsCountPerPage = 25; - - // Only faceting with category and taxon_label - Zhou - var golrResults = engine.search(term, {}, ["category", "taxon_label"], resultsCountPerPage, 0); - var info = newInfo(); - info.results = golrResults; - - if (fmt != null) { - // Comment out these lines in order to see the highlighted results for debugging - Zhou - // var bgr = new bbop_response_golr(golrResults); - // var t = bgr.highlighted_documents(); - // console.log(t); - - // return formattedResults(t, fmt); - - return formattedResults(info, fmt); - } - - info.term = term; - - // Default 0 - info.count = 0; - - // HTML addCoreRenderers(info, 'search', term); - // Handle the golr JSON using bbop-response-golr - var bgr = new bbop_response_golr(golrResults); - - // adorn object with rendering functions - if (bgr.documents().length > 0) { - info.hasResults = true; - - // The total number of matching results found - info.count = bgr.total_documents(); - - // Decide whether to show the load more button - info.loadMoreBtn = true; - if (resultsCountPerPage >= info.count) { - info.loadMoreBtn = false; - } - - // Combination filters - - // No sorting, just use the default order - var categories = info.results.facet_counts.facet_fields.category; - - // Sorting: human, mouse, zebrafish, fly, worm, and then everything else by data richness - var taxa = info.results.facet_counts.facet_fields.taxon_label; - - // Category filter - info.resultsCategoryFilter = ''; - - // Species filter - // Sorting: human, mouse, zebrafish, fly, worm, and then everything else by data richness - var dummyTaxa = [ - "Homo sapiens", - "Mus musculus", - "Danio rerio", - "Drosophila melanogaster", - "Caenorhabditis elegans" - ]; - - // If possible that some results don't have taxon specified - // we are not handling that since it's a data issue - Zhou - info.resultsSpeciesFilter = ''; - - // Create the new output format - Zhou - info.resultsOutput = '' - + '' - + '' - + ''; - - // This is an array - //var highlighted_docs = bgr.highlighted_documents(); - // use documents() as tmp hack - according to Jeremy - var highlighted_docs = bgr.documents(); - - for (var i = 0; i < highlighted_docs.length; i++) { - // Temp workaround since some results don't have taxon info - Zhou - var taxonText; - - // Temp workaround since some results don't have taxon info - Zhou - if (typeof(highlighted_docs[i].taxon_label) !== 'undefined') { - taxonText = highlighted_docs[i].taxon_label; - } else { - taxonText = ''; - } - - // Use the first highlighted string since no better/simplier approach - // after discussion with Jeremy and Seth- Zhou - var matchingStr = ''; - if (typeof(highlighted_docs[i].synonym) !== 'undefined') { - matchingStr = highlighted_docs[i].synonym[0]; - } else if (typeof(highlighted_docs[i].definition) !== 'undefined') { - matchingStr = highlighted_docs[i].definition[0]; - } else { - // Just use the label if highlighted? - matchingStr = highlighted_docs[i].label; - } - - // Convert all category elements to lowercase since genObjectHref() doesn't render "Phenotype" - // correctly in the URL - Zhou - var categoryArr = highlighted_docs[i].category.map(function(val) { - return val.toLowerCase(); - }); - - // Only use label_searchable for now - Zhou - info.resultsOutput += '' - + '' - + '' - + '' - + '' - + ''; - } - - info.resultsOutput += '
showing 1 - ' + resultsCountPerPage + ' of ' + info.count + ' results for "' + term + '"
TermCategoryTaxonMatching String
' + genObjectHref(categoryArr, highlighted_docs[i]) +'' + categoryArr.join(',') + '' + taxonText + '' + matchingStr + '
'; - } else { - info.hasResults = false; - - // Show users some suggestions if possible - var suggestions = engine.getSciGraphSuggestions(term, 5); - - var suggestionOutput = ''; - suggestions.forEach( function (suggestion) { - var encodedSuggestion = encodeURI(suggestion); - var href = "" + suggestion + ""; - suggestionOutput += href + "
"; - }); - - if (info.suggestSpan !== '') { - info.suggestSpan = "

No results found, did you mean:

" + suggestionOutput; - } else { - info.suggestSpan = "

No results found

"; - } - } + info.term = term; // jquery info.pup_tent_js_libraries.push("/jquery.min.js"); @@ -1418,9 +1178,6 @@ function searchHandler(request, term) { // Add search result js file - Zhou info.pup_tent_js_libraries.push("/search_results.js"); - // Make variable info available in search_results.js - info.pup_tent_js_variables.push({name:'searchResults', value: info.results}); - info.pup_tent_js_variables.push({name:'searchTerm', value: term}); // Add css @@ -1441,7 +1198,6 @@ function searchHandler(request, term) { web.wrapRouteGet(app, '/search/:term', '/search/{term}', ['term'], searchHandler, errorResponse); - //list all of the sources supplying data to monarch. function sourcesHandler(request, fmt) { try { @@ -2128,7 +1884,7 @@ function caseByIdHandler(request, id, fmt) { // Rendering. var info = newInfo(); info = engine.fetchDataInfo(id); - + if (fmt != null) { return formattedResults(info, fmt,request); @@ -2145,7 +1901,7 @@ function caseByIdHandler(request, id, fmt) { addGolrStaticFiles(info); info.hasPhenotypes = true; - + var phenotype_filter = [ { field: 'object_category', value: 'phenotype' }, { field: 'subject_category', value: 'case' }, @@ -2171,18 +1927,18 @@ function caseByIdHandler(request, id, fmt) { addNonEmptyAnchors(info, true); info.title = 'Monarch Case: '+info.label+' ('+ info.id+')'; - + // Link to disclaimer info.hasDisclaimer = true; info.hasDownloads = true; - + downloadList = [ { 'button_class': 'btn-warning', 'href': '/phenopacket?q=*:*&fq=subject_closure:"' + id + '"&personality=case', 'icon': '/image/phenopackets_logo.png', 'text': "PhenoPacket" - }, + }, { 'button_class': 'btn-success', 'href': '/downloads/' + id + '/association/phenotype.tsv', @@ -2196,14 +1952,14 @@ function caseByIdHandler(request, id, fmt) { 'text': "Variants" } ]; - + info.includes.downloads = downloadList.map(function (val) { return expandTemplate('button', val); }).join(' '); - + if (/^MONARCH:c\d+$/.test(id)) { info.hasSource = true; - info.source = + info.source = 'Undiagnosed ' + 'Diseases Program'; @@ -2213,12 +1969,12 @@ function caseByIdHandler(request, id, fmt) { info.includes.phenogrid_anchor = expandTemplate('phenogrid-anchor', info); info.pup_tent_js_libraries.push("/phenogridloader-onclick.js"); - + //Launch function for annotation score info.pup_tent_js_variables.push({name:'globalID',value:id}); info.monarch_launchable.push('getAnnotationScore(globalID)'); - + info.node_label = 'Case'; info.node_logo = '/image/carousel-diseases.png'; var output = pup_tent.render('node.mustache', info, 'monarch_base.mustache'); @@ -2233,7 +1989,7 @@ web.wrapRouteGet(app, '/case/:id.:fmt?', '/case/{id}.{fmt}', ['id', 'fmt'], case web.wrapRouteGet(app, '/case/:id', '/case/{id}', ['id'], caseByIdHandler, errorResponse); function clusterPageHandler(request) { - + try { var info = newInfo(); addCoreRenderers(info); @@ -2842,7 +2598,7 @@ function phenoPacketHandler(request) { } var personality = request.query.personality; - + if (filters.constructor !== Array) { filters = [request.query.fq] } @@ -3588,11 +3344,11 @@ function addGolrTable(info, query_field, div, filter, personality, anchor, is_st var is_static_var = "is_leaf_" + suffix; var or_filt_var = "or_filter_" + suffix; var launch = ''; - + if (typeof(is_static_id) === 'undefined') { is_static_id = info.isLeafNode; } - + info.pup_tent_js_variables.push({name: field_var, value: query_field}); info.pup_tent_js_variables.push({name: div_var, value: div}); info.pup_tent_js_variables.push({name: person_var, value: personality}); @@ -3964,7 +3720,7 @@ web.wrapRouteGet(app, '/disease/:id/:section', '/disease/{id}/{section}', ['id', function fetchFeatureSection(request, id, section, fmt) { - + var info = engine.fetchSectionInfo(id, section); var sectionInfo = @@ -4068,7 +3824,7 @@ function geneByIdHandler(request, id, fmt) { 'gene_phenotype','#ortholog-phenotypes', false); info.orthoPhenoNum = engine.fetchAssociationCount(ortho_phenotype_filter, 'object'); - + var interaction_filter = [ { field: 'subject_category', value: 'gene' }, { field: 'object_category', value: 'gene' }, @@ -4085,7 +3841,7 @@ function geneByIdHandler(request, id, fmt) { // Phenogrid addPhenogridFiles(info); - + // hack to inhibit species filters which isn't working on Gene page for some reason. addNonEmptyAnchors(info, true); @@ -5146,9 +4902,9 @@ web.wrapRouteGet(app, '/favicon.ico', '/favicon.ico', [], faviconHandler, errorR function resolveByIdHandler(request, id, fmt) { var result; - + id = engine.convertIdToCurie(id); - + if (id.indexOf(':') === -1) { id = ':' + id; } diff --git a/templates/search_results.mustache b/templates/search_results.mustache index 3d3b07b7..4a083cd8 100644 --- a/templates/search_results.mustache +++ b/templates/search_results.mustache @@ -1,5 +1,5 @@ {{{includes.navbar}}} -
+
@@ -7,7 +7,7 @@
-

"{{term}}" we found {{count}} matches

+

{{term}} has {[{numFound}]} matches

@@ -18,20 +18,20 @@
- {{#hasResults}} -
+
-
-
-

Category

- {{{resultsCategoryFilter}}} -
- -
-

Taxon

- {{{resultsSpeciesFilter}}} +
+

{[{beautifyFacetTitle(Object.keys(facet)[0])}]}

+
    +
  • + Select all +
  • +
  • + {[{filter[0]}]} ({[{filter[1]}]}) +
  • +
@@ -39,17 +39,25 @@
-
- {{{resultsOutput}}} -
+ + + + + + + + + + +
TermCategoryTaxonMatching String
{[{result.category.join(',')}]}{[{result.taxon_label}]}
- {{#loadMoreBtn}} +
-
+
- +
@@ -59,16 +67,23 @@
- {{/loadMoreBtn}} +
+
+
+

No results found.

+
+ Did you mean:
+ + {[{suggestion[0]}]}
+
- {{/hasResults}} - {{^hasResults}} - {{{suggestSpan}}} - {{/hasResults}} +
- {{{includes.footer}}} \ No newline at end of file + + + {{{includes.footer}}}