Permalink
Browse files

Improve search: handle enter key correctly, support multi-term search

  • Loading branch information...
mhlakhani committed Feb 27, 2014
1 parent ee7cc3a commit 8663ceb745e3136c0aa511ab768d967fffdcc00f
Showing with 147 additions and 51 deletions.
  1. +147 −51 content/readerscornersearch.haml
@@ -15,81 +15,177 @@
$(function() {
var invertedIndex = {{ readerscornerindex }};

var data = []
var intersectSafe = function(a, b)
{
var ai=0, bi=0;
var result = new Array();

while( ai < a.length && bi < b.length )
{
if (a[ai] < b[bi] ){ ai++; }
else if (a[ai] > b[bi] ){ bi++; }
else
{
result.push(a[ai]);
ai++;
bi++;
}
}

for (var key in invertedIndex) {
data.push({label: key, value: invertedIndex[key]})
return result;
}

$( "#search" ).autocomplete({
minLength: 2,
source: data,
focus: function( event, ui ) {
$( "#search" ).val( ui.item.label );
return false;
},
select: function( event, ui ) {
$( "#search" ).val( ui.item.label );
var complexSearch = function ( query ) {
var value = [];
var terms = query.split(" ");
var termResults = {};

var urls = [];
for (var i in ui.item.value) {
urls.push( "{{ url_for("readerscornersearch") }}" + "/" + ui.item.value[i] + ".json");
for (var key in invertedIndex) {
for (var term in terms) {
if (terms[term].length < 3) {
continue;
}
if (key.search(terms[term]) != -1) {
for (var val in invertedIndex[key]){
if (term in termResults) {
termResults[term].push(invertedIndex[key][val]);
} else {
termResults[term] = [invertedIndex[key][val]];
}
}
}
}
}

var jxhr = [];
var result = [];
$.each(urls, function (i, url) {
jxhr.push(
$.getJSON(url, function (json) {
result.push(json);
})
);
});

$.when.apply($, jxhr).done(function() {
results = $( "#results" );
results.empty();
for (var i in result) {
item = result[i];
var baseItem = $( "<div class=\"alert alert-info\">" );
var name = "";
if ("name" in item) {
name = item.name;
}
baseItem.append( "<h3><a class=\"permalink\" href=\"" + item.link + "\" title=\"Full article\" rel=\"nofollow\">&raquo; " + name + "</a></h3>" );
var _tmp = [];
for (var key in termResults) {
_tmp.push(termResults[key]);
}
var andResults = _tmp.reduce(function(p, c, i, a) {
return intersectSafe(p, c);
});
andResults = andResults.sort(function(a,b){return a-b}).filter(function(el,i,a){if(i==a.indexOf(el))return 1;return 0});
var orResults = _tmp.reduce(function(p, c, i, a) {
for (k in c) {
p.push(c[k]);
}
return p;
});
orResults = orResults.sort(function(a,b){return a-b}).filter(function(el,i,a){if(i==a.indexOf(el))return 1;return 0});

if ("caption" in item) {
baseItem.append( "<p>" + item.caption + "</p>" );
}
for (r in andResults) {
value.push(andResults[r]);
}
for (r in orResults) {
if (andResults.indexOf(orResults[r]) == -1) {
value.push(orResults[r]);
}
}
return value;
}

if ("description" in item) {
baseItem.append( "<p><em>" + item.description + "</em></p>" );
}
var selectfn = function( event, ui ) {
$( "#search" ).val( ui.item.label );

baseItem.appendTo(results);
var urls = [];
var value = complexSearch(ui.item.label);
for (var i in value) {
urls.push( "{{ url_for("readerscornersearch") }}" + value[i] + ".json");
}

if ("message" in item) {
var quoteItem = $( "<blockquote>" );
quoteItem.append( "<p>" + item.message + "</p>" );
quoteItem.appendTo(results);
}
var jxhr = [];
var result = [];
$.each(urls, function (i, url) {
jxhr.push(
$.getJSON(url, function (json) {
result.push(json);
})
);
});

$.when.apply($, jxhr).done(function() {
results = $( "#results" );
results.empty();
for (var i in result) {
item = result[i];
var baseItem = $( "<div class=\"alert alert-info\">" );
var name = "";
if ("name" in item) {
name = item.name;
}
baseItem.append( "<h3><a class=\"permalink\" href=\"" + item.link + "\" title=\"Full article\" rel=\"nofollow\">&raquo; " + name + "</a></h3>" );

if ("caption" in item) {
baseItem.append( "<p>" + item.caption + "</p>" );
}

if ("description" in item) {
baseItem.append( "<p><em>" + item.description + "</em></p>" );
}

baseItem.appendTo(results);

if ("message" in item) {
var quoteItem = $( "<blockquote>" );
quoteItem.append( "<p>" + item.message + "</p>" );
quoteItem.appendTo(results);
}
});


}
if (result.length == 0) {
$( "<h4>No results found!</h4>" ).appendTo(results);
}
});

return false;
};

$( "#search" ).autocomplete({
minLength: 0,
delay: 0,
focus: function( event, ui ) {
$( "#search" ).val( ui.item.label );
return false;
},
select: selectfn,
search: function( event, ui ) {
results = $( "#results" );
results.empty();
},
source: function( request, response ) {
if (request.term.length < 3) {
response([{label: "Enter terms 3 characters or longer", value: "No results found"}]);
return;
}
var result = [];
for (key in invertedIndex) {
if (key.search(request.term) != -1) {
result.push({label: key, value: invertedIndex[key].length});
}
}
if (result.length == 0) {
var count = complexSearch(request.term).length;
if (count == 0) {
result.push({label: request.term, value: "No results found"});
} else {
result.push({label: request.term, value: count});
}
}
response(result);
}
}).keypress(function(e) {
if (e.keyCode === 13)
{
selectfn(0, {item: {label: $( "#search" ).val()}});
$( "#search" ).autocomplete( "close" );
}
}).data( "ui-autocomplete" )._renderItem = function( ul, item ) {
query = $("#search").val();
pos = item.label.search(query);
left = item.label.substring(0, pos);
mid = item.label.substring(pos, pos+query.length);
right = item.label.substring(pos+query.length, item.label.length);
return $( "<li>" ).append( "<a>" + left + "<b>" + mid + "</b>" + right + " (" + item.value.length + ")" + "</a>" ).appendTo( ul );
return $( "<li>" ).append( "<a>" + left + "<b>" + mid + "</b>" + right + " (" + item.value + ")" + "</a>" ).appendTo( ul )
};
});

0 comments on commit 8663ceb

Please sign in to comment.