diff --git a/main/models.py b/main/models.py index 1b731616c52d014bcdd0d62eff7e1edfbffc9931..26535bfa4b0e045fb7c754dac3c4da8393cebfd4 100644 --- a/main/models.py +++ b/main/models.py @@ -436,22 +436,23 @@ class MainArticlesPage( return article_data_list - def get_context(self, request, *args, **kwargs): + def get_context(self, request, get_articles: bool = True, *args, **kwargs): ctx = super().get_context(request, args, kwargs) - article_timeline_list = self.get_article_data_list(1) - ctx["article_timeline_list"] = article_timeline_list - ctx["show_next_timeline_articles"] = MainArticlePage.objects.filter( - article_type=ARTICLE_TYPES.WORK_TIMELINE - ).live().count() > len(article_timeline_list) - - article_list = ( - MainArticlePage.objects.filter(article_type=ARTICLE_TYPES.PRESS_RELEASE) - .order_by("-date") - .live()[:11] - ) # dám LIMIT +1, abych věděl, jestli má cenu show_next - ctx["article_article_list"] = article_list[:10] - ctx["show_next_article"] = len(article_list) > 10 + if get_articles: + article_timeline_list = self.get_article_data_list(1) + ctx["article_timeline_list"] = article_timeline_list + ctx["show_next_timeline_articles"] = MainArticlePage.objects.filter( + article_type=ARTICLE_TYPES.WORK_TIMELINE + ).live().count() > len(article_timeline_list) + + article_list = ( + MainArticlePage.objects.filter(article_type=ARTICLE_TYPES.PRESS_RELEASE) + .order_by("-date") + .live()[:11] + ) # dám LIMIT +1, abych věděl, jestli má cenu show_next + ctx["article_article_list"] = article_list[:10] + ctx["show_next_article"] = len(article_list) > 10 return ctx @@ -488,6 +489,28 @@ class MainArticlesPage( } return JsonResponse(data=data, safe=False) + def get_all_articles_search_response(self, request): + article_paginator = Paginator( + MainArticlePage + .objects + .order_by("-date") + .live() + .search(request.GET["q"]), + 10, + ) + article_page = article_paginator.get_page(request.GET.get("page", 1)) + context = {"article_data_list": article_page.object_list} + html_content = render( + request, + "main/includes/person_article_preview.html", + context + ).content + data = { + "html": html_content.decode("utf-8"), + "has_next": article_page.has_next(), + } + return JsonResponse(data=data, safe=False) + @cached_property def search_url(self): return self.url + self.reverse_subpage("search") @@ -497,22 +520,23 @@ class MainArticlesPage( if request.method == "GET" and "q" in request.GET: query = request.GET["q"] - # Show 30 top results for the time being - results = ( + article_results = ( MainArticlePage .objects + .order_by("-date") .live() .search(query) - [:30] + [:11] ) return render( request, "main/main_article_search.html", { - **self.get_context(request), + **self.get_context(request, get_articles=False), "query": query, - "results": results, + "article_results": article_results[:10], + "show_more_articles": len(article_results) > 10, "sub_heading": f"Vyhledávání „{query}“" } ) @@ -524,7 +548,10 @@ class MainArticlesPage( if "months" in request.GET: return self.get_timeline_articles_response(request) if "page" in request.GET: - return self.get_articles_response(request) + if "q" not in request.GET: + return self.get_articles_response(request) + else: + return self.get_all_articles_search_response(request) return super().serve(request, *args, **kwargs) diff --git a/main/templates/main/main_article_search.html b/main/templates/main/main_article_search.html index e9cad7545ee0805a1df90d89984771e5afbf08f6..4031c09f7081f91257819bb31c2b83a03af889f1 100644 --- a/main/templates/main/main_article_search.html +++ b/main/templates/main/main_article_search.html @@ -6,59 +6,103 @@ <main role="main"> <div class="__js-root"> - <div class="grid-container article-section mb-8"> - <div class="grid-full"> - <div class="flex justify-center"> - <div class="flex flex-col items-end gap-3"> - <form - class="flex flex-row" - method="get" - action="{{ page.search_url }}" - > - <input - class="bg-grey-150 w-56 h-10 px-4 text-lg xl:h-14 xl:px-5" - type="text" - id="q" - name="q" - value="{{ query }}" - placeholder="Hledat články..." - aria-label="Vyhledávací box" - > - <button - class="btn btn--yellow-500 btn--to-yellow-600 btn--hoveractive" - aria-label="Vyhledat" - type="submit" - > - <div class="btn__body-wrap h-10 w-12 min-h-0 min-w-0 xl:h-14 xl:w-14"> - <div class="btn__body p-0"> - <i class="ico--search"></i> - </div> - </div> - </button> - </form> - <a href="{{ page.url }}" class="btn btn--black btn--to-yellow-500 btn--hoveractive uppercase"> - <span class="btn__body-wrap"> - <span class="btn__body text-lg lg:text-base"> - Zpět na seznam - </span> - </span> - </a> - </div> - </div> - </div> - </div> - <section class="mb-3 xl:mb-14"> - {% if results %} - {% include 'main/includes/person_article_preview.html' with article_data_list=results %} - {% else %} - <div class="grid-container article-section mb-8"> - <div class="grid-full"> - <p class="text-grey-300 text-center">Žádné výsledky.</p> - </div> - </div> - {% endif %} - </section> + <div class="grid-container article-section mb-8"> + <div class="grid-full"> + <div class="flex justify-center"> + <div class="flex flex-col items-end gap-3"> + <form + class="flex flex-row" + method="get" + action="{{ page.search_url }}" + > + <input + class="bg-grey-150 w-56 h-10 px-4 text-lg xl:h-14 xl:px-5" + type="text" + id="q" + name="q" + value="{{ query }}" + placeholder="Hledat články..." + aria-label="Vyhledávací box" + > + <button + class="btn btn--yellow-500 btn--to-yellow-600 btn--hoveractive" + aria-label="Vyhledat" + type="submit" + > + <div class="btn__body-wrap h-10 w-12 min-h-0 min-w-0 xl:h-14 xl:w-14"> + <div class="btn__body p-0"> + <i class="ico--search"></i> + </div> + </div> + </button> + </form> + <a href="{{ page.url }}" class="btn btn--black btn--to-yellow-500 btn--hoveractive uppercase"> + <span class="btn__body-wrap"> + <span class="btn__body text-lg lg:text-base"> + Zpět na seznam + </span> + </span> + </a> + </div> + </div> + </div> + </div> + <section class="mb-3 xl:mb-14"> + {% if article_results %} + <div id="searchArticleResultWrapper"> + {% include 'main/includes/person_article_preview.html' with article_data_list=article_results %} + </div> + {% if show_more_articles %} + <div class="grid-container"> + <div class="grid-content-with-right-side"> + <a + onclick="showMoreArticles(event, this)" + href="#" + data-url="{{ page_url }}" + data-page="2" + data-query="{{ query }}" + class="btn btn--black btn--to-yellow-500 btn--hoveractive uppercase" + > + <span class="btn__body-wrap"> + <span class="btn__body text-lg lg:text-base"> + Zobrazit další + </span> + </span> + </a> + </div> + </div> + {% endif %} + {% else %} + <div class="grid-container article-section mb-8"> + <div class="grid-full"> + <p class="text-grey-300 text-center">Žádné výsledky.</p> + </div> + </div> + {% endif %} + </section> {% include "main/includes/newsletter_section.html" %} </div> </main> + + <script type="text/javascript"> + async function showMoreArticles(event, btn) { + event.preventDefault() + + let searchArticleResultWrapper = document.getElementById('searchArticleResultWrapper') + let url = ( + btn.getAttribute('data-url') + + `?page=${btn.getAttribute('data-page')}` + + `&q=${btn.getAttribute('data-query')}` + ) + + const response = await fetch(url, { + method: "GET", + headers: {"X-Requested-With": "XMLHttpRequest"}, + }) + const data = await response.json() + searchArticleResultWrapper.innerHTML += data.html; + if (!data.has_next) { btn.style.display = 'none'; } + btn.setAttribute('data-page', parseInt(btn.getAttribute('data-page')) + 1) + } + </script> {% endblock content %}