Django-endless-pagination: apply javascript to whole html after "show more"? - javascript

views.py
class PortfolioListView(AjaxListView):
model = Portfolio
context_object_name = "portfolios"
template_name = "portfolios/portfolio_list.html"
page_template = 'portfolios/portfolio_list_page.html'
portfolio_list.html
{% extends "skeleton/base.html" %}
{% load el_pagination_tags %}
{% block content %}
<div class="test-class">
hi-1
</div>
<section>
<div class="container">
<div class="row">
<div class="col-md-offset-1 col-md-10">
{% include page_template %}
</div>
</div>
</div>
</section>
{% endblock %}
{% block custom_js %}
<script src="{% static 'el-pagination/js/el-pagination.js' %}"></script>
<script>$.endlessPaginate({});</script>
<script type="text/javascript">
$(document).ready(function(){
$(".test-class").click(function(){
alert("ji");
});
});
</script>
{% endblock %}
portfolio_list_page.html
<div>
{% lazy_paginate portfolios %}
<div class="test-class">
hi-2
</div>
<div class="test-class">
hi-3
</div>
{% show_more %}
</div>
When I load portfolio_list.html page and click hi-1, it shows alert.
But when I click show more and click hi-2 or hi-3, it doesn't show alert.
I want to show alert even I clicked hi-2 or hi-3.
How can I implement this?
p.s Actually, this is a kinda very simple code for showing clearly what I want to do.
What I eventually want to do is to execute whole javascripts code(e.g _owl_carousel(), _flexslider(), _popover(), _lightbox(), _mixitup(),, etc) after loading portfolio_list_page so that this whole javascript function also can be applied to newly loaded page

Related

Any ideas why error pop up is not interactable when you're not logged in but it's interactable after you logged in on Flask?

If the user is not logged in the popup is not interactable but once the user logs in it can be interacted with, not sure why this actually happens and it doesn't seem like it's a JavaScript problem, couldn't find any solutions to it by searching around. I wonder what could cause this behavior on Flask
HTML + Jinja2 :
<body>
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
{% if category == "soft-error" %}
<div class="toast" id="toast">
<div class="toast-content">
<div class="close-btn">
<a class="wa-close icon-pos" id="close-btn"></a>
</div>
<div class="message">
<div class="text-content">
<p class="text text-1" id="txt-hide">Error</p>
<span class="text text-2" id="txt-hide-2">{{ message }}</span>
</div>
</div>
</div>
</div>
{% endif %}
{% endfor %}
{% endif %}
{% endwith %}
{% block content %}{% endblock%}
</body>
JavaScript :
const closeBtn = document.getElementById('close-btn');
const toast = document.getElementById("toast");
closeBtn.addEventListener('click', () => {
toast.parentNode.removeChild(toast);
});
setTimeout(function() {
toast.parentNode.removeChild(toast);
}, 5000);

Show and hide text of different posts

I have several posts each of them composed of three parts : a title, a username/date and a body. What I want to do is to show the body when I click on either the title or the username/date and hide it if I click on it again. What I've done so far works but not as expected because when I have two or more posts, it only shows the body of the last post even if I click on another post than the last one. So my goal is only to show the hidden text body corresponding to the post I'm clicking on. Here is my code:
{% extends 'base.html' %}
{% block header %}
<h1>{% block title %}Test page{% endblock %}</h1>
<a class="action" href="{{ url_for('main_page.create') }}">New</a>
{% endblock %}
{% block content %}
{% for post in posts %}
<article class="post">
<header>
<script language="JavaScript">
function showhide(newpost)
{var div = document.getElementById(newpost);
if (div.style.display !== "block")
{div.style.display = "block";}
else {div.style.display = "none";}}
</script>
<div onclick="showhide('newpost')">
<h1>{{ post['title'] }}</h1>
<div class="about">by {{ post['username'] }} on {{ post['created'].strftime('%d-%m-%Y') }}</div>
</div>
</header>
<div id="newpost">
<p class="body">{{ post['body'] }}</p>
</div>
</article>
{% if not loop.last %}
<hr>
{% endif %}
{% endfor %}
{% endblock %}
Of course I looked for a solution as much as I could but I'm kind of stuck plus I'm a complete beginner in HTML/JS/CSS. And one last thing, I'm currently using Python's framework Flask. Thank you by advance.
You need to give each of your posts a unique id for your approach to work.
Change your code to
<div id="{{post_id}}">
<p class="body">{{ post['body'] }}</p
</div>
where post_id is that post's unique id e.g. its id in the database you are using that you pass to the template in your view. Then, change the call to the onclick event handler to
<div onclick="showhide('{{post_id}}')">
If you don't have a unique id you can also use the for loop's index: replace all post_id instances above with loop.index. See Jinja's for loop docs for more information.

Django-bootstrap-datepicker-plus is not rendering datepicker properly

I am facing with the problem that my datetimepicker is not loading at all.
Just in my template, the datetime field loads the current date and time when i press the calendar icon as the image shows.
Despite following the installation steps from here : https://pypi.org/project/django-bootstrap-datepicker-plus/ and checking other answers in stackoverflow i did not manage to find the solution.
I think the problem has to do with the imports and their priority.
my template
{% extends 'base.html' %}
{% load render_table from django_tables2 %}
{% load bootstrap4 %}
{% bootstrap_css %}
{% bootstrap_javascript jquery='full' %}
{% block page-title %}Creation of Process Note{% endblock %}
{% block content %}
<div class="row">
<div class="col-md-6 col-xl-6 offset-md-3">
<form class="well" method="post" action="">
{% csrf_token %}
{% bootstrap_form form %}
<br>
{% buttons %}
<button type="submit" class="btn btn-primary">
Submit
</button>
{% endbuttons %}
</form>
{{ form.media }}
</div>
</div>
{% endblock %}
in settings.py
BOOTSTRAP4 = {
'include_jquery': True,
}
In my base.html the appearence of the imports is:
Inside head
<link href="/static/theme/assets/css/bootstrap.min.css" rel="stylesheet" type="text/css">
<script src="/static/theme/assets/js/jquery.min.js"></script>
...
Inside footer
<script src="/static/theme/assets/js/bootstrap.bundle.min.js"></script>
...
my model
class Case_Notes(models.Model):
date_created = models.DateTimeField("Creation Date", null=True,blank=True, default=datetime.datetime.now)
date = models.DateTimeField("Appointment Date", null=True,blank=True)
notes = models.CharField("Notes",max_length=500, blank=True, null=True)
def __str__(self):
return self.notes
my form
class ProcessNotesForm(ModelForm):
notes= CharField(required=False,widget=Textarea(attrs={"rows":5, "cols":20}))
class Meta:
model = Case_Notes
fields = ("date","notes",)
widgets = {
'date': DateTimePickerInput(), # default date-format %m/%d/%Y will be used
}
Why datepicker widget in the form field is not rendering?
According to the documentation, the {{ form.media }} needs to follow right under the {% bootstrap_javascript jquery='full' %} in your template file.
{% load bootstrap4 %}
{% bootstrap_css %}
{% bootstrap_javascript jquery='full' %}
{{ form.media }}
Addition to {{ form.media }} you use tuple instead of an array in the fields Meta in the ModelForm:
class ProcessNotesForm(ModelForm):
notes= CharField(required=False,widget=Textarea(attrs={"rows":5, "cols":20}))
class Meta:
model = Case_Notes
fields = ["date", "notes" ] # change this ("date","notes",)
widgets = {
'date': DateTimePickerInput(), # default date-format %m/%d/%Y will be used
}

jQuery not working after ajax call, even though I'm using the correct on() method

I'm using django-el-pagination, a django package that allows ajax pagination. I'm paginating a queryset of Comment (a list of comments). The queryset is inside comments.html, which is inside comments_base.html, which is inside article.html (the parent view). Here's my views:
def article(request, category, id, extra_context=None):
name = resolve(request.path).kwargs['category']
instance = get_object_or_404(Post, id=id, entered_category=name)
new_comments_list = Comment.objects.filter(destination=id, parent_id=0).order_by('-timestamp')
template = 'article.html'
page_template = 'comments.html'
if request.is_ajax():
template = page_template
context = {
'id': id,
'comment_list': new_comments_list,
'page_template': page_template,
'instance': instance,
}
if extra_context is not None:
context.update(extra_context)
return render(request, template, context)
comments_base.html
{% block comments_base %}
<div class="commentsContainer">
<div class="endless_page_template">
{% include 'comments.html' %}
</div>
{% block js %}
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script src="{% static 'js/el-pagination/js/el-pagination.js' %}"></script>
<script>
$.endlessPaginate({
});
</script>
{% endblock %}
</div>
{% endblock %}
comments.html
{% block comments %}
{% paginate 10 comment_list %}
{% for i in comment_list %}
{% if i.parent_comment %}
<div class="comment_shell hasParent">
{% else %}
<div>
{% endif %}
<div class='comment_div' data-comment_id="{{ i.id }}">
<div class="left_comment_div">
<div class="username_and_votes">
<h3><a class='username_foreign'>{{ i.user }}</a></h3>
{% for j in i.score.all %}
<span class="upvotes">{{ j.upvotes }}</span>
<span class="downvotes">{{ j.downvotes }}</span>
{% endfor %}
</div>
<br>
<p>{{ i.comment_text }}</p>
</div>
</div>
{% include 'comments.html' with comment_list=i.replies.all %}
</div>
{% endfor %}
{% show_pages %}
{% endblock %}
So when I go to the next set of comments in the pagination, jQuery doesn't work. And I assume this is because of it being appended or dynamic content. So I used the on() method which other answers say to do. However it still doesn't work. I'll just show a simple example to show it doesn't work:
$('.upvotes').on('click', function() {
$(this).css('color', '#fff');
});
Doesn't change color onclick. So is there any reason why it still doesn't work, and how can I fix it?
This sounds like an application of jquery's on method overload that uses the additional selector argument:
.on( events [, selector ] [, data ], handler )
From the jquery documentation:
When a selector is provided, the event handler is referred to as delegated. The handler is not called when the event occurs directly on the bound element, but only for descendants (inner elements) that match the selector.
So this should work:
$('body').on('click', '.upvotes', function() {
$(this).css('color', '#fff');
});
Or in place of the 'body' selector use any other element that exists in the DOM at the time that javascript is executed.

Django Infinite scroll using Django Paginate repeating the queryset

Intro: I am using the the below link to add infinite scroll to my project https://simpleisbetterthancomplex.com/tutorial/2017/03/13/how-to-create-infinite-scroll-with-django.html
below is the github code for that link
https://github.com/sibtc/simple-infinite-scroll
The link shows how to add infinite scroll to both function based views and class based views. I have added this to my function based view and it works perfect.
The problem: I have 8 posts in my post-list which is a class-based view. After I add paginate_by = 3 I can only see 3 posts of the 8 posts. Everytime I scroll down these 3 posts keep repeating in an infinite loop
My Views:
class Postlist(SelectRelatedMixin, ListView):
model = Post
select_related = ('user', 'group')
paginate_by = 3
context_object_name = 'post_list'
template_name = 'posts/post_list.html'
def get_queryset(self):
queryset = super(Postlist, self).get_queryset().order_by('-created_at')
query = self.request.GET.get('q')
if query:
queryset = queryset.filter(
Q(title__icontains=query)|
Q(user__username__iexact=query)|
Q(user__first_name__iexact=query)|
Q(user__last_name__iexact=query)
)
return queryset
My Base.html: (I have the below files in JS folder they worked for my FBV)
<script src="{% static 'js/jquery-3.1.1.min.js' %}"></script>
<script src="{% static 'js/jquery.waypoints.min.js' %}"></script>
<script src="{% static 'js/infinite.min.js' %}"></script>
{% block javascript %}{% endblock %}
My post_list.html:
<div class="col-md-8">
<div class="infinite-container">
{% for post in post_list %}
<div class="infinite-item">
{% include "posts/_post.html" %} <!---This code is good---->
</div>
{% empty %}
some code
{% endfor %}
</div>
<div class="loading" style="display: none;">
Loading...
</div>
{% if page_obj.has_next %}
<a class="infinite-more-link" href="?page={{ post_list.next_page_number }}">More</a>
{% endif %}
</div>
{% block javascript %}
<script>
var infinite = new Waypoint.Infinite({
element: $('.infinite-container')[0],
onBeforePageLoad: function () {
$('.loading').show();
},
onAfterPageLoad: function ($items) {
$('.loading').hide();
}
});
</script>
{% endblock %}
In the templates I replaced post_list with page_obj see below code. That did it
{% if post_list.has_next %}
<a class="infinite-more-link" href="?page={{page_obj.next_page_number }}">More</a>
{% endif %}

Categories

Resources