djangoajaxwagtaillivesearch

Ajax live search in header on wagtail/Django


I recently just started learning Python, Wagtail and Django. There was a need to create a live search in the header of the site, but I just can’t get it to work correctly; as a result of the search, the entire page with search results is loaded.

Here's the code I put a lot of effort into:

in header.html:

<div class="block_search">
<input type="text" class="search_input searchbox"  id="search_header" value="" placeholder="Поиск товара..." name="q"  >
{% include "tags/header_search.html" %}
</div>
        

header_search.html:

{% load static wagtailcore_tags header_tags %}

<div id="search_box-result">
    {% get_header_search as search_result%}
    {% for result in search_result %}
    {{result.title}}
    {% endfor %}
</div>

Jquery:

<script>
        
                $(document).ready(function () {
                    $('#search_header').on('input',function(e){
                        var search_result = $("#search_header").val();
                        $.ajax({
                            type: 'GET',
                            cache: true,
                            url: '',
                            data: {"search": search_result},
                            success: function (response) {
                                $("#search_box-result").replaceWith(response)
                            }
                        });
                    });
                    
                    
                });
</script>

header_tags.py:

@register.simple_tag(takes_context=True)
def get_header_search(context):
    request = context['request']
    if request.method == 'GET':
        search_query = request.GET.get("search", None)
        print(search_query)
        if search_query:
            search_results = Page.objects.live().search(search_query)
        else:
            search_results = Page.objects.none()
        return search_results

`In browser: enter image description here

enter image description here


Solution

  • I think you need a way to identify where is an ajax call or a user call from a browser. I want that too. Considering what is the difference between ajax and user browser request I found this link When I can differentiate between those call I made this code:

    def is_ajax(request):
      if(request.headers.get('SEC_FETCH_SITE') == "same-origin"):
        return True
      return False    
    
    class Model(Page):
      description = models.CharField(max_length=511)
      def get_template(self, request):
        if is_ajax(request):
          return "base/model_ajax.html"
        return "base/model_page.html"
    

    When you look up your get_header_search tag, you can differentiate if it's ajax or not. Maybe when it's ajax, you can use another template or a JsonResponse, and when isn't, you can load a different template.

    When you ask by ajax, you need an URL, that url in wagtail could be a Wagtail API syntax or just a static url that could be rendered with the django context processor. In my case, it was for a static URL rendered inside the template, when I click it, I make an ajax call to a document specifically for a template, and when it wasn't . I just put a normal template.

    I hope it helps.