I have a Lecture model which contains lectures. For each lecture I have a title and a content and eventually some files. I was trying to make that when somebody presses on a title, the title and the content will display under, but only for that lecture. Problem is that if I use a class, all lectures will be shown and if I use and id only the first one will be shown. How should I do this ?
$('#title').click(function () {
$('#lecture-hide').toggle();
});
{% for c in category.list %}
<div id="title">
<p>Lecture {{ forloop.counter }}: <span>{{ c.lecture_title }}</span>
</p>
<br>
</div>
<div id="lecture-hide" style="display: none;">
<br>
<li><h5>{{ c.lecture_title }}</h5></li>
<li><p>{{ c.content }}</p></li>
{% for file in c.files.all %}
{% if file.files %}
{% if forloop.first %}
<p id="files">Lecture files:</p>
{% endif %}
<li><a class="media"
href='{{ MEDIA_URL }}{{ file.files.url }}'><i
class="fas fa-download"></i>{{ file.files.name }}</a></li>
{% endif %}
{% endfor %}
<br>
</div>
{% endfor %}
Maybe you can use next selector in your jQuery code like this:
$('div.title').click(function () {
$(this).next().toggle();
});
You have to change id of the title to class to apply this to every element of the list.
You need to set dynamic attributes in your html:
{% for c in category.list %}
<div class="title" id="title-{{ c.id }}">
<!-- the content -->
</div>
<div class="lecture-hide" for="title-{{ c.id }}" style="display: none;">
<!-- the content -->
</div>
{% endfor %}
and in JQuery
$('.title').click(function () {
$('.lecture-hide[for="title-' + $(this).attr('id') + '"]').toggle();
});
This will works even if the html elements order change.
Related
I am trying to implement for loop in my accordion. Everything seems to be fine except the fact that when I click on 3rd or 4th button then other bodies stay expanded. It should work exactly the same as in the first example in Bootstrap documentation so if you click on Accordion Item #2 then Accordion Item #1 and Accordion Item #3 collapse.
I am sure that the issue is with my {% if forloop.first %} but I am not sure how can I dynamically change that so it will collapse all accordion contents except active one.
My code:
{% for category in top_categories %}
<div class="accordion" id="accordionExample">
<div class="accordion-item">
<h2 class="accordion-header" id="heading{{category.id}}">
<button class="accordion-button" type="button" data-bs-toggle="collapse"
data-bs-target="#collapse{{category.id}}" aria-expanded="false" aria-controls="collapse{{category.id}}">
{{category.title}}
</button>
</h2>
<div id="collapse{{category.id}}" class="accordion-collapse {% if forloop.first %} show {% else %} collapse {% endif %}" aria-labelledby="heading{{category.id}}"
data-bs-parent="#accordionExample">
<div class="accordion-body">
{% for qa in category.qa.all|slice:"0:3" %}
Q: {{qa}}<hr>
{% endfor %}
</div>
</div>
</div>
</div>
{% endfor %}
I think that the main problem is that you are including <div class"accordion" id="accordionExample"> inside the loop. A secondary one is that the "collapse" class is also necessary for the first iteration. Try this:
<div class="accordion" id="accordionExample">
{% for category in top_categories %}
<div class="accordion-item">
<h2 class="accordion-header" id="heading{{category.id}}">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapse{{category.id}}" aria-expanded="true" aria-controls="collapse{{category.id}}">
{{category.title}}
</button>
</h2>
<div id="collapse{{category.id}}" class="accordion-collapse collapse {% if forloop.first %}show{% endif %}" aria-labelledby="heading{{category.id}}" data-bs-parent="#accordionExample">
<div class="accordion-body">
{% for qa in category.qa.all|slice:"0:3" %}
Q: {{qa}}<hr>
{% endfor %}
</div>
</div>
</div>
{% endfor %}
</div>
I'm using jinja2 template with Flask and MongoDB and I need to display users' cars in a template.
I was able to render cars in the profile template with car information and buttons to edit or delete a car. The problem is that if a user has multiple cars, only the first DELETE CAR button actually works (where I have an include modals to confirm) but nothing happens when click on the second or third delete button. Apparently I duplicated the id that needs to be unique. But I cannot achieve the results.
Here is my template: profile.html
{% extends 'layout/base.html' %}
{% block content %}
{% include 'components/navigation/navigation.html' %}
<div class="container">
<div class="row g-3 justify-content-center">
<div class="col-6 mt-5">
<div class="card">
<div class="card-body">
<h3 class="text-center profileHeader">
{{ username }}'s profile
</h3>
</div>
</div>
</div>
</div>
<div class="row row justify-content-center mt-4">
{% for car in cars %}
{% if session.user|lower == car.created_by|lower %}
<div class="card mb-3" style="max-width: 840px;">
<div class="row g-0">
<div class="col-md-4">
<img src="{{ car.car_image }}" class="imgCard" alt="ferrari image">
</div>
<div class="col-md-8">
<div class="card-body">
<ul class="list-group list-group-flush">
<li class="list-group-item"><strong>Year</strong>: {{ car.car_year }} </li>
<li class="list-group-item"><strong>Name</strong>: {{ car.car_name }}</li>
<li class="list-group-item"><strong>Designer</strong>: {{ car.car_design }}</li>
</ul>
<ul class="list-group list-group-flush">
<li class="list-group-item"><strong>Engine</strong>: {{ car.spec_engine }}</li>
<li class="list-group-item"><strong>Power</strong>: {{ car.car_power }}</li>
<li class="list-group-item"><strong>Trasmission</strong>: {{ car.trasmission }}</li>
<li class="list-group-item"><strong>Races</strong>: {{ car.races }}</li>
<li class="list-group-item"><strong>Wins</strong>: {{ car.wins }}</li>
<li class="list-group-item"><strong>Podiums</strong>: {{ car.podiums }}</li>
<li class="list-group-item"><strong>Poles</strong>: {{ car.poles }}</li>
<li class="list-group-item"><strong>Fast Laps</strong>: {{ car.fast_laps }}</li>
<li class="list-group-item"><strong>Constructor Championship</strong>: {{
car.constructor_champ
}}</li>
<li class="list-group-item"><strong>Driver Championship</strong>: {{ car.drivers_champ }}
</li>
<li class="list-group-item"><strong>Description</strong>: {{ car.description }}</li>
<p><em>by: {{ car.created_by }}</em></p>
</ul>
<div class="d-grid gap-2 d-md-flex justify-content-md-end">
<a id="myBtn" class="btn btn-danger"><i class=" fas fa-trash-alt"></i> Delete</a>
<a href="{{ url_for('editcar', car_id=car._id) }}" class="btn btn-danger" id="edit-btn"><i
class="far fa-edit"></i> Edit</a>
{% with car_id=car._id %}
{% include 'components/modals/confirm.html' %}
{% endwith %}
</div>
</div>
</div>
</div>
</div>
{% endif %}
{% endfor %}
</div>
enter code here
</div>
{% endblock %}
Just make unique the tag id of delete button, so the trigger will be unique in every button. How to make unique ? just add the car._id on tag id
<a id="myBtn-{{car._id}}" class="btn btn-danger"><i class=" fas fa-trash-alt"></i> Delete</a>
As #Darn pointed out, your ids need to be unique. But that is not the cause of your issue here.
I assume you have some Javascript code that gets triggered when user clicks on the delete link. The issue is probably from how that code is being triggered. The code needs to be written in such a way that it is bound to dynamically generated elements (you're generating the delete links on the fly i.e. afte the code for the delete was already bound; that delete code needs to also apply to each element when it is created).
You should bind the delete action to a class e.g.
$(".fa-trash-alt").on("click", function(){
$(this).parent() ...... // this is the link to the instance of the link that was clicked
});
I am trying to use a pagination to paginate one of my pages. I have tried a few different methods I have found online but for some reason, when I use paginate_by = 3, it doesn't actually paginate anything, yet still shows the html for the pagination at the bottom of the page.
View:
class SearchListView(ListView):
model = Post
template_name = "public/search.html"
paginate_by = 3
HTML:
{% extends 'public/base.html' %}
{% load staticfiles %}
{% block head %}
<link rel="stylesheet" type="text/css" href="{% static "public/css/search.css" %}" />
{% endblock %}
{% block content%}
<div class="search container-fluid">
<img src="/media/about-us.jpg" alt="">
<div class="search-title">
<h1 class="title">Search</h1>
</div>
<div class="search-main mb-5">
<form method='GET' action=''>
<input type="text" name='q' class="homebanner-search" placeholder="Enter your keywords" value='{{ request.get.q }}'>
</form>
</div>
</div>
<div class="container mt-5 mb-5">
<div class="detail-container">
{% for post in queryset %}
<a href="{% url 'post-detail' post.slug %}">
<div class="post-main">
<div class="post-image">
<img src="{{ post.image.url }}" class="card-img-top" alt="#">
<p class="post-category">{{ post.category }}</p>
</div>
<div class="post-body">
<div class="post-title">
<p class="post-title-p">Day in the life of {{ post.title }}</p>
</div>
<div class="post-text">
<p class="post-author-text text-muted">{{ post.sub_description|truncatewords:22 }}</p>
</div>
<div class="post-button">
<p>READ MORE ></p>
</div>
</div>
</div>
</a>
{% endfor %}
</div>
<div id="page_navigation" >
{% if is_paginated %}
<ul class="pagination">
{% if page_obj.has_previous %}
<li>«</li>
{% else %}
<li class="disabled"><span>«</span></li>
{% endif %}
{% for i in paginator.page_range %}
{% if page_obj.number == i %}
<li class="active"><span>{{ i }} <span class="sr-only">(current)</span></span></li>
{% else %}
<li>{{ i }}</li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li>»</li>
{% else %}
<li class="disabled"><span>»</span></li>
{% endif %}
</ul>
{% endif %}
</div>
</div>
{% endblock %}
So on the page, 3 items should be showing, and pagination should take me to the the next set of 3. The html is showing, and when I click the links it is taking me 2 page 2. The problem is the fact that 6 items are showing, and not 3, and when I go to page 2, there are the same 6 items there.
Unfortunately I couldn't reproduce your error exactly, but what did happen is that my objects wouldn't render when looping through queryset. So what I would recommend is try to loop through object_list instead:
{% for post in object_list %}
{{ post.name }}
{% endfor %}
Another thing you can do is add a context_object_name argument to your view:
class SearchListView(ListView):
model = Post
template_name = "public/search.html"
paginate_by = 3
context_object_name = 'posts'
and then loop through that:
{% for post in posts %}
{{ post.name }}
{% endfor %}
Also, I can't visualise what the search form is doing on this page since the ListView's model (Post) is the queryset, not whatever is searched for? So perhaps the link href is causing some trouble. Maybe try something like this instead:
<li>«</li>
Again, I could not reproduce the exact problem you are having, which is a shame because I feel like I have had the same issue before, so these are just suggestions pieced together from pagination that works for me and the code you posted. Hope it points you in the right direction.
I am a bit puzzled by the following behavior of the Django templates, which prevents me from successfully styling the output.
Namely, I have the following template:
<article class="article
{% if article.is_featured %} featured{% endif %}
{% if not article.published %} unpublished{% endif %}">
{% if not detail_view %}
<div class="post-preview">
<a href="{% namespace_url 'article-detail' article.slug namespace=namespace default='' %}">
<h2 class="post-title">
{% render_model article "title" "" "" "striptags" %}
</h2>
{% if article.lead_in %}
<h3 class="post-subtitle">
{% if not detail_view %}
{% render_model article "lead_in" "" "" "truncatewords:'20'|striptags" %}
{% else %}
{% render_model article "lead_in" "" "" "striptags" %}
{% endif %}
</h3>
{% endif %}
</a>
<p class="post-meta" style="margin-bottom: 0;"> Posted by
{% include "aldryn_newsblog/includes/author.html" with author=article.author %}
on {{ article.publishing_date|date:"F d, Y" }}
</p>
<p class="post-meta" style="margin: 0">
<h4 style="display:inline-flex">Categories:</h4>
{% for category in article.categories.all %}
{{ category.name }} {% if not forloop.last %}, {% endif %}
{% endfor %}
</p>
<p class="post-meta" style="margin: 0">
<h4 style="display:inline-flex">Tags:</h4>
{% for tag in article.tag %}
{{ tag.name }} {% if not forloop.last %}, {% endif %}
{% endfor %}
</p>
</div>
<hr>
{% endif %}
{% if detail_view %}
<!-- <h3>Testing template! (from article with detail_view=True)</h3> -->
{% render_placeholder article.content language placeholder_language %}
{% endif %}
</article>
The output of this template is roughly like this:
<article class="article">
<div class="post-preview">
<a href="/articles/third-post/">
<h2 class="post-title">
Third Post
</h2>
<h3 class="post-subtitle">
Third post lead-in text.
</h3>
</a>
<p class="post-meta" style="margin-bottom: 0;"> Posted by
<a href="">
</a>
on September 19, 2017
</p>
<p class="post-meta" style="margin: 0">
<h4 style="display:inline-flex">Categories:</h4>
Programming
</p>
<p class="post-meta" style="margin: 0">
<h4 style="display:inline-flex">Tags:</h4>
</p>
</div>
<hr>
</article>
Although the source HTML seems correct, the browser treats it as the following image illustrates.
What am I missing? Is the template incorrect? Or is this a bug I am observing? I tried this in Safari and Firefox. The result is the same.
No, that is just the browser dev tools trying to make sense of your invalid HTML.
An h element cannot go inside a p element.
Check out this answer:
<h1>, <h2>, <h3>... tags, inline within paragraphs (<p>)
They explain it in depth more in there but basically your <h1,2,3,4> tags being embedded in the <p> tags is considered illegal by the browser and is automatically closing the tags. Use a different tag and it should fix your problem.
Hey, dudes i wanna paginate some categories, but when i use autopaginate it always give me a TemplateError. Here is the code that i wanna paginate
<!-- red 1 -->
{% for tpl in cats %}
<div class="clear Vraz10"></div>
<div class="clear">
{% for cat in tpl %}
<div class="left BoxNapravlenie" onclick="location.href='{{ cat.get_absolute_url }}';">
<div class="left"><img src="{% if cat.icon %}{{ cat.icon.url }}{% else %}/media/images/napravlenia/love.gif{% endif %}" style="margin-top: 1px; margin-left: 1px;" title="{{ cat.cms_articles.count }} {% trans "articles" %}" /></div>
<div class="left BoxNapravlenieText">{{ cat }}</div>
</div>
<div class="left razdelitel2"><img src="/media/images/blank.gif" width="35" height="1" /></div>
{% endfor %}
</div>
{% endfor %}
<div class="clear Vraz10"></div>
<div class="OtherSection" onClick="location.href='{{ gencat.get_absolute_url }}';">{{ gencat }}</div>
<div class="clear Vraz10"></div>
I wanna paginate the categories, but i can't ;s And i'm asking for your help :}
It might be possible that you use {% autopaginate %} tag inside of block. Move it out of the {% block %} tag if this is the case.
Everything else can be left as is, just the autopaginate tag doesn't work inside of blocks. It doesn't generate any content so it doesn't matter where you put it.
{% extends ... %}
{% load pagination_tags %}
{% autopaginate .... %}
... other stuff ...