HTML Button is non-responsive, console doesn't register event - javascript

Working on a simple to-do app, but having a problem with the delete button. When I click, the browser console doesn't even register an event. Super confused on what to do here. I've gone through all my code in index.html as well as the app.py code, I can't figure out why it's not even registering in the browser that something happened, even if it doesn't lead to what I want it to do. Basically just not sure how to debug something that's not even registering as existing I guess?
I'm assuming it's a problem in the HTML but just in case, I'm including the relevant python code as well.
Thanks!
index.html
<ul id="todos">
{% for d in data %}
<li><input class="check-completed" data-id="{{ d.id }}"
type="checkbox" {% if d.completed %} checked {% endif %}> {{ d.description }}
<button class="li button deletebutton" data-id="{{ d.id }}">&cross;</button> <!-- &cross; is HTML for an X-->
</li>
{% endfor %}
</ul>
script in index.html:
const deletebtns = document.querySelectorAll('.deletebutton');
for (let i = 0; i < deletebtns.length; i++) {
const deletebutton = deletebtns[i];
deletebutton.onclick = function(e) {
const todoId = e.target.dataset['id'];
fetch('/todos/' + todoId, {
method: 'DELETE',
})
}
}
}
app.py:
#app.route('/todos/<todo_id>', methods=['DELETE'])
def delete_todo(todo_id):
try:
Todo.query.filter_by(id=todo_id).delete()
db.session.delete(todo)
db.session.commit()
except:
db.session.rollback()
finally:
db.session.close()
return redirect(url_for('index'))

Related

Using Javascript to change text Content of a button

Hey guys I'm creating a social media messaging app and right now I'm on the basics of creating a button to follow people.
When you click the button, it should change the button from saying "Follow" to "UnFollow". Then the counter for Followers should go up by 1.
So far this is my code and it's not doing anything. I'm not getting any errors but it's also not doing anything at all.
Can someone figure out what I'm doing wrong? Thanks
network.js:
document.addEventListener('DOMContentLoaded', function() {
document.getElementById('followButton').addEventListener('click', () => follow_user());
});
function follow_user() {
const element = document.getElementById('followButton');
element.value = "Un-Follow";
const element2 = document.getElementById('followers');
element2.textContent += 1;
}
profile.html :
{% extends "network/layout.html" %}
{% block body %}
<h2>{{user.username}}'s Profile</h2>
<p id="followers">Followers: {{user.followers}}</p>
<p>Follows: {{user.follows}}</p>
{% for newquery in newqueries reversed %}
<div class="newpost"><p>{{ newquery.body }}</p><p>By: {{ newquery.username }} on: {{ newquery.timestamp }} Likes: {{ newquery.likes }}</p></div>
{% endfor %}
<input type="button" value="Follow" id="followButton">
{% endblock %}
Your first problem is your follower count does not have an ID. You are trying to target it with #followers, but it only has a class .followers.
Your second problem is button inputs don't display textContent. They display their value.
const element = document.getElementById('followButton');
element.value = "Un-Follow";
Try something like this: const element = document.getElementById("followButton").value="Un-Button Follow" i think the value should be Button in between the un and follow i.e un-follow, Note(change it to suit your code)
Check this article here: https://www.permadi.com/tutorial/jsInnerHTMLDOM/index.html

Can't process ajax call on my page because Django request.is_ajax returns True when page is intially loaded

I have a page that makes ajax calls, and my view checks if the call is ajax with .is_ajax function. However, when the page is initially loaded (for example if I stop running the server and then restart it) the is_ajax function seems to return True, which causes a MultiValueDictKeyError at /alltext, because the request does not contain the key "alltext", which contains the data from my other ajax call.
The page is a e-commerce product page, and the product has different variants (i.e. size and color), and when the user chooses variants from a dropdown menu (i.e. Large, Blue), it makes an ajax call to the backend to retrieve the price of this specific variant from the database.
Here is my code:
views.py
def product_info(request):
if request.method == "GET" and not request.is_ajax: # this is supposed to be loaded on page load
return render(request, "product_info.html")
elif request.is_ajax and request.method == "GET":
print(request.is_ajax)
'''When a user chooses a product variant on the page, this makes an ajax call
to retrieve the price of this combination'''
print("request was ajax")
combinations = request.GET["alltext"]
combinations_list = combinations.split(";")
product = Product.objects.all().latest("id")
var_names = Variation.objects.filter(product=product)
corresponding_values = []
for i in range(len(combinations_list)):
# finding this variant in database
var_name = var_names[i]
var_values = VariationValue.objects.filter(variation_name=var_name)
for val_obj in var_values:
val = val_obj.value
if val == combinations_list[i]:
corresponding_values.append(val_obj)
found_price = None
for i in range(len(corresponding_values)):
val = corresponding_values[i]
if i == 0:
combo_query = VariationCombination.objects.filter(variation_value=val)
else:
combo_query = combo_query.filter(variation_value=val)
price = combo_query[0].price
return HttpResponse("You chose: " + combinations + "price: " + price)
And here is the relevant part of the product_info page - the forms where the user chooses the variants and the script that sends the variants to the backend:
product_info.html
<form class="variations-form">
{% for name in variation_names %}
<div class="form-group">
<label class="btn-label">{{ name.variation_name }}:</label>
<!--<button type="button" class="btn btn-danger dropdown-toggle" data-toggle="dropdown">
<span class="selection"></span><span class="caret"></span>
</button>-->
<select name="variation{{ forloop.counter }}" class="form-control variations" id="variation{{ forloop.counter }}">
<option value="" selected disabled>{{ name.variation_name }}</option>
{% for key, value_list in variation_values.items %}
{% if key == name.variation_name %}
{% for value in value_list %}
<option value="{{ value }}">{{ value }}</option>
{% endfor %}
{% endif %}
{% endfor %}
</select>
</div>
<br>
{% endfor %}
</form>
Script tag with ajax call
<script>
$(document).ready(function () {
$('.form-control').change(function(){
if ($('#variation1').val()) {
var valueFrom = $('.variations option:selected').map(function () {
return $(this).val();
}).get();
var alltext = valueFrom.join(";")
$('#chosen-options').html(alltext).show('fast');
$.ajax(
{
type:"GET",
data:{
'action':'options_chosen',
alltext: alltext
},
success: function( data )
{
$('#chosen-options').html(data).show('fast');
}
});
};
});
});
</script>
Still not entirely sure what was wrong but I fixed it! At first, the page was setup so that it loads the template "homepage.html" at first, and then when you click on a product it opens in the same page, by loading the template "product_info.html". So I just changed it so that the product_info opens up on a new page when you click a product (and added the new page to urls.py), and now it works!

How to update a separated element with axios?

My code right now works perfectly fine!
It updates the user status(disable, enable account) without refreshing the page.
Right now if I click to the red button Desactiver it will become green Activer and the same thing in reverse..
What I wanna do is: When I Click to the button the status also get updated (which is in a different <td> )
In my axios code, I tried to get the status element using
const statusText= this.querySelector('span.status11');
and update it using
statusText.textContent=response.data.current;
The problem is that using this.querySelector return null because it is in a different <td>
and this points to a.js-status because on my code i did
document.querySelectorAll('a.js-status').forEach(function(link)
Here is the image
Here is my current code that updates ONLY the button (while i wanna update the button + the status <td>
Controller function:
/**
* #Route("/{id}/status", name="user_status", methods={"GET","POST"})
* #param Request $request
* #param User $user
* #return Response
*/
public function updateStatus(User $user): Response
{
if($user->getStatus()==true){
$user->setStatus(false);
$current="Desactiver";
} else {
$user->setStatus(true);
$current="Activer";
}
$this->getDoctrine()->getManager()->flush();
return $this->json([
'code'=>200,
'message'=>'the Status of is updated',
'current'=>$current
],200);
}
html code :
{% if user.status == 0 %}
Compte est <span class="status11" >Desactiver</span>
{% else %}
Compte est <span class="status11" >Activer</span>
{% endif %}
</td>
<td>
{% if user.status == 1 %}
<button class="btn btn-danger btn-sm">Desactiver</button>
{% else %}
<button class="btn btn-success btn-sm">Activer</button>
{% endif %}
</td>
My axios/javascript code :
{% block javascripts %}
<script src="https://unpkg.com/axios/dist/axios.min.js"> </script>
<script>
function onClickBtnLike(event){
event.preventDefault();
const url = this.href;
const btn= this.querySelector('button');
axios.get(url).then(function(response){
if(btn.classList.contains('btn-danger')) {
btn.classList.replace('btn-danger','btn-success');
btn.textContent="Activer";
}else{
btn.classList.replace('btn-success','btn-danger');
btn.textContent="Desactiver";
}
});
}
document.querySelectorAll('a.js-status').forEach(function(link){
link.addEventListener('click',onClickBtnLike);
})
</script>
{% endblock %}
You can traverse up from the button to the containing row and search for your status span from there:
const status = this.closest('tr').querySelector('.status11');
status.textContent = (status.textContent == "Activer" ? "Desactiver" : "Activer");
You could also target the previous td directly by using this.parentElement.previousElementSibling but the former is clearer and gives you some leeway if you want to change the html structure.

How can I save the return value of a javascript function in a django template variable?

Can anybody help me?
I'm doing comments features in django and I stopped because I don't know how to do this.
My idea is to set a variable value with comment.id for each comment when clicking on the "RESPONDER" button and save it to a django template variable to access it after posting an answer.
The form is displayed when you click on the button, showing the CSS class and the anchor link.
post.html:
{% for comment in comments %}
<input class="blog__answer__reply" type="button" name="comment_parent_id" onclick="comment_parent_id=set_comment_parent_id({{ comment.id|escapejs }})" value="RESPONDER">
{% endfor %}
views.py:
def add_comment(request, post_slug):
try:
comment_parent_id = int(request.POST.get('comment_parent_id'))
except:
comment_parent_id = None
functions.js:
function set_comment_parent_id(comment_id) {
return comment_id
}
SOLVED
post.html:
{% for comment in comments %}
<input class="blog__answer__reply" type="button" name="comment_parent_id" onclick="comment_parent_id=set_comment_parent_id({{ comment.id|escapejs }})" value="RESPONDER">
{% endfor %}
views.py:
def add_comment(request, post_slug):
try:
comment_parent_id = int(request.POST.get('comment_parent_id'))
except:
comment_parent_id = None
functions.js:
function set_comment_parent_id(comment_id) {
return comment_id
}

How to change model variable by onclick function used in template asynchronously (without refreshing explicitly)

I am making a django app where the user can post status'. The list of his previous status' is also showed on the same page with a delete post option against each post. I have added an onclick function to that button which uses ajax calls to change the class variable in models.py. ie. the delete variable in class status_class in models.py changes its value from 0 to 1 after the delete post button is clicked. And then only the posts with delete=1 are showed. Help me modify the delete_post function in the script so that it works as I've mentioned above. Please do mention if any other changes are needed. Thanks.
Models.py
from django.db import models
from django.contrib.auth.models import User
class status_class(models.Model):
username=models.ForeignKey(User)
text=models.CharField(max_length=2000, null=False, blank=False)
pub_date=models.DateTimeField("Published: ")
delete=models.IntegerField(default=0)
def __unicode__(self):
return self.text
Script in template
<script>
function deletepost(id)
{
$.ajax({
url: "/delete_post/",
type: "POST",
data: {'value':id},
success: function(response) {
},
});
}
</script>
URL
url(r'^delete_post/$', 'status.views.deletepost_view', name='deletepost_view'),
View
#csrf_exempt
def deletepost_view(request):
value=request.POST.get("value")
b=User.objects.filter(id=str(value))
#delete change statement
resp=json.dumps(b)
return HttpResponse(resp, content_type="application/json")
Template
{% for i in d %}
<p>{{ i.text }} &nbsp&nbsp&nbsp&nbsp {{ i.pub_date }}
<button type="button" class="btn btn-danger" onclick="deletepost(i.id);"> Delete Post </button></p>
<hr>
{% endfor %}
NOTE: Also help me with this. I want to filter posts and show only that posts having the delete variable equal to 0. ie. that have not been deleted. Where should I write the filter statement?
The changes to the following would work.
View
def deletepost_view(request):
value=request.POST.get("value")
b=status_class.objects.get(id=str(value))
b.delete = 1
b.save()
resp=json.dumps(b)
return HttpResponse(resp, content_type="application/json")
Template
{% for i in d %}
<p>{% if i.delete == 0 %}
{{ i.text }}&nbsp&nbsp&nbsp&nbsp {{ i.pub_date }}
<button type="button" class="btn btn-danger" onclick="deletepost({{ i.id }});"> Delete Post </button>
<hr></p>
{% endif %}
{% endfor %}

Categories