Skip to content

Commit

Permalink
ajax search results: a cvan/gkobes collabo (bug 684342)
Browse files Browse the repository at this point in the history
  • Loading branch information
gkoberger authored and cvan committed Oct 13, 2011
1 parent a9564b1 commit e07256c
Show file tree
Hide file tree
Showing 17 changed files with 307 additions and 120 deletions.
2 changes: 1 addition & 1 deletion apps/addons/templates/addons/impala/listing/sorter.html
Original file line number Original file line Diff line number Diff line change
@@ -1,4 +1,4 @@
<div id="sorter" class="c"> <div id="sorter" class="c pjax-trigger">
<h3>{{ _('Sort by:') }}</h3> <h3>{{ _('Sort by:') }}</h3>
<ul> <ul>
{% for item in sort_opts %} {% for item in sort_opts %}
Expand Down
6 changes: 3 additions & 3 deletions apps/amo/templates/amo/impala/paginator.html
Original file line number Original file line Diff line number Diff line change
@@ -1,5 +1,5 @@
{% if pager.paginator.num_pages > 1 %} {% if pager.paginator.num_pages > 1 %}
<nav class="paginator c"> <nav class="paginator c pjax-trigger">
<p class="num"> <p class="num">
{# L10n: This is a page range (e.g., Page 1 of 50). #} {# L10n: This is a page range (e.g., Page 1 of 50). #}
{% trans current_pg=pager.number, {% trans current_pg=pager.number,
Expand All @@ -16,10 +16,10 @@
{% if not pager.has_previous() %}class="disabled"{% endif %}> {% if not pager.has_previous() %}class="disabled"{% endif %}>
&#x25C2;&#x25C2;</a> &#x25C2;&#x25C2;</a>
<a href="{{ pager.url|urlparams(page=pager.previous_page_number()) }}" <a href="{{ pager.url|urlparams(page=pager.previous_page_number()) }}"
class="button{% if not pager.has_previous() %} disabled{% endif %}"> class="button prev{% if not pager.has_previous() %} disabled{% endif %}">
&#x25C2; {{ _('Previous') }}</a> &#x25C2; {{ _('Previous') }}</a>
<a href="{{ pager.url|urlparams(page=pager.next_page_number()) }}" <a href="{{ pager.url|urlparams(page=pager.next_page_number()) }}"
class="button{% if not pager.has_next() %} disabled{% endif %}"> class="button next{% if not pager.has_next() %} disabled{% endif %}">
{{ _('Next') }} &#x25B8;</a> {{ _('Next') }} &#x25B8;</a>
<a href="{{ pager.url|urlparams(page=pager.paginator.num_pages) }}" <a href="{{ pager.url|urlparams(page=pager.paginator.num_pages) }}"
title="{{ _('Jump to last page') }}" title="{{ _('Jump to last page') }}"
Expand Down
70 changes: 33 additions & 37 deletions apps/search/templates/search/results.html
Original file line number Original file line Diff line number Diff line change
@@ -1,4 +1,8 @@
{% extends "impala/base.html" %} {% extends "base_ajax.html" if is_pjax else "impala/base.html" %}

{% block bodyclass %}
{{ 'pjax' if waffle.switch('ajax-search') }} {{ super() }}
{% endblock %}


{% block search_form %} {% block search_form %}
{% with skip_autofill=True %} {% with skip_autofill=True %}
Expand Down Expand Up @@ -47,42 +51,34 @@ <h3>{{ title }}</h3>
{% endmacro %} {% endmacro %}


{% block content %} {% block content %}
<section id="search-facets" class="secondary" role="complementary"> {% if is_pjax %}
<h2>{{ _('Filter Results') }}</h2> {% include "search/results_inner.html" %}
<ul class="facets island"> {% else %}
{{ facet(_('Category'), categories) }} <section id="search-facets" class="secondary" role="complementary">
<li class="facet"> <h2>{{ _('Filter Results') }}</h2>
<h3>{{ _('Works with') }}</h3> <ul class="facets island pjax-trigger">
{% if versions %} {{ facet(_('Category'), categories) }}
{{ facet_links(versions) }} <li class="facet">
{% endif %} <h3>{{ _('Works with') }}</h3>
{% if platforms %} {% if versions %}
{{ facet_links(platforms) }} {{ facet_links(versions) }}
{% endif %} {% endif %}
</li> {% if platforms %}
{{ facet(_('Tag'), tags) }} {{ facet_links(platforms) }}
</ul> {% endif %}
<p>{{ _('{0} matching results')|f(pager.paginator.count|numberfmt) }}</p> </li>
</section> {{ facet(_('Tag'), tags) }}

</ul>
<p>{{ _('{0} matching results')|f(pager.paginator.count|numberfmt) }}</p>
</section>


<section class="primary" role="main"> <section class="primary" role="main">

<h1>{{ heading }}</h1>
<div class="listing results island hero c"> <div class="listing results island hero c">
<h1>{{ heading }}</h1> <div id="pjax-results">
{{ impala_addon_listing_header( {% include "search/results_inner.html" %}
request.get_full_path()|urlparams(page=None), </div>
sort_opts, query.sort, extra_sort_opts) }}
{% if pager.object_list %}
<div class="items">
{{ impala_addon_listing_items(pager.object_list, field=query.sort,
src='search') }}
</div> </div>
{{ pager|impala_paginator }} </section>
{% else %} {% endif %}
{% include 'search/no_results.html' %}
{% endif %}
</div>

</section>
{% endblock %} {% endblock %}
11 changes: 11 additions & 0 deletions apps/search/templates/search/results_inner.html
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,11 @@
{{ impala_addon_listing_header(request.get_full_path()|urlparams(page=None),
sort_opts, query.sort, extra_sort_opts) }}
{% if pager.object_list %}
<div class="items">
{{ impala_addon_listing_items(pager.object_list, field=query.sort,
src='search') }}
</div>
{{ pager|impala_paginator }}
{% else %}
{% include 'search/no_results.html' %}
{% endif %}
38 changes: 36 additions & 2 deletions apps/search/tests/test_views.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -104,9 +104,10 @@ class TestESSearch(amo.tests.ESTestCase):
def setUpClass(cls): def setUpClass(cls):
super(TestESSearch, cls).setUpClass() super(TestESSearch, cls).setUpClass()
cls.setUpIndex() cls.setUpIndex()
cls.search_views = ('search.search', 'apps.search')


@amo.tests.mobile_test @amo.tests.mobile_test
def test_mobile_get(self): def test_mobile_results(self):
r = self.client.get(reverse('search.search')) r = self.client.get(reverse('search.search'))
eq_(r.status_code, 200) eq_(r.status_code, 200)
self.assertTemplateUsed(r, 'search/mobile/results.html') self.assertTemplateUsed(r, 'search/mobile/results.html')
Expand All @@ -116,6 +117,40 @@ def test_legacy_redirects(self):
r = self.client.get(base + '?sort=averagerating') r = self.client.get(base + '?sort=averagerating')
self.assertRedirects(r, base + '?sort=rating', status_code=301) self.assertRedirects(r, base + '?sort=rating', status_code=301)


def test_results(self):
# These context variables should exist for normal requests.
expected_context_vars = {
'search.search': ('categories', 'platforms', 'versions', 'tags'),
'apps.search': ('categories', 'tags'),
}

for view in self.search_views:
r = self.client.get(reverse(view))
eq_(r.status_code, 200)
eq_(r.context['is_pjax'], None)

for var in expected_context_vars[view]:
assert var in r.context, (
'%r missing context var in view %r' % (var, view))

doc = pq(r.content)
eq_(doc('html').length, 1)
eq_(doc('#pjax-results').length, 1)
eq_(doc('#search-facets .facets.pjax-trigger').length, 1)
eq_(doc('#sorter.pjax-trigger').length, 1)

def test_pjax_results(self):
for view in self.search_views:
r = self.client.get(reverse(view), HTTP_X_PJAX=True)
eq_(r.status_code, 200)
eq_(r.context['is_pjax'], True)

doc = pq(r.content)
eq_(doc('html').length, 0)
eq_(doc('#pjax-results').length, 0)
eq_(doc('#search-facets .facets.pjax-trigger').length, 0)
eq_(doc('#sorter.pjax-trigger').length, 1)

def assert_ajax_query(self, params, addons=[]): def assert_ajax_query(self, params, addons=[]):
r = self.client.get(reverse('search.ajax') + '?' + params) r = self.client.get(reverse('search.ajax') + '?' + params)
eq_(r.status_code, 200) eq_(r.status_code, 200)
Expand Down Expand Up @@ -172,7 +207,6 @@ def test_ajax_search_personas_by_id(self):
addon.update(type=amo.ADDON_PERSONA) addon.update(type=amo.ADDON_PERSONA)
Persona.objects.create(persona_id=4, addon_id=4) Persona.objects.create(persona_id=4, addon_id=4)
self.assert_ajax_query('q=4', [addon]) self.assert_ajax_query('q=4', [addon])
self.assert_ajax_query('q=4&exclude_personas=true', [])


def test_ajax_search_char_limit(self): def test_ajax_search_char_limit(self):
self.assert_ajax_query('q=ad', []) self.assert_ajax_query('q=ad', [])
Expand Down
22 changes: 15 additions & 7 deletions apps/search/views.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -418,14 +418,18 @@ def app_search(request, template=None):
facets = pager.object_list.facets facets = pager.object_list.facets


ctx = { ctx = {
'is_pjax': request.META.get('HTTP_X_PJAX'),
'pager': pager, 'pager': pager,
'query': query, 'query': query,
'form': form, 'form': form,
'sorting': sort_sidebar(request, query, form), 'sorting': sort_sidebar(request, query, form),
'sort_opts': form.fields['sort'].choices, 'sort_opts': form.fields['sort'].choices,
'categories': category_sidebar(request, query, facets),
'tags': tag_sidebar(request, query, facets),
} }
if not ctx['is_pjax']:
ctx.update({
'categories': category_sidebar(request, query, facets),
'tags': tag_sidebar(request, query, facets),
})
return jingo.render(request, template, ctx) return jingo.render(request, template, ctx)




Expand Down Expand Up @@ -500,20 +504,24 @@ def search(request, tag_name=None, template=None):
qs = qs.order_by('-weekly_downloads') qs = qs.order_by('-weekly_downloads')


pager = amo.utils.paginate(request, qs) pager = amo.utils.paginate(request, qs)
facets = pager.object_list.facets


ctx = { ctx = {
'is_pjax': request.META.get('HTTP_X_PJAX'),
'pager': pager, 'pager': pager,
'query': query, 'query': query,
'form': form, 'form': form,
'sort_opts': sort, 'sort_opts': sort,
'extra_sort_opts': extra_sort, 'extra_sort_opts': extra_sort,
'sorting': sort_sidebar(request, query, form), 'sorting': sort_sidebar(request, query, form),
'categories': category_sidebar(request, query, facets),
'platforms': platform_sidebar(request, query, facets),
'versions': version_sidebar(request, query, facets),
'tags': tag_sidebar(request, query, facets),
} }
if not ctx['is_pjax']:
facets = pager.object_list.facets
ctx.update({
'categories': category_sidebar(request, query, facets),
'platforms': platform_sidebar(request, query, facets),
'versions': version_sidebar(request, query, facets),
'tags': tag_sidebar(request, query, facets),
})
return jingo.render(request, template, ctx) return jingo.render(request, template, ctx)




Expand Down
44 changes: 44 additions & 0 deletions media/css/impala/search.less
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -123,5 +123,49 @@
li ul { li ul {
padding: 0 12px 0 0; padding: 0 12px 0 0;
} }
.facets .facet {
&:after {
right: auto;
left: 5px;
}
&.active:after {
-moz-transform: rotate(-90deg);
}
}
}
}

.results {
position: relative;
&.loading {
.updating {
background: rgba(255,255,255, 0.8)
url(../../img/impala/loading-big.gif)
50% 50px no-repeat;
border: 1px solid #ddd;
.box-shadow(0 -2px 0 rgba(200, 200, 200, 0.3) inset,
0 0 1px rgba(0, 0, 0, 0.1));
.border-box;
.border-radius(5px);
color: @medium-gray;
font: bold 20px @head-sans;
margin-left: -250px / 2;
position: absolute;
top: 45px;
left: 50%;
padding: 15px 15px 45px;
text-align: center;
z-index: 100;
width: 250px;
&.tall {
top: 200px;
}
}
.items {
opacity: .2;
}
}
#sorter {
float: none;
} }
} }
Binary file added media/img/impala/loading-big.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions media/js/impala/forms.js
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -13,3 +13,9 @@ function populateErrors(context, o) {
$row.append($list.append($(format('<li>{0}</li>', v)))); $row.append($list.append($(format('<li>{0}</li>', v))));
}); });
} }


function fieldFocused(e) {
var tags = /input|keygen|meter|option|output|progress|select|textarea/i;
return tags.test(e.target.nodeName);
}
26 changes: 16 additions & 10 deletions media/js/impala/listing.js
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -5,16 +5,7 @@ $(function() {
$p.popup($a, {width: 300, pointTo: $a}); $p.popup($a, {width: 300, pointTo: $a});
}); });


// Mark incompatible add-ons on listing pages unless marked with ignore. initListingCompat();
$('.listing .item.addon').each(function() {
var $this = $(this);
if ($this.find('.acr-override').length) {
$this.addClass('acr');
} else if (!$this.hasClass('ignore-compatibility') &&
$this.find('.concealed').length == $this.find('.button').length) {
$this.addClass('incompatible');
}
});


$('.theme-grid .hovercard.theme').each(function() { $('.theme-grid .hovercard.theme').each(function() {
var $this = $(this); var $this = $(this);
Expand All @@ -38,3 +29,18 @@ $(function() {
$('.item.static').removeClass('static'); $('.item.static').removeClass('static');
}); });
}); });


function initListingCompat(domContext) {
domContext = domContext || document.body;
// Mark incompatible add-ons on listing pages unless marked with ignore.
$('.listing .item.addon', domContext).each(function() {
var $this = $(this);
if ($this.find('.acr-override').length) {
$this.addClass('acr');
} else if (!$this.hasClass('ignore-compatibility') &&
$this.find('.concealed').length == $this.find('.button').length) {
$this.addClass('incompatible');
}
});
}
Loading

0 comments on commit e07256c

Please sign in to comment.