Using ajax and django to delete an item in for loop - javascript

Trying to delete a post/comment by using the bootstrap × on click and fade out. I have some code written up but it isn't working. I feel I am missing something so simple. Any guidance or help would be highly appreciated.
urls.py
url(r'^delete/(?P<pk>\d+)/$', views.delete, name='delete'),
views.py
#login_required
def delete(request, pk):
warn = get_object_or_404(Warning, pk=pk)
fop = get_object_or_404(Followers, pk=warn.person.pk)
warn.delete()
return redirect('yardsale.views.follower_warnings', pk=fop.pk)
template
{% for warns in warn.warnings.all %}
<div class="warning-list col-md-4">
{# <a href="{% url 'delete' pk=warns.pk %}"> #}
<button type="button" class="close">×</button>
{# </a> #}
<div class="publish-date"><strong>Warned:</strong> {{ warns.publish_date }}</div>
<div class="posted-by"><strong>Warned By: </strong> {{ warns.author }}</div>
<div class="warningtype"><strong>Warning Type: </strong>{{ warns.WarningType }}</div>
<div class="description">
<strong>Description:</strong> {{ warns.descript }}
</div>
{% endfor %}
main.js
$(".close").click(function () {
if (confirm("Are you sure you want to delete this?")){
$.ajax({
type: "DELETE",
url: "{% url 'delete' pk=warns.pk %}",
beforeSend: function(xhr) {
xhr.setRequestHeader("X-CSRFToken", getCookie("csrftoken"));
}
success: function() {
var close=$(this).parent();
close.fadeOut(1000);
});
}
})
}
});

The main.js is as follows.
$(".close").click(function () {
var close=$(this).parent();
if (confirm("Are you sure you want to delete this?")){
$.ajax({
type: "DELETE",
url: $(this).data('url'),
beforeSend: function(xhr) {
xhr.setRequestHeader("X-CSRFToken", getCookie("csrftoken"));
},
success: function() {
close.fadeOut(1000);
}
});
}
});

Related

How to call an element in jquery when the ID of the element is stored in a variable?

Template
{% for question, count, is_follow in zipp %}
<div class="border rounded my-2 px-3 py-1" style="box-shadow: 2px 2px 5px #2b6dad;">
<p class="fst-normal">
<small>Tags: </small>
{% for tag in question.tags.all %}
<small><i>{{tag.name}} |</i></small>
{% endfor %}
</p>
<p><a href="{{question.get_absolute_url}}" style="text-decoration: none; color: black"><h5>{{ question.question }}</h5>
<small>Arguments added: {{ count }}</small></a></p>
<div class="blank" id="{{question.question_id}}">
{% include 'snippets/follow_question.html' %}
</div>
<button type="button" class="btn btn-secondary btn-sm mt-1"><i class="fa fa-share-alt" style="padding-right: 3px;"></i>Share</button>
</div>
{% endfor%}
Script
<script type='text/javascript'>
$(document).ready(function(event){
$(document).on('click', '#follow', function(event){
event.preventDefault();
var this_element = $(this)
var pk = $(this_element).attr('value');
$.ajax({
type: 'POST',
url: '{% url 'follow_question' %}',
data: {'id': pk, 'csrfmiddlewaretoken': '{{ csrf_token }}'},
datatype: 'json',
success: function(response){
var id = $(this_element).closest('.blank').attr('id');
$('id').html(response['form']);
},
error: function(rs, e){
console.log(rs.responseText);
},
});
});
});
</script>
Inside the script, the ID of the element is stored in var id. I want to use that ID to change its html as I was trying to do in the next line but it's not working. How can I do that?
You are looking for an associated element to get it's id to use to look for that same element again.
That is redundant when you can just use the reference to the closest element itself
Simplified version:
this_element.closest('.blank').html(response['form'])
Why not
var id = $(this_element).closest('.blank').attr('id');
$(`#${id}`).html(response['form']); // $('#' + id)

Understanding Ajax and adding cart count

website: https://www.fermento24.com
If you add a product to the cart, it'll show you the recently added product, total and possibility to go to cart. What I wanted to add was a count of the sort, like: There are currently another 5 products in the cart.
I tried to use {{ cart.item_count }}, but since the popup works on Ajax it doesn't seem to update on time, only showing me at the first time how many products were in the cart (thus, incorrect informations).
How do I go and implement something like this? What follows under is a test I did based on other answers I found here, but that still didn't work.
<div class="loading-modal modal">{{ 'general.search.loading' | t }}</div>
<div class="newsletter-success-modal">
<div class="modal-overlay"></div>
<div class="ajax-modal-content">
<a class="close close-window btn" title="{{ 'general.password_page.close' | t }}">
<i class="fa fa-times"></i>
</a>
<i class="fa fa-check" aria-hidden="true"></i>
<span>{{ 'general.newsletter_form.mailing_list_success_message' | t }}</span>
</div>
</div>
<div class="ajax-error-modal modal">
<div class="modal-inner">
<div class="ajax-error-title">{{ 'general.search.error' | t }}</div>
<div class="ajax-error-message"></div>
</div>
</div>
<div class="ajax-success-modal modal">
<div class="overlay"></div>
<div class="content">
<div class="ajax-left">
<p class="added-to-cart info">{{ 'cart.general.added_to_cart' | t }}</p>
<p class="added-to-wishlist info">{{ 'products.wishlist.added_to_wishlist' | t }}</p>
<img class="ajax-product-image" alt="modal window" src="/" />
<div class="ajax-cart-desc">
<h3 class="ajax-product-title"></h3>
<span class="ajax_price"></span>
<p>{{ 'cart.general.qty' | t }}: <span class="ajax_qty"></span></p>
</div>
</div>
<div class="ajax-right">
<div>Totale nel carrello: <span class="ajax_cartTotal"></span><br>
<span class="cart-item-count"> </span>
</div>
<button class="btn continue-shopping" onclick="javascript:void(0)">{{ 'cart.general.continue_shopping' | t }}</button>
<div class="success-message added-to-cart"><i class="fa fa-shopping-cart"></i>{{ 'cart.general.view_cart' | t }} </div>
</div>
<i class="fa fa-times-circle"></i>
</div>
</div>
<script type="text/javascript">
$(function(){
var cartCount = {{ cart.item_count }};
$('.varients-item').on('click', function(){
var obj = $(this);
$.ajax({
type: 'POST',
url: '/cart/add.js',
data: {
quantity: 1,
id: $(this).attr("data-variant")
},
dataType: 'json',
success: function (data) {
$.ajax({
type: 'GET',
dataType: 'json',
url: '/cart.json',
success: function(cart){
cartCount++;
$('.cart-item-count').html(cartCount);
}
});
}
});
});
});
</script>
You need to update the code and your JS code is looks like similar to demo code below:
$(function(){
$('.varients-item').on('click', function(){
var obj = $(this);
$.ajax({
type: 'POST',
url: '/cart/add.js',
data: {
quantity: 1,
id: $(this).attr("data-variant")
},
dataType: 'json',
success: function (data) {
$.ajax({
type: 'GET',
dataType: 'json',
url: '/cart.js',
success: function(cart){
// once you get the data from AJAX API you need to get the latest count
let total = cart.item_count;
$('.cart-item-count').html(total);
}
});
}
});
});
});
Here is the reference for the cart.js over Shopify documentation.
Link

Passing different URL parameters to AJAX function in Django

How to pass the different URL names to the javascript function. Here are my HTML and Javascript code.
{% for profile, g_name in group_list %}
<li class="contact">
<div class="wrap">
<img src="{{profile}}" alt="No image" />
<div class="meta">
<input type="hidden" id="myGroup" name="myGroup" value="{{g_name}}">
<button onclick="GetMessages()">
<p class="name">{{g_name}}</p>
</button>
</div>
</div>
</li>
{% endfor %}
<script>
function GetMessages() {
var myGroup = document.getElementById('myGroup').value;
$('.ajaxProgress').show();
$.ajax({
type: "GET",
url: "/getmsgs/"+myGroup,
success: function(response){
$("#display").empty();
...
},
error: function(response){
alert("No Data Found");
}
});
}
</script>
and this is my URL
path('getmsgs/<str:word>/', views.groupmsgs_ajax, name='groupmsgs_ajax'),
when I try the above method I am getting the first 'myGroup' id value. it is passing the first group name by default.
I am not able to call other group names.
Thank you for any help
That is because all input elements have the same id myGroup so document.getElementById('myGroup').value get always the first element value.
The following code changes should solve the issue given that g_id exists and is a string
{% for profile, g_name, g_id in group_list %}
<li class="contact">
<div class="wrap">
<img src="{{profile}}" alt="No image" />
<div class="meta">
<input type="hidden" id="{{g_id}}" name="{{g_id}}" value="{{g_name}}">
<button onclick="GetMessages({{g_id}})">
<p class="name">{{g_name}}</p>
</button>
</div>
</div>
</li>
{% endfor %}
<script>
function GetMessages(id) {
var myGroup = document.getElementById(id).value;
$('.ajaxProgress').show();
$.ajax({
type: "GET",
url: "/getmsgs/"+myGroup,
success: function(response){
$("#display").empty();
...
},
error: function(response){
alert("No Data Found");
}
});
}
</script>
Or pass the name directly to GetMessages function
{% for profile, g_name, g_id in group_list %}
<li class="contact">
<div class="wrap">
<img src="{{profile}}" alt="No image" />
<div class="meta">
<button onclick="GetMessages({{g_name}})">
<p class="name">{{g_name}}</p>
</button>
</div>
</div>
</li>
{% endfor %}
<script>
function GetMessages(myGroup) {
$('.ajaxProgress').show();
$.ajax({
type: "GET",
url: "/getmsgs/"+myGroup,
success: function(response){
$("#display").empty();
...
},
error: function(response){
alert("No Data Found");
}
});
}
</script>

how to display comments with ajax submit call on the same post detail page

I am trying to display user comments after they click on the comment submit button. I added an ajax call on my comment section. However when i click on the submit button after writing a comment, Page is not refreshing but it is not displaying the new comment right away. Only after i refresh the page my new comment is available. I want to display new comment on the page right after clicking the submit button without reloading the page.
I am unable to figure out what is going wrong here, my codes are as follow:
at the end of base.html
<script>
$(document).on('submit', '.comment-form', function(event){
event.preventDefault();
console.log($(this).serialize());
$.ajax({
type: 'POST',
url: $(this).attr('action'),
data: $(this).serialize(),
datatype: 'json',
success: function(response) {
$('.main-comment-section').html(response['form']);
},
error: function(rs, e) {
console.log(rs.responseText);
},
});
});
in post_detail.html, i am calling comment_section.html using the following
<div class="main-comment-section">
{% include 'webpage/comment_section.html' %}
</div>
My comment_section.html
<h1>New comment</h1>
<form method="post" class="comment-form" action=".">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="submit" class="save btn btn-outline-success">
</form>
{{ comments.count }} Comments</h3>
<!-- comments -->
{% for comment in comments %}
<article class="media comment">
<img class="rounded-circle article-img" src="{{ comment.author.profile.image.url }}">
<div class="media-body">
<div class="article-metadata">
<a class="mr-2" href="{% url 'user-profile' comment.author.username %}">{{ comment.author.first_name }} {{ comment.author.last_name }}</a>
<small class="text-muted">{{ comment.created_date }}</small>
</div>
<p class="article-content" "mr-4">{{ comment.content | linebreaks }}</p>
</div>
</article>
<div class="row">
<div class="col-1"></div>
<div class="col-10">
<div class="reply">
<div class="form-group row">
<form method="POST">
{% csrf_token %}
<input type="hidden" name="{{ comment_id }}" value="{{ comment.id }}">
{{ comment_form.as_p }}
<button type="submit" class="save btn btn-default">Comment</button>
</form>
</div>
</div>
</div>
</div>
{% empty %}
<pclass="article-content" "mr-4"> No comments here yet :(</p>
{% endfor %}
views.py
class PostDetailView(FormMixin,DetailView):
model = Post
context_object_name = 'post'
slug_url_kwarg = 'slug'
slug_field = 'slug' # DetailView's default value: optional
form_class = CommentForm
def get_success_url(self):
return reverse('post-detail', kwargs={'slug': self.object.slug})
def get_context_data(self, *args, **kwargs):
slug = self.kwargs.get("slug")
post = get_object_or_404(Post, slug=slug)
comments= Comment.objects.filter(post=post)
context = super(PostDetailView,self).get_context_data()
context['form'] = CommentForm(initial={'post': self.object, 'author': self.request.user})
context["comments"] = comments
context["post"] = post
return context
if self.request.is_ajax():
html = render_to_string('webpage/comment_section.html', context, request=self.request)
return JsonResponse({'form': html})
def post(self, request, *args, **kwargs):
self.object = self.get_object()
form = self.get_form()
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
def form_valid(self, form):
form.save()
return super(PostDetailView, self).form_valid(form)
form.py
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ['author','content', 'post']
widgets = {
'content' : forms.Textarea(attrs={'class':'form-control', 'placeholder' : 'Write a comment here', 'rows':'4', 'cols': '50'}),
'author' : forms.TextInput({'class':'form-control', 'value':'', 'id':'Idspacename', 'type':'hidden'}),
'post' : forms.TextInput({'class':'form-control', 'value':'', 'id':'Idspacename', 'type':'hidden'}),
}
and urls.py
path('post/<slug:slug>/', PostDetailView.as_view(), name='post-detail'),
Please help. Thanks in advance!
I will answer on the javascript part, first you need to create wrapper for the comment list. If you get the response from success you can append the element into the wrapper.
$.ajax({
method: 'POST',
url: your_url,
data: your_data,
success(function(response) {
const comment_list = document.getElementById('comment_list');
const _el = document.createElement('article');
_el.setAttribute('class', 'media comment');
const _elImg = document.createElement('img');
_elImg.setAttribute('class', 'rounded-circle article-img')
_elImg.setAttribute('src', response.author.profile.image.url);
const mediaBody = document.createElement('div');
mediaBody.setAttribute('class', 'media-body');
const metaData = document.createElement('div');
metaData.setAttribute('class', 'article-metadata');
metaData.innerHTML = '<a class="mr-2" href="url_to_profile' + response.author.username '">' + response.author.first_name + response.author.last_name '</a><small class="text-muted">' + response.created_date + '</small>';
const commentContent = document.createElement("p");
commentContent.setAttribute("article-content mr-4");
commentContent.innerHTML = response.content;
mediaBody.appendChild(metaData);
mediaBody.appendChild(commentContent);
_el.appendChild(_elImg);
_el.appendChild(mediaBody);
})
})
<div id="comment_list">
<!-- foreach starting here and loop this below element -->
<article class="media comment">
<img class="rounded-circle article-img" src="{{ comment.author.profile.image.url }}">
<div class="media-body">
<div class="article-metadata">
<a class="mr-2" href="{% url 'user-profile' comment.author.username %}">{{ comment.author.first_name }} {{ comment.author.last_name }}</a>
<small class="text-muted">{{ comment.created_date }}</small>
</div>
<p class="article-content" "mr-4">{{ comment.content | linebreaks }}</p>
</div>
</article>
<!-- end foreach -->
</div>

AJAX call is triggered only in the first link and not in any other links inside a for loop

I have an issue in implementing AJAX call for all the links inside for loop in Python Flask application.
Only the first link triggers AJAX call and no other links triggers AJAX call.
Below is the code of the respective .html and .js file I have implemented.
.html
{% for article in articles %}
{% if article._id in likes %}
<button data-toggle="tooltip" title="Unlike" id="unlike-button" value="{{article._id}}"><span id="user-like-recommend" class="glyphicon glyphicon-heart" aria-hidden="true"></span></button>
{% else %}
<button data-toggle="tooltip" title="Like" id="like-button" value="{{article._id}}"><span id="user-like-recommend" class="glyphicon glyphicon-heart-empty" aria-hidden="true"></span></button>
{% endif %}
{% endfor %}
.js
document.getElementById("like-button").addEventListener("click", function(e) {
e.preventDefault();
var article = $('#like-button').val();
var data = {"article": article};
console.log(data);
if(data){
$.ajax({
type: 'POST',
contentType: 'application/json',
url: '/article_liked',
dataType : 'json',
data : JSON.stringify(data),
success: function (response) {
success("Article was successfully liked.");
}
What should I do to fix this issue?
Change the ids into classes, ids must be unique
{% for article in articles %}
{% if article._id in likes %}
<button data-toggle="tooltip" title="Unlike" class="unlike-button" value="{{article._id}}"><span id="user-like-recommend" class="glyphicon glyphicon-heart" aria-hidden="true"></span></button>
{% else %}
<button data-toggle="tooltip" title="Like" class="like-button" value="{{article._id}}"><span id="user-like-recommend" class="glyphicon glyphicon-heart-empty" aria-hidden="true"></span></button>
{% endif %}
{% endfor %}
js:
$(".like-button").on("click", function(e) {
e.preventDefault();
var article = $(this).val();
var data = {"article": article};
console.log(data);
if(data){
$.ajax({
type: 'POST',
contentType: 'application/json',
url: '/article_liked',
dataType : 'json',
data : JSON.stringify(data),
success: function (response) {
success("Article was successfully liked.");
}

Categories

Resources