i am working on a project in Django where users can comment on a post. How do i update the comment count of each post, when user comment on a post increases the count to 1. I tried adding the id to div's but nothing happened. How do i implement this?
Home Template:
<!-- Comment count post is an object of all post in homepage -->
<div class="col-4 col-md-4 col-lg-4" id="newfeeds-form">
<a href="{% url 'site:comments' post.id %}" class="home-comment-icon z-depth-0">
<img src="{{ '/static/' }}images/comment.png" width="19" height="19" alt="comment-icon">
{% if post.comments.all|length > 999 %}
<span class="font-weight-bold dark-grey-text" id="number-of-comments">
{{ post.comments.count|floatformat }}
</span>
{% else %}
<span class="font-weight-bold dark-grey-text" id="number-of-comments">
{{ post.comments.count }} Comment{{ post.comments.count|pluralize }}
</span>
{% endif %}
</a>
</div>
<!-- New Feeds Comment Form -->
<div id="newfeeds-form">
{% include 'ajax_newfeeds_comments.html' %}
</div>
Ajax submit comment:
$(document).ready(function() {
$('.feeds-form').on('submit', onSubmitFeedsForm);
$('.feeds-form .textinput').on({
'keyup': onKeyUpTextInput,
'change': onKeyUpTextInput // if another jquery code changes the value of the input
});
function onKeyUpTextInput(event) {
var textInput = $(event.target);
textInput.parent().find('.submit').attr('disabled', textInput.val() == '');
}
function onSubmitFeedsForm(event) {
event.preventDefault();
// if you need to use elements more than once try to keep it in variables
var form = $(event.target);
var textInput = form.find('.textinput');
var hiddenField = form.find('input[name="post_comment"]');
$.ajax({
type: 'POST',
url: "{% url 'site:home' %}",
// use the variable of the "form" here
data: form.serialize(),
dataType: 'json',
beforeSend: function() {
// beforeSend will be executed before the request is sent
form.find('.submit').attr('disabled', true);
},
success: function(response) {
// as a hint: since you get a json formatted response you should better us "response.form" instead of response['form']
$('#newfeeds-form' + hiddenField.val()).html(response.form);
// do you really want to reset all textarea on the whole page? $('textarea').val('');
textInput.val(''); // this will trigger the "change" event automatically
},
error: function(rs, e) {
console.log(rs.resopnseText);
},
complete: function() {
// this will be executed after "success" and "error"
// depending on what you want to do, you can use this in the "error" function instead of here
// because the "success" function will trigger the "change" event automatically
textInput.trigger('change');
}
});
}
});
If you are sure that a new comment will be created with each request, than you can do it with incrementing the count on your desired html element.
I have not worked with python or django so far, but have tried to optimize the code.
<!-- ... -->
<div class="col-4 col-md-4 col-lg-4" id="newfeeds-form">
<span class="font-weight-bold dark-grey-text" id="number-of-comments" data-number="{{ post.comments.count }}">
{% if post.comments.count > 999 %}
{{ post.comments.count|div:1000|floatformat:1 }}k Comments
{% else %}
{{ post.comments.count }} Comment{{ post.comments.count|pluralize }}
{% endif %}
</span>
</div>
<!-- ... -->
function onSubmitFeedsForm(event) {
// ...
$.ajax({
// ...
success: function(response) {
$('#newfeeds-form' + hiddenField.val()).html(response.form);
textInput.val('');
// how you can increment the value of the amount of comments
refreshNumberOfComments();
},
// ...
});
// ...
}
// ...
function refreshNumberOfComments() {
var numberOfCommentsElement = $('#number-of-comments');
var numberOfComments = parseInt(numberOfCommentsElement.data('number')) + 1;
numberOfCommentsElement.data('number', numberOfComments);
if (numberOfComments == 1) {
numberOfCommentsElement.text(numberOfComments + ' Comment');
} else if (numberOfComments > 999) {
numberOfCommentsElement.text((numberOfComments / 1000).toFixed(1) + 'k Comments');
} else {
numberOfCommentsElement.text(numberOfComments + ' Comments');
}
}
Another option is to give the request the information about the amount of comments.
So you could make it in jQuery like this example
$.ajax({
// ...
success: function(response) {]
$('#newfeeds-form' + hiddenField.val()).html(response.form);
textInput.val('');
// your server side script should implement a new field "number_of_comments"
refreshNumberOfComments(response.number_of_comments); // for this call the function above has to get a parameter
},
// ...
});
Related
I asked this question previously and didn't get any help/solution. So I'm asking again.
I'm trying to make sure that even if the user refresh the page or goes back and comes back to that page, the radio button is still the same as what the user selects.
N.B: the value of the radio button is saved in sessions
<div class="col-md-1 ps-md-1">
<input class="align-middle h-100" type="radio" name="deliveryOption" id="{{option.id}}"
value="{{option.id}}">
</div>
Ajax
$('input[type=radio][name=deliveryOption]').on('change', function(e) {
e.preventDefault();
$.ajax({
type: "POST",
url: '{% url "checkout:cart_update_delivery" %}',
data: {
deliveryoption: $(this).val(),
csrfmiddlewaretoken: "{{csrf_token}}",
action: "post",
},
success: function (json) {
document.getElementById("total").innerHTML = json.total;
document.getElementById("delivery_price").innerHTML = json.delivery_price;
},
error: function (xhr, errmsg, err) {},
});
});
my view
def cart_update_delivery(request):
cart = Cart(request)
if request.POST.get("action") == "post":
delivery_option = int(request.POST.get("deliveryoption"))
delivery_type = DeliveryOptions.objects.get(id=delivery_option)
updated_total_price = cart.cart_update_delivery(delivery_type.delivery_price)
session = request.session
if "purchase" not in request.session:
session["purchase"] = {
"delivery_id": delivery_type.id,
}
else:
session["purchase"]["delivery_id"] = delivery_type.id
session.modified = True
response = JsonResponse({"total": updated_total_price, "delivery_price": delivery_type.delivery_price})
return response
when I added a django templating if statement, it kinda work but the radio button is always remember on the last radio button when refreshed.
{% for option in deliveryoptions %}
<input class="align-middle h-100" type="radio" {% if deliveryoption == %} checked=1 {% elif delivery_option == 2 %} checked="checked"{% endif %} autocomplete='on' name="deliveryOption" id="{{option.id}}"
value="{{option.id}}">
</div>
</div>
</div>
{% endfor %}
</div>
I am using django and I am getting all id from checkboxes and now I want to pass them to my view function, but I don't know how. I've tried request.GET.getlist('vals') but with no success. any suggestions?
events.html:
<script>
$(document).ready(function(){
$("button").click(function(){
type: 'POST';
var vals = [];
$.each($("input[name='checkb']:checked"),function(vals){
vals.push($(this).attr('id'));
});
alert("values: " + vals.join(", "));
});
});
</script>
<td><button><i class="bi bi-sim"></i></button></th>
{% for l in object_list %}
<tr>
<td>
<form>
<label><input type="checkbox" id={{l.pk}} name="checkb"></label>
<form>
...
urls.py:
path('eprint',views.eprint,name='eprint'),
views.py:
def eprint(request):
print('eprint')
v=request.GET.getlist(vals)
ok I finally solved this problem. I am using AJAX to send the id's to my view:
java script in the template:
<script>
$(document).ready(function() {
$("button").click(function() {
var vals = [];
$.each($("input[name='checkb']:checked"), function() {
vals.push($(this).attr('id'));
});
console.log('cons2:',vals)
$.get('eprint/ticked/',{marked: vals})
console.log('after')
});
});
</script>
views.py:
def eprint(request):
print('eprint')
print(request.GET)
I want to use Django+jquery-ajax to refresh my blog's new comments.
The code is as follows:
views.py:
#require_POST
def wirte_comment(request):
"""ajax new article comment"""
if request.user.is_anonymous:
login_url = reverse('login')
return JsonResponse({'status': 'redirect',
'login_url': login_url})
# logined
article_id = int(request.POST.get('article_id'))
comment_form = ArticleCommentForm(request.POST)
article = get_object_or_404(Article, id=article_id)
if comment_form.is_valid():
new_comment = comment_form.save(commit=False)
new_comment.author = request.user
new_comment.article = article
new_comment.save()
create_action(request.user, article,
verb=f"{request.user.username} commentted《{article.title}》")
# comment html
with open('blog/templates/blog/add_comment.html') as f:
html = f.read()
return JsonResponse({'status': 'ok',
'html': html})
else:
return JsonResponse({'status': 'ko'})
I sent the HTML of the new comment as a string to the front end:
add_comment.html:
<div class="comment">
<p class="comment-author">
<a href="{% url 'account:user_detail' article.author %}">
{% avatar article.author 25 class="circle-avatar" %}
</a>
<a href="{% url 'account:user_detail' article.author %}">
{{ article.author }}
</a>
{{ comment.created |date:'y/m/d h:i' }}
</p>
<p>{{ comment }}</p>
</div>
article.html
<script>
$(document).ready(function () {
$('#new_comment').click(function () {
var text = $('#text').val();
$.post(comment_url,
{
article_id: article_id,
content: text
},
function (data) {
if (data['status'] === 'redirect') {
window.location.href = data['login_url'];
}
if (data['status'] === 'ok') {
$('#comment-list').prepend(data['html']);
}
}
);
});
});
</script>
And then there's a problem:
When I submit a new comment,it's rendered like this:
{% avatar article.author 25 class="circle-avatar" %} {{ article.author }} {{ comment.created |date:'y/m/d h:i' }}
{{ comment }}
How can i solve this problem?
Thanks very much.
I think you need to wrap your logic inside the success function of the ajax call.
$(document).ready(function () {
$('#new_comment').click(function () {
var text = $('#text').val();
$.ajax({
url:comment_url,
data : {
article_id: article_id,
content: text
},
dataType: 'json',
success: function (data){
if (data['status'] === 'redirect') {
window.location.href = data['login_url'];
}
if (data['status'] === 'ok') {
$('#comment-list').prepend(data['html']);
}
}
})
})
});
I've been stuck on this issue for a few weeks as I'm not very familiar with how to get the ajax set up. I'm working on a Django app which is basically one page that has a Dropdown menu. I would like to get whatever the user selects from the Dropdown menu and pass that data into my views.py so I can use that information to display a graph. Right now the graph part is working (I can pass in hard coded data into it and it will generate the graph) and my dropdown is working as well. However, I don't know how to get data from the drop down into my views.py. Here is how it looks.
Display.html
{% extends "RecordEvent/nav.html" %}
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
</head>
{% block content %}
<div class="row">
<div class="padded">
<div class="download-header">
<h3>Logs</h3>
<div class="row inline download-header">
<div class="col-lg-6">
<div class="dropdown padding col-lg-6">
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
<span id="dropdownTitle" class="">Measurable</span>
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
{% include 'RecordEvent/includes/EntryDropdown.html' %}
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<div class='padded'>
<div class='col-sm-12' url-endpoint='{% url "api-data" %}'>
<h1>Graph Data</h1>
<canvas id="myChart" width="400" height="400"></canvas>
</div>
</div>
<script>
{% block jquery %}
var endpoint = 'display/api/chart/data/'
var defaultData = []
var defaultLabels = [];
$.ajax({
method: "GET",
url: endpoint,
success: function(data){
defaultLabels = data.labels
defaultData = data.default
console.log(data)
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: defaultLabels,
datasets: [{
label: '# Measurable',
data: defaultData,
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
},
error: function(error_data){
console.log("error")
console.log(error_data)
}
})
{% endblock %}
</script>
{% endblock %}
The first div creates the Dropdown menu. Everything below is to get the graph setup.
views.py
#login_required
def DisplayView(request):
return render(request,'DisplayData/Display.html')
class ChartData(APIView):
authentication_classes = []
permission_classes = []
def get(self, request, format=None):
all_entries = models.Entries.objects.all().filter(parent=2) #change to input from drop down
all_id = models.Entries.objects.all().values_list('id', flat=True)
all_measurables = models.Measurables.objects.all().filter(user_id=1) #change to current user
all_times = [m.timestamp for m in all_entries]
all_data = []
for m in all_entries:
data = m.data
json_data = json.loads(data)
value = json_data['value']
all_data.append(value)
data = {
"labels": all_times,
"default": all_data,
#"default": all_parent,
}
return Response(data)
#login_required
def LogDisplay(request):
measurables=[entry for entry in models.Measurables.objects.all().filter(user_id=request.user.id)]
return render(request, 'DisplayData/Logs.html',{'dropdown':measurables})
I need to get the value from the drop down into the where the comment says get value from drop down.
How can I do it?
to post via form
<form method='post' action = 'api url'>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
{% include 'RecordEvent/includes/EntryDropdown.html' %}
</ul>
</form>
amd in views.py access with
request.post[<name>]
to post via ajax
$('ul li').click(function(){
$.ajax({
url: <api url>,
type:'post',
data:{<name>:$(this).html()},
})
I want to iterate over files in a folder and and render links that execute a file from a flask interface.
The html/js I wrote executes the file selected by the user as many times as there are files in the folder. where do i need to be more specific so it only executes once?
{% for item in restartFiles %}
<script type=text/javascript>
$(function() {
$('a.calculate').bind('click', function() {
var item = $(this).attr('id');
$.getJSON($SCRIPT_ROOT + '/restartajax/'+item, {
}, function(data) {
$("span.result").text(data.result);
});
return false;
});
});
</script>
<h4>{{item}}</h4>
<span class="result">?</span>
<p>restart {{ item }}
</div>
{%endif%} {%endfor%}
The view, just in case
#app.route('/restartajax/<computer>')
def restartajax(computer):
def runJob(computer):
try:
subprocess.call(r"\\covenas\decisionsupport\meinzer\production\bat\restart\%s" % computer)
except Exception,e:
print 'there was an exception', e
thr = Thread(target = runJob, args = [computer])
thr.start()
return jsonify(result="restarting "+computer+" please wait 10 minutes")
You have placed your <script> tag inside a for loop. Move it outside the loop, preferably after the loop.
{% for item in restartFiles %}
<h4>{{item}}</h4>
<span class="result">?</span>
<p>restart {{ item }}
</div>
{%endif%} {%endfor%}
// THE SCRIPT IS NOW HERE
<script type=text/javascript>
$(function() {
$('a.calculate').bind('click', function() {
var item = $(this).attr('id');
$.getJSON($SCRIPT_ROOT + '/restartajax/'+item, {
}, function(data) {
$("span.result").text(data.result);
});
return false;
});
});
</script>