Adding OTT Embedded Search to your site

OTT Embedded Search allows you to add our Technology Search functionality to your web site without having to write any code.  Paste the code below into your web page where you want the search functionality to appear, reload your page, and it should start working immediately.

Sites currently using Embedded Search

NOTE:
NCI also manages abstracts for NHGRI, NICD, NEI, NIA, CC, NIDA, NIDCD, NCCIH
NHLBI also manages abstracts for NINR, NIAAA, NIBIB, NIDCD, NIEHS, NINR 
NIAID also manages abstracts for CDC

Adding Embedded Search to your site

If you use this code, please register your site with us by emailing us at nihott@nih.gov so we can keep you informed on changes and improvements that may affect any sites running the OTT Embedded Search.

Adding Search Components

<div class="ott-embed">
  <div class="placeholder">Loading available technologies...</div>
</div>
<script type="text/javascript" src="https://www.techtransfer.nih.gov/modules/custom/nih_algolia/js/ott-search.js"></script>
<noscript>Javascript must be enabled for the OTT-Embed Search Form to work.</noscript>
<script>
  // custom callback function definition to integrate with analytics
  function myCallback() {
    console.log("Custom Analytics code definition");
  }
  // customize ottEmbedSettings to suit the needs of your site
  ottEmbedSettings = {
    // selector : '.ott-embed', // class name of this code
    // query : false, // true or empty: show search box, false: hide search box
    jQueryUrl: 'https://code.jquery.com/jquery-latest.min.js', // link to latest jQuery version
    // facets: false, // hide facets
    // facet1: false, // hide facet 1 (Content Type)
    facetType: false, // hide Content Type facet
    // facet2: false, // hide facet 2 (Development Stage)
    // facetDevStage: false, // hide Development Stage facet
    // facet3: false, // hide facet 3 (Disease Area)
    // facetDiseaseArea: false, // hide Disease Area facet
    // facet4: false, // hide facet 4 (Technology)
    // facetTechnology: false, // hide Technology facet
    // facet5: false, // hide facet 5 (Collaboration Sought)
    // facetCollaboration: false, // hide Collaboration Sought facet
    // facet6: false, // hide facet 6 (Center)
    // facetCenter: false, // hide Center facet
    // facet7: false, // hide facet 7 (inventor)
    // facetInventor: false, // hide Inventor facet
    sort: false, // hide sort by dropdown
    // stats: false, // hide number of results
    // pager: false, // hide all pagers (don't disable pager if hitsPerPage is less than the expected number of results)
    // pager_top: false, // hide pager at top
    // pager_bottom: false, // hide pager at bottom
    // results: false, // hide search results
    // filter: 'type:tech', // example filter on Technologies under Type facet
    filter: 'field_ics:NCATS', // Limit to NCATS abstracts
    // filter: '"type:tech" AND "field_ics:NCATS"', // example filter on Technology Bundle type and NCATS center
    // techOnly: true, // if False, we do not automatically add "type:tech" to the filter, allowing all types to be returned
    hitsPerPage: 20, // number of results per page
    // resultsPerPage: true, // Show number of hits per page (5, 10, 20, etc) dropdown
    // exactHighlightSearchResults: true, // true: highlight exact and fuzzy search differently, false or empty: normal highlighting
    // Example html template for each search result. Clicking on a result will bring you to its detail page on 
    // https://techtransfer.nih.gov. You may edit the html or leave empty to use default
    searchResultTemplate: `
      <article class="{{ type }}">
        <p class="content-type">
          Technology <span class="field_id">{{#helpers.snippet}}{ "attribute": "field_id" }{{/helpers.snippet}}</span>
        </p>
        <p class="title">
          <a href="https://techtransfer.nih.gov/{{ url }}">{{#helpers.snippet}}{ "attribute": "title" }{{/helpers.snippet}}</a> 
          <!-- To link to a detail page on your site, set href="https://yoursite.url/?tech={{ field_id }}" -->
          <!-- where tech is the detailParameter. You can find further details on this below -->
        </p>
        <p class="inventors">
          {{#helpers.snippet}}{ "attribute": "field_lead_inventors" }{{/helpers.snippet}}
        </p>
        <p class="desc body">
          {{#helpers.snippet}}{ "attribute": "rendered_item" }{{/helpers.snippet}}
        </p>
      </article>
      `,
    // Example html template for the embedded search form. You may edit the html or leave empty to use default
    searchFormTemplateHtml: `
      <div class="ottEmbedSearch">
        <div class="query-container">
          <div class="query">&nbsp;</div>
          <div class="bookmark save-search" data-category="search">&nbsp;</div>
        </div>
        <div class="search-header-container">
          <div class="sort-by">&nbsp;</div>
          <div class="pagination">&nbsp;</div>
          <div class="stats">&nbsp;</div>
        </div>
        <div class="search-results-container">
          <div class="facets-left-column search-results-container-column">
          <div class="filterLabel toggler"><span>Filter(s)</span><span class="chevron panel-is-expanded"></span></div>
            <div class="facets">
              <div class="facet1wrapper">
                <div class="facet1">&nbsp;</div>
              </div>
              <div class="facet2wrapper">
                <div class="facet2">&nbsp;</div>
              </div>
              <div class="facet3wrapper">
                <div class="facet3">&nbsp;</div>
              </div>
              <div class="facet4wrapper">
                <div class="facet4">&nbsp;</div>
              </div>
              <div class="facet5wrapper">
                <div class="facet5">&nbsp;</div>
              </div>
              <div class="facet6wrapper">
                <div class="facet6">&nbsp;</div>
              </div>
              <div class="facet7wrapper">
                <div class="facet7">&nbsp;</div>
              </div>
            </div>
          </div>
          <div class="hits-right-column search-results-container-column">
            <div class="hits"></div>
            <div class="search-footer-container">
              <div class="sort-by2"></div>
              <div class="pagination2"></div>
              <div class="stats2"></div>
            </div>
          </div>
        </div>
      </div>
      `,
    analyticsSearchCallback: myCallback, // custom analytics code // COMING SOON
  };
  ott_embed(ottEmbedSettings);
</script>
<style>
  .ott-embed .search-results-container .facets-left-column {
    margin-right: 32px;
    width: 33%;
    max-width: 33%;
  }

  .ott-embed .ais-Hits-item .title>a {
    color: #0051a8;
    text-decoration: underline;
    font-weight: normal;
  }
</style>

The analyticsSearchCallback function (coming soon) is used as middleware to integrate Algolia and an analytics tool, such as Google Analytics or Adobe Analytics.

Same-site Detail Pages

The basic Embedded Search will link out to the TechTransfer.nih.gov website for detail pages.   If you would like to keep users on your own site instead of sending them to our site, tweak the SearchResultTemplate parameter and use the code below into your web page where you display the details page for a search result, reload your page, and it should start working immediately.

<div class="ott-embed">
  <div class="placeholder">Loading available technologies...</div>
</div>
<script type="text/javascript" src="https://www.techtransfer.nih.gov/modules/custom/nih_algolia/js/ott-search.js"></script>
<noscript>Javascript must be enabled for the OTT-Embed Search Form to work.</noscript>
<script>
  // customize ottEmbedSettings to suit the needs of your site
  ottEmbedSettings = {
    detailSelector: '.ott-details', // class name of search result details code
    detailParameter: 'tech', // name of parameter used to identify search result record. Make sure that it matches the 
      // parameter used in the a tag of the searchResultTemplate in the above code block.
    // Example html template for the search results' details page. You may edit the html or leave empty to use default
    detailTemplate: '\${record.rendered_item_embed}',
    detailTitleTemplate: '${title} | Technology Details', // template for detail page title
    detailBreadcrumbSelector: '.ott-details-breadcrumb ul', // class name of details breadcrumb code
    detailBreadcrumbTemplate: '
      <ol class="ott-details-breadcrumb">
        <li><a href='/'>Home</a></li>
        <li><a href='/technology'>Technology</a></li>
        <li>\${title}</li>
      </ol>
      ',
  };
  ott_embed(ottEmbedSettings);
</script>
<style>
  .ott-embed .search-results-container .facets-left-column {
    margin-right: 32px;
    width: 33%;
    max-width: 33%;
  }

  .ott-embed .ais-Hits-item .title>a {
    color: #0051a8;
    text-decoration: underline;
    font-weight: normal;
  }
</style>

Rewriting paths

To properly link Related Technologies records, you will need to add a rewrite rule to your site's .htaccess file.  For example, if your detail page is at /my/search/detail?tech=TAB-1234 then you would want to add the following redirect rewrite rule:

RewriteEngine On
RewriteRule ^tech/(.*)$ /my/search/detail?abstract=$1 [R=301,L]
 

Customizing the Search Result Template

You can create a custom search result template by setting the searchResultTemplate parameter to a string (as in the first example, above, or a function.  The function can include dynamic logic controlling the display based on content.   For example, here is a display that displays an optional field_publish_date value, converted from a Unix timestamp to a human-friendly dormat, if the content type is "News" or "Notice".

In the configuration object, set the searchResultTemplate value to point to a function:

 //... rest of settings object
 
 // Use a function as the searchResultTemplate to customize the search results
    searchResultTemplate: hitTemplate, // function accepting 'hit' object, returning template string
    
 //... rest of settings object

and then put any needed logic in your template function and return a template string:

function hitTemplate(hit) {
    // Function to convert Unix timestamp to YYYY-MM-DD format
    function formatDate(unixTimestamp) {
        if (!unixTimestamp) return ''; // Return empty if date is missing
        const date = new Date(unixTimestamp * 1000); // Convert to milliseconds
        return date.toISOString().split('T')[0]; // Extract YYYY-MM-DD
    }

    // Determine if the date should be displayed
    const contentTypesWithDate = ["news", "notices"]; // Define types that should display the date
    const lowerCaseType = hit.type ? hit.type.toLowerCase() : ''; // Ensure case insensitivity
    const displayDate = contentTypesWithDate.includes(lowerCaseType) && hit.field_date_published
        ? formatDate(hit.field_date_published)
        : '';

    // Extract inventors correctly
    const inventors = hit.field_inventor_names && hit.field_inventor_names.length > 0
        ? `<p class="inventors"><span class="inventors">${hit.field_inventor_names.join('; ')}</span></p>`
        : ''; // Display only if present

    return `
      <article class="${hit.type}">
        <div class='bookmark' data-path='${hit.url}' data-title='${hit.title}'></div>
        <p class="content-type">
          ${hit.type}&nbsp;&nbsp;&nbsp;&nbsp;${displayDate ? `${displayDate}` : ''} 
          ${processAlgoliaStringOrArray(hit._snippetResult.field_e_numbers, prefix = '<span class="field_e_numbers"> ', suffix = '</span>', separator = '')}
          <span class="field_id"> ${hit._snippetResult.field_id?.value || ''} </span>
        </p>
        <p class="title"><a href='${hit.url}'>${hit._snippetResult.title?.value || 'Untitled'}</a></p>
        ${inventors} <!-- Only displayed if there are inventors -->
        <p class="desc body">${hit._snippetResult.rendered_item?.value || ''}</p>
      </article>
    `;
};

Testing and Debugging

DEBUG mode will display debugging information in the browser console as the scripts run. Enable DEBUG mode by either calling the ott-search.js script with a "?debug=1" parameter or by setting a cookie called DEBUG with a value of 1 in the browser.

DEVELOP mode allows the testing of an upcoming version of the ott-search.js code. Enable DEVELOP mode by either calling the ott-search.js script with a "?develop=1" parameter or by setting a cookie called DEVELOP with a value of 1 in the browser.

To enable both DEBUG and DEVELOP mode, use ott-search.js?debug=1&develop=1 or set both cookies.

Integration Assistance

For assistance with using this code, contact nihott@nih.gov.