Skip to content

Commit

Permalink
Merge branch 'pr/1548'
Browse files Browse the repository at this point in the history
* pr/1548:
  Tidy whitespace
  Disable mouse movement select on autocomplete
  use Constructor.io autocomplete for author search
  • Loading branch information
rwstauner committed Jul 6, 2015
2 parents d43df67 + 5c845be commit 3baa39e
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 47 deletions.
2 changes: 2 additions & 0 deletions root/home.html
Expand Up @@ -4,6 +4,8 @@
<form action="/search">
<input type="text" name="q" size="41" autofocus="autofocus" id="search-input" class="form-control home-search-input">
<input type="hidden" name="size" id="size" value="20">
<input type="radio" class="search-radios" id="search_modules" name="search_type" value="modules" checked> <label for="search_modules" class="search-labels"> Modules</label>
<input type="radio" class="search-radios" id="search_authors" name="search_type" value="authors"> <label for="search_authors" class="search-labels"> Authors</label>
<br>
<button type="submit" class="btn search-btn">Search the CPAN</button>
<button type="submit" class="btn search-btn" name="lucky" value="1">I'm Feeling Lucky</button>
Expand Down
2 changes: 1 addition & 1 deletion root/mobile/toolbar-search-form.html
Expand Up @@ -3,4 +3,4 @@
<input type="search" class="form-control tool-bar-form" placeholder="Search" name="q">
<input type="submit" class="hidden">
</form>
</div>
</div>
17 changes: 17 additions & 0 deletions root/static/css/jquery.autocomplete.css
Expand Up @@ -25,6 +25,11 @@
overflow: hidden;
}

.autocomplete-suggestion-description {
font-size: 0.7em;
margin-left: 10px;
}

input {
font-size: 28px;
padding: 10px;
Expand All @@ -33,6 +38,18 @@ input {
margin: 20px 0;
}

input[type=radio].search-radios {
display: inline;
width: auto !important;
vertical-align: middle;
margin-right: 5px;
}

label.search-labels {
vertical-align: middle;
margin: 0 45px 0 0;
}

div.autocomplete-suggestions div:nth-child(2n+2) {
background: #f9f9f9;
}
Expand Down
126 changes: 85 additions & 41 deletions root/static/js/cpan.js
Expand Up @@ -184,52 +184,96 @@ $(document).ready(function() {
if (search_input.hasClass('top-input-form')) {
ac_width += search_input.parents("form.search-form").first().find('.search-btn').first().outerWidth();
}
search_input.autocomplete({
serviceUrl: '/search/autocomplete',
// Wait for more typing rather than firing at every keystroke.
deferRequestBy: 150,
// If the autocomplete fires with a single colon ("type:") it will get no results
// and anything else typed after that will never trigger another query.
// Set 'preventBadQueries:false' to keep trying.
preventBadQueries: false,
dataType: 'json',
lookupLitmit: 20,
paramName: 'q',
autoSelectFirst: false,
// This simply caches the results of a previous search by url (so no reason not to).
noCache: false,
triggerSelectOnValidInput: false,
maxHeight: 180,
width: ac_width,
transformResult: function(data) {
var result = $.map(data, function(row) {
search_input.bind('modules_autocomplete', function() {
$(this).autocomplete({
serviceUrl: '/search/autocomplete',
// Wait for more typing rather than firing at every keystroke.
deferRequestBy: 150,
// If the autocomplete fires with a single colon ("type:") it will get no results
// and anything else typed after that will never trigger another query.
// Set 'preventBadQueries:false' to keep trying.
preventBadQueries: false,
dataType: 'json',
lookupLitmit: 20,
paramName: 'q',
autoSelectFirst: false,
// This simply caches the results of a previous search by url (so no reason not to).
noCache: false,
triggerSelectOnValidInput: false,
maxHeight: 180,
width: ac_width,
transformResult: function(data) {
var result = $.map(data, function(row) {
return {
data: row.documentation,
value: row.documentation
};
});
var uniq = {};
result = $.grep(result, function(row) {
uniq[row.value] = typeof(uniq[row.value]) == 'undefined' ? 0 : uniq[row.value];
return uniq[row.value]++ < 1;
});
return {
data: row.documentation,
value: row.documentation
suggestions: result
};
});
var uniq = {};
result = $.grep(result, function(row) {
uniq[row.value] = typeof(uniq[row.value]) == 'undefined' ? 0 : uniq[row.value];
return uniq[row.value]++ < 1;
});
return {
suggestions: result
};
},
onSelect: function(suggestion) {
document.location.href = '/pod/' + suggestion.value;
},
onSelect: function(suggestion) {
document.location.href = '/pod/' + suggestion.value;
}
});

// Disable the built-in hover events to work around the issue that
// if the mouse pointer is over the box before it appears the event may fire erroneously.
// Besides, does anybody really expect an item to be selected just by
// hovering over it? Seems unintuitive to me. I expect anyone would either
// click or hit a key to actually pick an item, and who's going to hover to
// the item they want and then instead of just clicking hit tab/enter?
$('.autocomplete-suggestions').off('mouseover.autocomplete');
$('.autocomplete-suggestions').off('mouseout.autocomplete');
});

search_input.bind('authors_autocomplete', function() {
$(this).constructorAutocomplete({
key: 'bQssESEa8XUBKzSUjarO',
directResults: true,
maxHeight: 400,
transformResult: function(response) {
if (response['sections'] && response['sections']['url']) {
response['sections']['url'].forEach(function(dataset) {
if (dataset.value) {
dataset.value = dataset.value.replace(/^[^:]+: /, "");
}
});
}
return response;
}
});

// Disable the built-in hover events (see comment above)
$('.autocomplete-suggestions').off('mouseover.autocomplete');
$('.autocomplete-suggestions').off('mouseout.autocomplete');
});
search_input.trigger('modules_autocomplete');
$.getScript("//cnstrc.com/js/ac.js", function() {
if ($('input[name=search_type]:checked').val() == "authors") {
search_input.trigger('authors_autocomplete');
}
});

// Disable the built-in hover events to work around the issue that
// if the mouse pointer is over the box before it appears the event may fire erroneously.
// Besides, does anybody really expect an item to be selected just by
// hovering over it? Seems unintuitive to me. I expect anyone would either
// click or hit a key to actually pick an item, and who's going to hover to
// the item they want and then instead of just clicking hit tab/enter?
$('.autocomplete-suggestions').off('mouseover.autocomplete');
$('.autocomplete-suggestions').off('mouseout.autocomplete');
$("input[name=search_type]").click(function() {
if ($(this).val() == "authors") {
if (typeof $("#search-input").autocomplete === "function") {
$("#search-input").autocomplete("dispose");
}
search_input.trigger('authors_autocomplete');
} else {
if (typeof $("#search-input").constructorAutocomplete === "function") {
$("#search-input").constructorAutocomplete("dispose");
}
search_input.trigger('modules_autocomplete');
}
});

$('#search-input.autofocus').focus();

Expand Down
16 changes: 11 additions & 5 deletions root/wrapper.html
Expand Up @@ -180,11 +180,17 @@
<div class="input-group">
<form action="<% IF req.uri.path == '/mirrors'; req.uri.path; ELSE; '/search'; END %>" class="form-inline search-form">
<div class="input-append">
<input type="text" name="q" size="41" id="search-input" class="form-control top-input-form" value="<% req.param('q').join(' ') or req.parameters.lucky %>">
<input type="hidden" name="size" id="size" value="20">
<span class="input-group-btn">
<button class="btn search-btn" type="submit">Search<% IF req.uri.path == '/mirrors' %> Mirrors<% END %></button>
</span>
<div>
<input type="text" name="q" size="41" id="search-input" class="form-control top-input-form" value="<% req.param('q').join(' ') or req.parameters.lucky %>">
<input type="hidden" name="size" id="size" value="20">
<span class="input-group-btn">
<button class="btn search-btn" type="submit">Search<% IF req.uri.path == '/mirrors' %> Mirrors<% END %></button>
</span>
</div>
<div class="smaller">
<input type="radio" class="search-radios" id="search_modules" name="search_type" value="modules" <% IF !(req.param('search_type') eq 'authors' || req.uri.path.search('^/author/')) %> checked <% END %>> <label for="search_modules" class="search-labels"> Modules</label>
<input type="radio" class="search-radios" id="search_authors" name="search_type" value="authors" <% IF (req.param('search_type') eq 'authors' || req.uri.path.search('^/author/')) %> checked <% END %>> <label for="search_authors" class="search-labels"> Authors</label>
</div>
<small class="smaller">
<% IF total.defined; IF page > 1 %>Page <% page %> of <% END; IF total == 999; 'more than '; END; total | format_number %>
result<% IF total != 1; 's'; END %> (<% took / 1000 %> seconds)<% ELSE; "&nbsp;" | none; END %>
Expand Down

0 comments on commit 3baa39e

Please sign in to comment.