this.service = new FluidbookService(this, datas.id);
this.support = new FluidbookSupport(this);
this.loader = new FluidbookLoader(this);
+ this.index = new FluidbookIndex(this);
this.search = new FluidbookSearch(this);
this.pad = new FluidbookPad(this);
this.links = new FluidbookLinks(this);
$('#menuList > ul > li').not(exception).fadeIn(300);
},
+ initSearchResults: function () {
+ this.menuSearchResults = $('#menuSearchResults');
+ },
initSearchHints: function () {
this.hideMenuItems('#menuSearch'); // Hide everything except the search form so we can have space for the hints
this.menuSearchHints.fadeIn(300);
+
+ this.initSearchResults();
+
// if (this.menuSearchHints.hasClass('mm-hidden')) {
// this.nav.menuAPI.openPanel(this.menuSearchHints, false);
// }
// $("#searchHints").html('');
// $("#searchHints").hide();
this.menuSearchHints.html('').hide(); // Clear and hide all hints
- this.showMenuItems('#menuSearch'); // Show menu items that were hidden previously
},
+
+ hideSearchResults: function () {
+ this.menuSearchResults.html('').hide();
+ },
+
+ // Check if a search is active in the interface
+ isSearchActive: function () {
+ return ($('#q').val().length > 0);
+ },
+
+ // Clear search query and close search related menu items
+ closeSearch: function () {
+ $('#q').val(''); // Clear search field
+ this.hideSearchHints();
+ this.hideSearchResults();
+ this.showMenuItems(); // Show menu items that were hidden previously
+ },
+
getLocationToShare: function () {
if (this.datas.phonegap) {
return this.datas.offlineLink;
// Bind API hooks (see http://mmenu.frebsite.nl/documentation/core/off-canvas.html#h4)
this.menuAPI.bind("open:finish", function () {
+ $('body').addClass('menu-open');
$this.menuIsOpen = true;
});
this.menuAPI.bind("close:finish", function () {
+ $('body').removeClass('menu-open');
$this.menuIsOpen = false;
});
// Click handler to close menu
$(document).on('click', '#' + buttonID, function(e) {
+
e.preventDefault();
- $this.menuAPI.close();
+
+ // If the search is active, the close button should clear the search
+ // and return the user to the main menu instead of closing the menu
+ if ($this.fluidbook.isSearchActive()) {
+ $this.fluidbook.closeSearch();
+ } else {
+ $this.menuAPI.close();
+ }
+
+
});
return '<a href="#" id="'+ buttonID +'">'+ getSpriteIcon('interface-close') +'</a>';
// Search form handler
$(document).on('submit', '#searchForm', function () {
var q = $("#q").val();
+
if (q == '') {
return false;
}
$this.fluidbook.search.find(q, function (results) {
- // Todo: see FluidbookMenu displayResults function...
+
+ // Handle empty result set
+ if (results.total <= 0) {
+ fluidbook.menuSearchResults.html(this.fluidbook.l10n.__('no result found'));
+ return false;
+ }
+
+ var hits = [];
+
+ // Create a list of all pages so we can record which ones have a hit on the search term
+ for (var i = 0; i <= $this.fluidbook.datas.pages; i++) {
+ hits[i] = 0;
+ }
+ // Map result hits to pages
+ $.each(results.results, function (k, v) {
+ hits[k] += v;
+ });
+
+ // ToDo: check the purpose of the group variable? Also check tracking
//$this.displayResults(r, group, cb);
- console.log('Search results...');
- console.log(results);
+ //console.log('Search results...');
+ //console.log(results);
+
+ // Display results
+ //res += $this.fluidbook.l10n.__('search results for') + ' « ' + q + " »"
+
+ // Use the index of all pages as a starting point to filter results thumbnails
+ fluidbook.menuSearchResults.html($this.fluidbook.index.getView()).hide();
+
+ // Process each spread of pages to collect the ones with results
+ fluidbook.menuSearchResults.find('.doubleThumb').each(function() {
+
+ var currentPages = $(this).data('pages').toString().split(','),
+ totalHits = 0,
+ pagesWithHits = [];
+
+ // Get total number of hits for pages in this spread
+ for (var i in currentPages) {
+ var pageNum = parseInt(currentPages[i]);
+ if (hits[pageNum] > 0) {
+ totalHits += hits[pageNum];
+ pagesWithHits.push(currentPages[i]);
+ }
+ }
+
+
+ // If there's already a .hits element, this spread has already been processed
+ if ($(this).find('.hits').length > 0) {
+ return;
+ }
+
+ if (totalHits == 0) {
+ // Should pages with no results still be shown?
+ if (fluidbook.datas.searchShowNoResultsPages) {
+ $(this).append('<div class="overlay"></div>');
+ $(this).append('<div class="hits no">' + $this.fluidbook.l10n.__('no result found') + '</div>');
+ } else {
+ $(this).remove();
+ return;
+ }
+ } else {
+ // Add the
+ $(this).append('<div class="hits yes">' + totalHits + ' ' + fluidbook.l10n.__('hit(s)') + '</div>');
+ if (fluidbook.pad.enabled) {
+ if (pagesWithHits.length == 1) {
+ $(this).find('a').attr('href', '#/page/' + pagesWithHits[0]);
+ } else {
+ $(this).find('a').attr('href', '#/search/' + e + '/' + $(this).attr('page'));
+ }
+ } else {
+ $(this).find('a').attr('href', '#/page/' + $(this).attr('page'));
+ }
+ }
+
+ });
+
+ // Todo: handle results.terms here... Highlighting?
+
+
+ fluidbook.hideSearchHints();
+ fluidbook.menuSearchResults.fadeIn(300);
+
});
// window.location.hash = '/search/' + q;
});
//$("#q").keyup(searchHints);
- $(document).on('keyup', '#q', searchHints);
+ $(document).on('keyup', '#q', function(key) {
+ if (13 == key.which) return; // Ignore enter key otherwise hints are re-displayed after form is submitted
+ searchHints();
+ });
$(document).on('click', ".hint", function () {
var e = $("#q").val().split(' ');