-
Notifications
You must be signed in to change notification settings - Fork 211
Reuters tutorial: step 2
- Reuters tutorial
- Step 1: Talk to Solr
- Step 2: Add a results widget
- Step 3: Add a pager widget
- Step 4: Add a tagcloud widget
- Step 5: Display the current filters
- Step 6: Add a free-text widget
- Step 7: Add an autocomplete widget
- Step 8: Add a map widget
- Step 9: Add a calendar widget
- Step 10: Extra credit
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.
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')); }
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.