0

So I have a homepage that consists of a base listview which includes all of the objects from my db(as shown in the cbv .all() query). What I wanted to do is include a search filter, hence I thought it would be a good idea to isolate it into a separate "list.html" fragment in order to make it reusable later on. Currently, I have an ajax call that sends information to the cbv and the return is a render to list.html fragment. However, when I visit the homepage, the page doesn't get rendered to begin with.

Help or advice would be very much appreciated, thank you again.

urls.py

urlpatterns = [
url(r'^$', exp_view.DrugListView.as_view() , name = 'drug_list')]

here is my CBV template:

views.py

class DrugListView(ListView):
context_object_name = 'drugs'
model = Drug
template_name = 'expirations/drug_list.html'

def get(self, request):
    if self.request.is_ajax():
        text_to_search = self.request.GET.get('searchText')
        print(text_to_search)
        return render(request, "expirations/list.html", {'drug':Drug.objects.filter(name__contains = text_to_search).order_by('name')})
    else:
        return render(request, "expirations/list.html", {'drug':Drug.objects.all().order_by('name')})

here is drug_list.html

{% extends 'expirations/index.html' %}

{% block content %}

{% include 'expirations/list.html' %}

{% endblock %}
{% block javascript %}
<script>
$(document).ready(function(){
  var input = $("#searchText")
    input.keyup(function() {
    $.ajax({
      type: "GET",
      url: "{% url 'drug_list' %}",
      data: {'searchText' : input.val()},
      success: function(data){
        $("#list_view").load("expirations/list.html")
        }
    })
    });
})
</script>
{% endblock %}

here is list.html:

{% for drug in drugs %}
    <div class = '.col-sm-12'>
        <ul class = 'list-group'>
            <li class = "list-group-item" >
              <span class = "badge">First Expiration: {{ drug.early_exp|date:"l M d Y" }}</span>
              <a href="{% url 'drug_detail' pk=drug.pk %}">{{ drug.name }}</a>
              {% regroup drug.expiration_dates.all by facility as facility_list %}
              {% for x in facility_list %}
              <span class="label label-info">{{ x.grouper }}</span>
              {% endfor %}
            </li>
        </ul>
    </div>
{% endfor %}
hpca01
  • 370
  • 4
  • 15

3 Answers3

1

You've misunderstood what you need to do in your success callback.

That function has no access to Django templates. But it doesn't need to, because Django has already sent the fragment in the response, which is available in the data parameter. You just need to insert that into the existing page.

For that you'll need a container; so you should modify your drug_list.html so that there is a div around the include:

{% block content %}

<div id="list_contents">
  {% include 'expirations/list.html' %}
</div>

{% endblock %}

and now your success function can be:

  success: function(data) {
    $("#list_contents").html(data)
 }
Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
0

I do not think that it will work this way. For Ajax calls and CBV look at example in the docs.

Then you would need to return the new, filtered data (in html format) to the ajax call and replace the html in the sucess function via JS.

ger.s.brett
  • 3,267
  • 2
  • 24
  • 30
0

Daniel Roseman definitely helped solve the puzzle, here is the updated code:

views.py: updated if/else statement to include a default list view of the general template. also added the context name 'drugs' instead of 'drug'

class DrugListView(ListView):
    context_object_name = 'drugs'
    model = Drug
    template_name = 'expirations/drug_list.html'

    def get(self, request):
        if self.request.is_ajax():
            text_to_search = self.request.GET.get('searchText')
            print(text_to_search)
            return render(request, "expirations/list.html", {'drugs':Drug.objects.filter(name__contains = text_to_search).order_by('name')})
        else:
            return render(request, "expirations/drug_list.html", {'drugs':Drug.objects.all().order_by('name')})

drug_list.html: changed success callback function load html as suggested by daniel.

{% extends 'expirations/index.html' %}

{% block content %}
  <div id = 'list_view'>
  {% include 'expirations/list.html' %}
  </div>
{% endblock %}
{% block javascript %}
<script>
$(document).ready(function(){
  var input = $("#searchText")
    input.keyup(function() {
    $.ajax({
      type: "GET",
      url: "{% url 'drug_list' %}",
      data: {'searchText' : input.val()},
      success: function(data){
        $("#list_view").html(data)
        }
    })
    });
})
</script>
{% endblock %}
hpca01
  • 370
  • 4
  • 15