0e7f7ab051
This is an interface for quick and efficient browsing through records. It presents a page at /cgi-bin/koha/opac-browse.pl that allows you to enter the prefix of an author, title, or subject and it'll give you a list of the options that match that. You can then scroll through these and select the one you're after. Selecting it provides a list of records that match that particular search. To Test: 1 - Apply patches 2 - Update database (updatedatabase on kohadevbox) 3 - Compile the CSS https://wiki.koha-community.org/wiki/Working_with_SCSS_in_the_OPAC_and_staff_client yarn build --view=opac on kohadevbox 4 - Enable the new syspref OpacBrowseSearch 5 - Have ES running and some records in it SearchEngine syspref set to Elasticsearch 6 - Browse to opac home, click 'Browse search' link for your site) 7 - Test searching for author, title, and subject 8 - Verify that results are returned in expected order 9 - Experiment with fuzziness https://www.elastic.co/guide/en/elasticsearch/reference/5.6/common-options.html#fuzziness Options are: exact (0 edits), fuzzy (1 edit), very fuzzy (2 edits) 10 - Click any result and verify specific titles are correct 11 - Click through title to record and verify it is the correct record 12 - Test that disabling pref removes the link on the opac home Signed-off-by: David Nind <david@davidnind.com> Signed-off-by: Katrin Fischer <katrin.fischer.83@web.de> Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>
172 lines
6.7 KiB
JavaScript
172 lines
6.7 KiB
JavaScript
jQuery.fn.overflowScrollReset = function() {
|
|
$(this).scrollTop($(this).scrollTop() - $(this).offset().top);
|
|
return this;
|
|
};
|
|
|
|
$(document).ready(function(){
|
|
var xhrGetSuggestions, xhrGetResults;
|
|
|
|
$('#browse-search form').submit(function(event) {
|
|
// if there is an in progress request, abort it so we
|
|
// don't end up with a race condition
|
|
if(xhrGetSuggestions && xhrGetSuggestions.readyState != 4){
|
|
xhrGetSuggestions.abort();
|
|
}
|
|
|
|
var userInput = $('#browse-searchterm').val().trim();
|
|
var userField = $('#browse-searchfield').val();
|
|
var userFuzziness = $('input[name=browse-searchfuzziness]:checked', '#browse-searchfuzziness').val();
|
|
var leftPaneResults = $('#browse-searchresults li').not('.loading, .no-results');
|
|
var rightPaneResults = $('#browse-selectionsearch ol li');
|
|
|
|
event.preventDefault();
|
|
|
|
if(!userInput) {
|
|
return;
|
|
}
|
|
|
|
// remove any error states and show the results area (except right pane)
|
|
$('#browse-suggestionserror').addClass('hidden');
|
|
$('#browse-searchresults .no-results').addClass('hidden');
|
|
$('#browse-resultswrapper').removeClass('hidden');
|
|
$('#browse-selection').addClass('hidden').text("");
|
|
$('#browse-selectionsearch').addClass('hidden');
|
|
|
|
// clear any results from left and right panes
|
|
leftPaneResults.remove();
|
|
rightPaneResults.remove();
|
|
|
|
// show the spinner in the left pane
|
|
$('#browse-searchresults .loading').removeClass('hidden');
|
|
|
|
xhrGetSuggestions = $.get(window.location.pathname, {api: "GetSuggestions", field: userField, prefix: userInput, fuzziness: userFuzziness})
|
|
.always(function() {
|
|
// hide spinner
|
|
$('#browse-searchresults .loading').addClass('hidden');
|
|
})
|
|
.done(function(data) {
|
|
var fragment = document.createDocumentFragment();
|
|
|
|
if (data.length === 0) {
|
|
$('#browse-searchresults .no-results').removeClass('hidden');
|
|
|
|
return;
|
|
}
|
|
|
|
// scroll to top of container again
|
|
$("#browse-searchresults").overflowScrollReset();
|
|
|
|
// store the type of search that was performed as an attrib
|
|
$('#browse-searchresults').data('field', userField);
|
|
|
|
$.each(data, function(index, object) {
|
|
// use a document fragment so we don't need to nest the elems
|
|
// or append during each iteration (which would be slow)
|
|
var elem = document.createElement("li");
|
|
var link = document.createElement("a");
|
|
link.textContent = object.text;
|
|
link.setAttribute("href", "#");
|
|
elem.appendChild(link);
|
|
fragment.appendChild(elem);
|
|
});
|
|
|
|
$('#browse-searchresults').append(fragment.cloneNode(true));
|
|
})
|
|
.fail(function(jqXHR) {
|
|
//if 500 or 404 (abort is okay though)
|
|
if (jqXHR.statusText !== "abort") {
|
|
$('#browse-resultswrapper').addClass('hidden');
|
|
$('#browse-suggestionserror').removeClass('hidden');
|
|
}
|
|
});
|
|
});
|
|
|
|
$('#browse-searchresults').on("click", 'a', function(event) {
|
|
// if there is an in progress request, abort it so we
|
|
// don't end up with a race condition
|
|
if(xhrGetResults && xhrGetResults.readyState != 4){
|
|
xhrGetResults.abort();
|
|
}
|
|
|
|
var term = $(this).text();
|
|
var field = $('#browse-searchresults').data('field');
|
|
var rightPaneResults = $('#browse-selectionsearch ol li');
|
|
|
|
event.preventDefault();
|
|
|
|
// clear any current selected classes and add a new one
|
|
$(this).parent().siblings().children().removeClass('selected');
|
|
$(this).addClass('selected');
|
|
|
|
// copy in the clicked text
|
|
$('#browse-selection').removeClass('hidden').text(term);
|
|
|
|
// show the right hand pane if it is not shown already
|
|
$('#browse-selectionsearch').removeClass('hidden');
|
|
|
|
// hide the no results element
|
|
$('#browse-selectionsearch .no-results').addClass('hidden');
|
|
|
|
// clear results
|
|
rightPaneResults.remove();
|
|
|
|
// turn the spinner on
|
|
$('#browse-selectionsearch .loading').removeClass('hidden');
|
|
|
|
// do the query for the term
|
|
xhrGetResults = $.get(window.location.pathname, {api: "GetResults", field: field, term: term})
|
|
.always(function() {
|
|
// hide spinner
|
|
$('#browse-selectionsearch .loading').addClass('hidden');
|
|
})
|
|
.done(function(data) {
|
|
var fragment = document.createDocumentFragment();
|
|
|
|
if (data.length === 0) {
|
|
$('#browse-selectionsearch .no-results').removeClass('hidden');
|
|
|
|
return;
|
|
}
|
|
|
|
// scroll to top of container again
|
|
$("#browse-selectionsearch").overflowScrollReset();
|
|
|
|
$.each(data, function(index, object) {
|
|
// use a document fragment so we don't need to nest the elems
|
|
// or append during each iteration (which would be slow)
|
|
var elem = document.createElement("li");
|
|
var title = document.createElement("h4");
|
|
var link = document.createElement("a");
|
|
var author = document.createElement("p");
|
|
var destination = window.location.pathname;
|
|
|
|
destination = destination.replace("browse", "detail");
|
|
destination = destination + "?biblionumber=" + object.id;
|
|
|
|
author.className = "author";
|
|
|
|
link.setAttribute("href", destination);
|
|
link.setAttribute("target", "_blank");
|
|
link.textContent = object.title;
|
|
title.appendChild(link);
|
|
|
|
author.textContent = object.author;
|
|
|
|
elem.appendChild(title);
|
|
elem.appendChild(author);
|
|
fragment.appendChild(elem);
|
|
});
|
|
|
|
$('#browse-selectionsearch ol').append(fragment.cloneNode(true));
|
|
})
|
|
.fail(function(jqXHR) {
|
|
//if 500 or 404 (abort is okay though)
|
|
if (jqXHR.statusText !== "abort") {
|
|
$('#browse-resultswrapper').addClass('hidden');
|
|
$('#browse-suggestionserror').removeClass('hidden');
|
|
}
|
|
});
|
|
|
|
});
|
|
|
|
});
|