Reputation: 127
I am trying to the table in my all-reviews whenever someone checks one of the filters at the top using ajax. However, when a filter is checked it is getting the entire page back including things like the navbar and then updating the table with the entire page data instead of just the filtered reviews. The issue I believe is with my view since its rendering the all-reviews.html page but I cannot figure out how to do it properly where the returned data doesn't include the navbar and other unneeded information that is imported into my base.html. Lastly, I am trying to make it so that if they click a filter, it loads the new data, but then if they uncheck the filter, or check a different one the data is refreshed again. Currently after the first time a filter is checked nothing happens if subsequent filters are checked or unchecked.
base.html
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>{% block title %}{% endblock %}</title>
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<link rel="stylesheet" href="{% static "app.css" %}" />
{% block css_files %}{% endblock %}
</head>
<body id="page">
{% include "./includes/navigation.html" %}
{% block content %}
{% endblock %}
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.js" integrity="sha512-n/4gHW3atM3QqRcbCn6ewmpxcLAHGaDjpEBu4xZd47N0W2oQ+6q7oc3PXstrJYXcbNU1OHdQ1T7pAP+gi5Yu8g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
{% block js_files %}{% endblock %}
</body>
</html>
all-reviews.html
{% extends "base.html" %}
{% load static %}
{% block title %}
All Reviews
{% endblock %}
{% block css_files %}
<link rel="stylesheet" href="{% static "trading_log/all-reviews.css"%}"/>
{% endblock %}
{% block content %}
<div class="container-fluid">
<div id="filters">
<form id="filters_form" class="" action="" method="GET">
<input type="checkbox" id="macd_filter" name="filters" value="macd_filter" onchange="triggerFilterFormSubmit()">
<label for="macd_filter">MACD</label>
<input type="checkbox" id="rsi_filter" name="filters" value="rsi_filter" onchange="triggerFilterFormSubmit()">
<label for="rsi_filter">RSI</label>
</form>
</div>
<table class="table table-striped table-hover" id="review_data">
<thead class="thead-dark">
<tr>
<th class="" scope="col">Review #</th>
<th class="" scope="col">Associated Trade</th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
{% for review in reviews %}
{% include "trading_log/includes/review.html" %}
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}
{% block js_files %}
<script src="{% static "trading_log/filters.js" %}"></script>
{% endblock %}
review.html
{% if review %}
<tr data-toggle="collapse" data-target="#accordion{{review.id}}" class="clickable">
<th scope="">{{ review.id }}</th>
<td class="">{{ review.trade_id.id }}</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td class="text-center accordian-container" colspan="8" style="padding-bottom: 0px;padding-top: 0px;">
<div id="accordion{{review.id}}" class="collapse">
{% include "trading_log/includes/review-card.html" %}
</div>
</td>
</tr>
{% endif %}
filters.js
function triggerFilterFormSubmit() {
$.ajax({
type: "GET",
url: $('#filters_form').attr('action'),
data: $('#filters_form').serialize(),
success: function(data){
$("#page").html(data)
console.log(data)
}
});
};
views.py
class AllReviewsView(ListView):
model = Review
def get(self, request):
user_id = request.user.id
filters = request.GET.getlist("filters")
filtered_reviews = []
reviews = Review.objects.filter(user_id=user_id)
if filters:
for filter in filters:
for review in reviews:
if review.nine_min_potential_macd_div:
filtered_reviews.append(review)
else:
filtered_reviews = self.get_queryset().filter(user_id=user_id)
context = {
"reviews": filtered_reviews
}
return render(request, "trading_log/all-reviews.html", context)
Upvotes: 2
Views: 2697
Reputation: 1118
Don't use .load() in jquery. There is a better way using django's built in render_to_string method along with jquery ajax. Unlike .load() it's incredibly fast.
Consider the following very simple example to inject or refresh part of your page with django/ajax/jquery. Building on this simple example you can create some complex and robust ajax interactions.
views.py
from django.http import JsonResponse
from django.template.loader import render_to_string
def inject_some_content(request):
data = dict()
context = {'my_context': 'some_context'}
data['my_content'] = render_to_string('app_name/injected_content.html',
context, request=request)
return JsonResponse(data)
urls.py
from django.urls import path
from .views import inject_some_content
urlpatterns = [
path('inject-some-html/', inject_some_content, name='inject_some_content'),
[
your_page.html
<div id="target-div"> <!-- your content gets put here by ajax --> </div>
<button type="button" class="load-content" href="{% url 'inject_some_content' %}">Click Me</button>
<script>
var loadThisContent = function () {
var btn = $(this);
$.ajax({
url: btn.attr("href"),
dataType: 'json',
success: function (data) {
$('#target-div').html(data.my_content);
}
}
)
};
$('.load-content').on('click', loadThisContent);
</script>
injected_content.html
<h1>Hello World!! I just got put here by Ajax! Here is {{my_context}}!</h1>
Lastly, as long as you are using the ajax method in Jquery, avoid including the minified version of the jquery library, which for some unexplained reason drops the ajax method.
Upvotes: 3
Reputation: 1119
You need to use load()
. Manage your code with if statements.
(logic is if (filter_2.clicked){ $('#colTwo').load(your_page_url + ' #colTwo');}
)
Filter.js:
function triggerFilterFormSubmit() {
$.ajax({
type: "GET",
url: $('#filters_form').attr('action'),
data: $('#filters_form').serialize(),
success: function(data){
$("#page").html(data)
$('#filter_result').load(your_page_url + '#filter_result');
console.log(data)
}
});
};
Upvotes: 1