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 >
<div id="filters">
<form id="filters_form" 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 id="review_data">
<thead >
<tr>
<th scope="col">Review #</th>
<th 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}}" >
<th scope="">{{ review.id }}</th>
<td >{{ 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 colspan="8" style="padding-bottom: 0px;padding-top: 0px;">
<div id="accordion{{review.id}}" >
{% 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)
CodePudding user response:
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)
}
});
};
CodePudding user response:
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()
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" 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!</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.