Reuters tutorial: step 2

James McKinney edited this page Feb 23, 2015 · 34 revisions

Table of Contents

Let’s display the documents in the Solr response by creating a results widget. We can create a new widget, ResultWidget.js, by inheriting from AbstractWidget, from which every AJAX Solr widget inherits.

(function ($) {
AjaxSolr.ResultWidget = AjaxSolr.AbstractWidget.extend({
});
})(jQuery);

And add the JavaScript files for the widget:

<script src="../../lib/core/AbstractWidget.js"></script>
<script src="widgets/ResultWidget.js"></script>

Before we define any methods on the widget, let’s add an instance of the widget to the Manager in reuters.js:

Manager.addWidget(new AjaxSolr.ResultWidget({
  id: 'result',
  target: '#docs'
}));

Every widget takes a required id, to identify the widget, and an optional target. The target is usually the CSS selector for the HTML element that the widget updates after each Solr request.

Now, we implement the abstract method afterRequest, which each widget runs after the Manager receives the Solr response. The Manager stores the response in Manager.response (which the widgets may access through this.manager.response).

afterRequest: function () {
  $(this.target).empty();
  for (var i = 0, l = this.manager.response.response.docs.length; i < l; i++) {
    var doc = this.manager.response.response.docs[i];
    $(this.target).append(this.template(doc));
  }
},

template: function (doc) {
  var snippet = '';
  if (doc.text.length > 300) {
    snippet += doc.dateline + ' ' + doc.text.substring(0, 300);
    snippet += '<span style="display:none;">' + doc.text.substring(300);
    snippet += '</span> <a href="#" class="more">more</a>';
  }
  else {
    snippet += doc.dateline + ' ' + doc.text;
  }

  var output = '<div><h2>' + doc.title + '</h2>';
  output += '<p id="links_' + doc.id + '" class="links"></p>';
  output += '<p>' + snippet + '</p></div>';
  return output;
}

The afterRequest method empties the target HTML element and appends HTML content to it for each document in the Solr response.

Note: If you are using your own Solr instance, you may need to change the template method to match your own Solr fields: specifically, doc.text, doc.dateline, doc.title and doc.id.

[What we have so far]

We’re now displaying the first ten results for the search term “oil” – nice! Let’s display each document’s tags and implement the “more” link. Add the following code inside the for-loop in afterRequest:

var items = [];
items = items.concat(this.facetLinks('topics', doc.topics));
items = items.concat(this.facetLinks('organizations', doc.organisations));
items = items.concat(this.facetLinks('exchanges', doc.exchanges));

var $links = $('#links_' + doc.id);
$links.empty();
for (var j = 0, m = items.length; j < m; j++) {
  $links.append($('<li></li>').append(items[j]));
}

Note: If you are using your own Solr instance, you may want to change (or remove) the lines adding facet links for topics, organisations and exchanges.

To get the rest of the code to run, we’ll need to define the method facetLinks and its helper facetHandler:

start: 0,

facetLinks: function (facet_field, facet_values) {
  var links = [];
  if (facet_values) {
    for (var i = 0, l = facet_values.length; i < l; i++) {
      links.push(
        $('<a href="#"></a>')
        .text(facet_values[i])
        .click(this.facetHandler(facet_field, facet_values[i]))
      );
    }
  }
  return links;
},

facetHandler: function (facet_field, facet_value) {
  var self = this;
  return function () {
    self.manager.store.remove('fq');
    self.manager.store.addByValue('fq', facet_field + ':' + AjaxSolr.Parameter.escapeValue(facet_value));
    self.doRequest(0);
    return false;
  };
},

The above creates links for browsing by topic, organization, or exchange. Clicking a link will reset the filter queries, add a filter query, and send a Solr request, setting the Solr start parameter to 0. See the ParameterStore remove and addByValue, and the AbstractWidget doRequest API methods.

To implement the “more” link, we implement another abstract method: init. A widget’s init method is called once when the Manager’s init method is called.

init: function () {
  $(document).on('click', 'a.more', function () {
    var $this = $(this),
        span = $this.parent().find('span');

    if (span.is(':visible')) {
      span.hide();
      $this.text('more');
    }
    else {
      span.show();
      $this.text('less');
    }

    return false;
  });
}

We implement a final abstract method, beforeRequest, to display a loading spinner while waiting for Solr to return a response. Here is the code:

beforeRequest: function () {
  $(this.target).html($('<img>').attr('src', 'images/ajax-loader.gif'));
}

[What we have so far]

In this iteration, we wrote a results widget. We described how to define a widget and add it to the manager; introduced two widget properties – id and target – and three abstract methods – init, beforeRequest, and afterRequest – all inherited from AbstractWidget; and used the ParameterStore remove and addByValue API methods.

Let's paginate those results.

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.