Upgrading a template with a default sessions and history widget

This guide provides the steps required to update a template that includes an un-customized sessions and history widget. If you are using a template that also customizes the sessions and history widget please see: upgrading a template with a customized sessions and history widget.

This guide shows the steps required to upgrade a template for an existing search built prior to Funnelback v15.24 that used the default session search and click history or the session cart tools widgets.

Prior to Funnelback 15.24, the widget was delivered using an angularJS based session library. In 15.24, this was split into two independent widgets; one to handle search and click history and another to handle cart functionality.

This guide focuses on updating the code within existing Funnelback Freemarker templates to make use of the two replacement widgets.

Upgrade process

Replace JavasScript libraries

funnelback-session-1.0.0.js is no longer required and should be removed. Note: In some older versions, the file was named funnelback-session.js without the version number suffix.

The angularJS library was previously used only for the Funnelback session tool, and it also should be removed unless other custom functionality relying on this library has been added to the custom template.

Replace:

<script src="${GlobalResourcesPrefix}thirdparty/angular-1.0.7/angular.js"></script>
<script src="${GlobalResourcesPrefix}thirdparty/angular-1.0.7/angular-resource.js"></script>
<script src="${GlobalResourcesPrefix}js/funnelback-session-1.0.0.js"></script>

with:

<script nomodule type="text/javascript" src="${GlobalResourcesPrefix}thirdparty/es6-promise-4.2.5/es6-promise.auto.min.js"></script>
<script type="text/javascript" src="${GlobalResourcesPrefix}thirdparty/handlebars-4.7/handlebars.min.js"></script>
<script type="text/javascript" src="${GlobalResourcesPrefix}js/funnelback.session-cart-0.1.min.js"></script>
<script type="text/javascript" src="${GlobalResourcesPrefix}js/funnelback.session-history-0.1.min.js"></script>

<script type="text/javascript">
  var flbSessionCart = new Funnelback.SessionCart({collection: '${question.collection.id}'});
  var flbSessionHistory = new Funnelback.SessionHistory({collection: '${question.collection.id}'});
</script>

Update Freemarker templates

  1. From the <style> tag located in the <head> section, remove the following angularJS specific classes:

[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak { display: none !important; }
  1. From the <body> tag, remove the attributes that were previously used to initiate the angularJS library.

Replace:

<body<#if question.collection.configuration.valueAsBoolean("ui.modern.session")> data-ng-app="Funnelback" data-ng-controller="DefaultCtrl"</#if>>

with:

<body>
  1. Update the element used to trigger the display of the cart.

Replace:

<li data-ng-class="{active: isDisplayed('cart')}"><a href="#" data-ng-click="toggleCart()" title="{{cart.length}} item(s) in your selection"><span class="glyphicon glyphicon-shopping-cart"></span> <span class="badge" data-ng-cloak>{{cart.length}}</ng-pluralize --></span></a></li>

with:

<li class="flb-cart-count"></li>
  1. Update the element used to trigger the display of the history box.

Replace:

<li data-ng-class="{active: isDisplayed('history')}"><a href="#"  data-ng-click="toggleHistory()" title="Search History">History</a></li>

with:

<li><a class="session-history-toggle">History</a></li>
  1. Remove the angularJS attribute and instead add an id attribute with search-results-content.

Replace:

<div class="row" data-ng-show="isDisplayed('results')">

with:

<div id="search-results-content" class="row">
  1. Remove angularJS attributes that are no longer used.

Replace:

<div class="breadcrumb" data-ng-controller="SearchHistoryCtrl" data-ng-show="!searchHistoryEmpty">

with:

<div class="breadcrumb session-history-breadcrumb">
  1. Remove angularJS attributes that were used to show the history box and instead add the CSS class session-history-show.

Replace:

<button class="btn btn-link pull-right" data-ng-click="toggleHistory()"><small class="text-muted"><span class="glyphicon glyphicon-plus"></span> More&hellip;</small></button>

with:

<button class="btn btn-link pull-right session-history-show"><small class="text-muted"><span class="glyphicon glyphicon-plus"></span> More&hellip;</small></button>
  1. Remove the code below as the cart widget now handles the display of adding or removing items from the cart.

<#if question.collection.configuration.valueAsBoolean("ui.modern.session")><a href="#" data-ng-click="toggle()" data-cart-link data-css="pushpin|remove" title="{{label}}"><small class="glyphicon glyphicon-{{css}}"></small></a></#if>
  1. Remove the angularJS attribute previously used to show the history box and instead add the CSS class session-history-show. Optionally add the class session-history-link as well so that this link will be hidden if the click history is cleared.

Replace:

<small class="text-warning"><span class="glyphicon glyphicon-time"></span> <a title="Click history" href="#" class="text-warning" data-ng-click="toggleHistory()">Last visited ${prettyTime(session.getClickHistory(s.result.indexUrl).clickDate)}</a></small>

with:

<small class="text-warning session-history-link"><span class="glyphicon glyphicon-time"></span> <a title="Click history" href="#" class="text-warning session-history-show">Last visited ${prettyTime(session.getClickHistory(s.result.indexUrl).clickDate)}</a></small>
  1. Remove the angularJS attributes.

Replace:

<div id="search-history" data-ng-cloak data-ng-show="isDisplayed('history')">

with:

<div id="search-history">
  1. Remove the angularJS attributes previously used to disable the query box when result cart or session history was open. This is no longer necessary to disable.

Replace:

<div class="form-group">
  <input required name="query" id="query" title="Search query" type="text" value="${question.inputParameterMap["query"]!}" accesskey="q" placeholder="Search <@s.cfg>service_name</@s.cfg>&hellip;" class="form-control query" data-ng-disabled="isDisplayed('cart') || isDisplayed('history')">
</div>
<button type="submit" class="btn btn-primary" data-ng-disabled="isDisplayed('cart') || isDisplayed('history')"><span class="glyphicon glyphicon-search"></span> Search</button>

with:

<div class="form-group">
  <input required name="query" id="query" title="Search query" type="text" value="${question.inputParameters["query"]?first!}" accesskey="q" placeholder="Search <@s.cfg>service_name</@s.cfg>&hellip;" class="form-control query">
</div>
<button type="submit" class="btn btn-primary"><span class="glyphicon glyphicon-search"></span> Search</button>
  1. Remove the angularJS attribute previously used to hide the history box and instead add the CSS class session-history-hide.

Replace:

<a href="#" data-ng-click="hideHistory()"><span class="glyphicon glyphicon-arrow-left"></span> Back to results</a>

with:

<a href="#" class="session-history-hide"><span class="glyphicon glyphicon-arrow-left"></span> Back to results</a>
  1. Update the output of the click history data.

Replace:

<div class="col-md-6" data-ng-controller="ClickHistoryCtrl">
  <div data-ng-show="!clickHistoryEmpty && <@fb.HasClickHistory />">
    <h3><span class="glyphicon glyphicon-heart"></span> Recently clicked results
      <button class="btn btn-danger btn-xs" title="Clear click history" data-ng-click="clear('Your history will be cleared')"><span class="glyphicon glyphicon-remove"></span> Clear</button>
    </h3>
    <ul class="list-unstyled">
      <#list session.clickHistory as h>
        <li><a href="${h.indexUrl}">${h.title}</a> &middot; <span class="text-warning">${prettyTime(h.clickDate)}</span><#if h.query??><span class="text-muted"> for &quot;${h.query!}&quot;</#if></span></li>
      </#list>
    </ul>
  </div>
  <div data-ng-show="clickHistoryEmpty || !<@fb.HasClickHistory />">
    <h3><span class="glyphicon glyphicon-heart"></span> Recently clicked results</h3>
    <p class="text-muted">Your click history is empty.</p>
  </div>
</div>

with:

<div class="col-md-6">
  <h3>
    <span class="glyphicon glyphicon-heart"></span> Recently clicked results
    <button class="btn btn-danger btn-xs session-history-clear-click" title="Clear click history"><span class="glyphicon glyphicon-remove"></span> Clear</button>
  </h3>
  <#list session.clickHistory>
    <ul class="session-history-click-results">
    <#items as h>
      <li><a href="${h.indexUrl}">${h.title}</a> &middot; <span class="text-warning">${prettyTime(h.clickDate)}</span><#if h.query??><span class="text-muted"> for &quot;${h.query!}&quot;</#if></span></li>
    </#items>
    </ul>
  </#list>
  <p class="session-history-click-empty text-muted">Your click history is empty.</p>
</div>
  1. Update the output of the search history data.

Replace:

<div class="col-md-6" data-ng-controller="SearchHistoryCtrl">
  <div data-ng-show="!searchHistoryEmpty && <@fb.HasSearchHistory />">
    <h3><span class="glyphicon glyphicon-search"></span> Recent searches
      <button class="btn btn-danger btn-xs" title="Clear search history" data-ng-click="clear('Your history will be cleared')"><span class="glyphicon glyphicon-remove"></span> Clear</button>
    </h3>
    <ul class="list-unstyled">
      <#list session.searchHistory as h>
        <li><a href="?${h.searchParams}">${h.originalQuery!} <small>(${h.totalMatching})</small></a> &middot; <span class="text-warning">${prettyTime(h.searchDate)}</span></li>
      </#list>
    </ul>
  </div>
  <div data-ng-show="searchHistoryEmpty || !<@fb.HasSearchHistory />">
    <h3><span class="glyphicon glyphicon-search"></span> Recent searches</h3>
    <p class="text-muted">Your search history is empty.</p>
  </div>
</div>

with:

<div class="col-md-6">
  <h3>
    <span class="glyphicon glyphicon-search"></span> Recent searches
    <button class="btn btn-danger btn-xs session-history-clear-search" title="Clear search history"><span class="glyphicon glyphicon-remove"></span> Clear</button>
  </h3>
  <#list session.searchHistory>
    <ul class="session-history-search-results list-unstyled">
    <#items as h>
      <li><a href="?${h.searchParams}">${h.originalQuery!} <small>(${h.totalMatching})</small></a> &middot; <span class="text-warning">${prettyTime(h.searchDate)}</span></li>
    </#items>
    </ul>
  </#list>
  <p class="session-history-search-empty text-muted">Your search history is empty.</p>
</div>
  1. Update the output of cart data. The cart data display is now handled by widget using Handlebars templating.

Replace:

<div id="search-cart" data-ng-cloak data-ng-show="isDisplayed('cart')" data-ng-controller="CartCtrl">
  <div class="row">
    <div class="col-md-12">
      <a href="#" data-ng-click="hideCart()"><span class="glyphicon glyphicon-arrow-left"></span> Back to results</a>
      <h2><span class="glyphicon glyphicon-pushpin"></span> Saved
        <button class="btn btn-danger btn-xs" title="Clear selection" data-ng-click="clear('Your selection will be cleared')"><span class="glyphicon glyphicon-remove"></span> Clear</button>
      </h2>

      <ul class="list-unstyled">
        <li data-ng-repeat="item in cart">
          <h4>
            <a title="Remove" data-ng-click="remove(item.indexUrl)" href="javascript:;"><small class="glyphicon glyphicon-remove"></small></a>
            <a href="{{item.indexUrl}}">{{item.title|truncate:70}}</a>
          </h4>

          <cite class="text-success">{{item.indexUrl|cut:'http://'}}</cite>
          <p>{{item.summary|truncate:255}}</p>
        </li>
      </ul>
    </div>
  </div>
</div>

with:

<div id="search-cart"></div>