Skip to content

Commit

Permalink
feat: add searching (#157)
Browse files Browse the repository at this point in the history
Resolves #36.
  • Loading branch information
greatislander authored Aug 17, 2020
1 parent 5bfb1d9 commit a405a85
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 35 deletions.
45 changes: 30 additions & 15 deletions maps/static/maps/css/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -228,35 +228,40 @@ select[multiple] {
}
}

.my-profiles .cards .card__wrapper {
.my-profiles .cards .card__wrapper,
.results .cards .card__wrapper {
display: grid;
gap: 1.25rem;
grid-template-columns: 100%;
grid-template-rows: 1fr 3rem;
}

@media (min-width: 37.5rem) {
.my-profiles .cards {
.my-profiles .cards,
.results .cards {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}

@supports (display:grid) {
.my-profiles .cards {
.my-profiles .cards,
.results .cards {
display: grid;
gap: 1.875rem;
grid-template-columns: 100%;
}
}

.my-profiles .cards .card__wrapper {
.my-profiles .cards .card__wrapper,
.results .cards .card__wrapper {
margin-bottom: 1.875rem;
width: 100%;
}

@supports (display:grid) {
.my-profiles .cards .card__wrapper {
.my-profiles .cards .card__wrapper,
.results .cards .card__wrapper {
margin-bottom: 0;
}
}
Expand All @@ -276,56 +281,66 @@ select[multiple] {
}

@supports (display:grid) {
.my-profiles .cards {
.my-profiles .cards,
.results .cards {
grid-template-columns: repeat(2, 1fr);
}
}

.my-profiles .cards .card__wrapper {
.my-profiles .cards .card__wrapper,
.results .cards .card__wrapper {
width: calc(50% - 0.9375rem);
}

@supports (display:grid) {
.my-profiles .cards .card__wrapper {
.my-profiles .cards .card__wrapper,
.results .cards .card__wrapper {
width: 100%;
}
}

.my-profiles .card:nth-child(2n) {
.my-profiles .card:nth-child(2n),
.results .card:nth-child(2n) {
margin-left: 1.875rem;
}

@supports (display:grid) {
.my-profiles .card:nth-child(2n) {
.my-profiles .card:nth-child(2n),
.results .card:nth-child(2n) {
margin-left: 0;
}
}

.my-profiles .cards .card__wrapper + .card__wrapper {
.my-profiles .cards .card__wrapper + .card__wrapper,
.results .cards .card__wrapper + .card__wrapper {
margin-top: 0;
}
}

@media (min-width: 80rem) {
.my-profiles main {
.my-profiles main,
.results main {
width: calc(66.66667% - 0.625rem);
}

@supports (display:grid) {
.my-profiles main {
.my-profiles main,
.results main {
grid-column: 3/11;
width: 100%;
}
}
}

@media (min-width: 120rem) {
.my-profiles main {
.my-profiles main,
.results main {
width: calc(50% - 0.9375rem);
}

@supports (display:grid) {
.my-profiles main {
.my-profiles main,
.results main {
grid-column: 4/12;
width: 100%;
}
Expand Down
10 changes: 1 addition & 9 deletions maps/templates/maps/header.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,7 @@
{% icon 'search' %}
</button>

<form role="search" method="get" class="search-form search-form--inverse" action="#">
<label>
<span class="screen-reader-text">{% trans 'search' %}</span>
<input id="s" name="s" type="search" />
</label>
<button type="submit" class="button button--search"><span class="screen-reader-text">{% trans 'submit search' %}</span>
{% icon 'search' %}
</button>
</form>
{% include 'maps/search.html' %}
{% endif %}

<nav class="nav" aria-labelledby="menu-primary-label">
Expand Down
10 changes: 6 additions & 4 deletions maps/templates/maps/search--home.html
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
{% load maps_extras %}
{% load i18n %}
<section class="home__search">
<form role="search" method="get" class="search-form search-form--inverse" action="/">
<form role="search" method="get" class="search-form search-form--inverse" action="{% url 'search_results' %}">
<!-- {% csrf_token %} -->
<label>
<span class="screen-reader-text">search</span>
<input id="s" name="s" placeholder="Search by co-op or individual name, details, or tags…" type="search">
<span class="screen-reader-text">{% trans 'search' %}</span>
<input id="s" name="s" placeholder="{% trans 'Search by co-op or individual name, details, or tags…' %}" type="search">
</label>
<button type="submit" class="button button--search" disabled><span class="screen-reader-text">submit search</span> {% icon 'search' %}
<button type="submit" class="button button--search"><span class="screen-reader-text">{% trans 'submit search' %}</span> {% icon 'search' %}
</button>
</form>
</section>
10 changes: 6 additions & 4 deletions maps/templates/maps/search.html
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
{% load maps_extras %}
<form role="search" method="get" class="search-form" action="/">
{% load i18n %}
<form role="search" method="get" class="search-form" action="{% url 'search_results' %}">
<!-- {% csrf_token %} -->
<label>
<span class="screen-reader-text">search</span>
<input id="s" name="s" placeholder="Search by co-op or individual name, details, or tags…" type="search">
<span class="screen-reader-text">{% trans 'search' %}</span>
<input id="s" name="s" placeholder="{% trans 'Search…' %}" type="search">
</label>
<button type="submit" class="button button--search"><span class="screen-reader-text">submit search</span> {% icon 'search' %}</button>
<button type="submit" class="button button--search"><span class="screen-reader-text">{% trans 'submit search' %}</span> {% icon 'search' %}</button>
</form>
34 changes: 34 additions & 0 deletions maps/templates/maps/search_results.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{% extends 'maps/base.html' %}
{% load i18n %}
{% load maps_extras %}
{% block title %}{{ 'Search results' |titlify }}{% endblock %}
{% block bodyclass %}results{% endblock %}
{% block content %}
<div class="page-header">
<p><a class="link--breadcrumb" href="/">{% trans 'Home' %}</a></p>
<h1>{% blocktrans with search_term=search_term %}Search results for “{{ search_term }}”{% endblocktrans %}</h1>
</div>
{% include 'maps/partials/messages.html' %}
{% if object_list %}
<h2 aria-role="status">{% if object_list|length > 1 %}{% blocktrans with org_count=object_list|length %}{{org_count}} organizations found{% endblocktrans %}{% else %}{% trans '1 organization found' %}{% endif %}</h2>
<ul class="cards">
{% for organization in object_list %}
{% include 'maps/partials/card_organization.html' %}
{% endfor %}
</ul>
{% else %}
<h2 aria-role="status">{% trans 'No organizations found' %}</h2>
<p>{% trans 'No organizations matched your search term.' %}</p>
{% endif %}
{% if individual_list %}
<h2 aria-role="status">{% if individual_list|length > 1 %}{% blocktrans with individual_count=individual_list|length %}{{individual_count}} individuals found{% endblocktrans %}{% else %}{% trans '1 individual found' %}{% endif %}</h2>
<ul class="cards">
{% for individual in individual_list %}
{% include 'maps/partials/card_individual.html' %}
{% endfor %}
</ul>
{% else %}
<h2 aria-role="status">{% trans 'No individuals found' %}</h2>
<p>{% trans 'No individuals matched your search term.' %}</p>
{% endif %}
{% endblock %}
3 changes: 2 additions & 1 deletion maps/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from .views import INDIVIDUAL_FORMS, ORGANIZATION_FORMS, TOOL_FORMS, show_more_about_you_condition, show_scope_and_impact_condition,\
IndividualProfileWizard, OrganizationProfileWizard, ToolWizard, OrganizationDelete, PrivacyPolicyView, TermsOfServiceView, AboutPageView,\
InvididualOverviewUpdate, InvididualBasicInfoUpdate, OrganizationBasicInfoUpdate, OrganizationOverviewUpdate, OrganizationContactUpdate,\
SummaryPageView, ToolUpdate
SummaryPageView, ToolUpdate, SearchResultsView
from accounts.models import UserSocialNetwork
from mdi.models import SocialNetwork

Expand All @@ -26,6 +26,7 @@
path('accounts/', views.account_settings, name='account-settings'),
path('about/', AboutPageView.as_view(), {'title': 'About'}, name='about'),
path('about/impact/', SummaryPageView.as_view(), {'title': 'Summary of Impact'}, name='impact'),
path('search/', SearchResultsView.as_view(), name='search_results'),
path('privacy-policy/', PrivacyPolicyView.as_view(), {'title': 'Privacy Policy'}, name='privacy_policy'),
path('terms-of-service/', TermsOfServiceView.as_view(), {'title': 'Terms of Service'}, name='terms_of_service'),
]
29 changes: 27 additions & 2 deletions maps/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib import messages
from django.conf import settings
from django.db.models import Sum, Count
from django.db.models import Sum, Count, Q, Value
from django.db.models.functions import Concat
from django_countries import countries
from django.http import HttpResponse, HttpResponseRedirect
from django.urls import reverse_lazy, reverse
from django.template import loader
from django.utils.translation import gettext_lazy as _
from django.views.generic import TemplateView
from django.views.generic import TemplateView, ListView
from django.views.generic.edit import DeleteView, UpdateView
from django.shortcuts import get_object_or_404, render, redirect
from django.forms import inlineformset_factory # ModelMultipleChoiceField, SelectMultiple
Expand Down Expand Up @@ -754,6 +755,30 @@ def delete(self, request, *args, **kwargs):
messages.success(self.request, self.success_message % obj.__dict__)
return super(OrganizationDelete, self).delete(request, *args, **kwargs)


class SearchResultsView(ListView):
model = Organization
template_name = 'maps/search_results.html'

def get_queryset(self):
query = self.request.GET.get('s')
object_list = Organization.objects.filter(
Q(name__icontains=query) | Q(type__name__icontains=query) | Q(sectors__name__icontains=query) | Q(categories__name__icontains=query) | Q(description__icontains=query) | Q(city__icontains=query) | Q(state__icontains=query) | Q(country__exact=query) | Q(legal_status__name__icontains=query)
).distinct()
return object_list

def get_context_data(self, **kwargs):
query = self.request.GET.get('s')
context = super(SearchResultsView, self).get_context_data(**kwargs)
individual_list = get_user_model().objects.annotate(full_name=Concat('first_name', Value(' '), 'last_name')).filter(has_profile=True).filter(
Q(full_name__icontains=query) | Q(roles__name__icontains=query) | Q(bio__icontains=query) | Q(city__icontains=query) | Q(state__icontains=query) | Q(country__exact=query) | Q(affiliation__icontains=query)
)
context.update({
'search_term': query,
'individual_list': individual_list
})
return context

# My Profiles


Expand Down

0 comments on commit a405a85

Please sign in to comment.