flask jquery ajax call that is executing on every loop - python

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>

Related

no values from jquery in a template to my view function

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)

How do i update comment count using Ajax

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
},
// ...
});

How to get data from Ajax request and change the HTML according to this?

I have tried to make an ajax request for getting the background task status but I cannot get the data.
Here is my Ajax request;
var ii=setInterval(function()
{
$.ajax({
type: "get",
url: '{% url "data:status" %}',
success:function (data)
{
console.log(data)
}
});
}, 5000);
function Cii(){
clearInterval(ii)
}
Here is my HTML;
<div class="jumbotron text-center" id="status">
<div id="display_status">
{% if pending and running %}
<p>{{pending}} Waiting.</p>
<p>{{running}} Going on.</p>
{% else %}
{% if completed >= 0 %}
<a href='#'> It's done, press for make prediction!</a>
{% else %}
<p>0 Waiting.</p>
<p>0 Going on.</p>
{% endif %}
{% endif %}
</div>
</div>
Here is the function which is triggered from ajax request;
def get_process_status():
now = timezone.now()
pending_tasks = Task.objects.filter(run_at__gt=now)
running_tasks = Task.objects.filter(locked_at__gte=now)
completed_tasks = CompletedTask.objects.all()
connection.close()
return len(pending_tasks), len(running_tasks), len(completed_tasks)
And here is my view;
#login_required(login_url = "user:login")
def process_status_view(request):
if request.is_ajax():
pending, running, completed = get_process_status()
context = {
"pending": pending,
"running": running,
"completed": completed,
}
return render(request, "pending_page.html", context)
return render(request, "pending_page.html")
How can I fix this?

change datalist input when another changes

I have two datalist input like this.
<input list="Province" name="Province" id="1">
<datalist id="Province">
{% for item in province_list %}
<option >{{item.Name}}</option>
{% endfor %}
</datalist>
<input list="City" name="City" id="2">
<datalist id="City">
{% for item in city_list %}
<option >{{item.Name}}</option>
{% endfor %}
</datalist>
i want when user select Province, i show list of that province city in input2.
I use JavaScript as below:
$("input[name=Province]").on('input', function () {
province = $(this).val();
dataList.empty();
$.ajax({
url: "/get_cars_"+province,
dataType: 'json',
success: function (data) {
console.log(data);
for (var i = 0, len = data.length; i < len; i++) {
$("input[name=City]").append("<option value='" +
data[i].city + "'></option>");
}
},
error: function (req, status, err) {
console.log('something went wrong', status, err);
}
});
});
In server side handle "/get_cities_\w+" request.
Remove second "for" statement in html code:
<datalist id="City">
</datalist>
Server side code in Django:
def getTheVendorProducts(request):
if request.is_ajax():
try:
uriQueri = request.build_absolute_uri()
province = uriQueri.split('_')[]
province = urllib.parse.unquote(province.split('?')[0])
vendorProduct= getTheCitiesOfprovince(province)
return HttpResponse(convertListToJson(vendorProduct), 'application/json')
except Exception as e:
logging.error(e)
return failedHttpResponse()
You need to define your own "getTheCitiesOfprovince" and "convertListToJson" functions. Visit here For more information about this type questions.

how to loop variables from Python controller to JavaScript with flask?

I want to show nested content on website:
eg:
phrase1: apple
tweet including phrase1: I like apple.
phrase2: banana
tweet including phrase2: banana is best.
my dataset which in python controller is[["apple","including phrase1: I like apple."],["banana","banana is best."]]
my html file is:
{% extends "layout.html" %}
{% block body %}
<p>Click the button to loop from 1 to 6, to make HTML headings.</p>
<button onclick="myFunction2()">Try it</button>
<div id="demo"></div>
<script>
function myFunction2() {
var x ="", i;
for (i=1; i<=2; i++) {
x = x +"<h2 class=\"phrase\">phrase"+i+":"+"{{phrases[i]}}"+"</h2>";
}
document.getElementById("demo").innerHTML = x;
}
</script>
{% endblock %}
but it only shows:
Click the button to loop from 1 to 6, to make HTML headings.
phrase1:
phrase2:
didn't show any phrase. but when I use {{phrases[1]}} {{phrases[2]}},it can show normally. can't I use i loop every variable?
You can use ajax with your flask backend. First, create the HTML template to display the button, and create a second, smaller template to loop over the dataset:
home.html:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>
<body>
<p>Click the button below to access tweet list from 1-6</p>
<button class='tweets'>View Tweets</button>
<div id='results'></div>
</body>
<script>
$(document).ready(function() {
$('.tweets').click(function() {
$.ajax({
url: "/get_tweets",
type: "get",
data: {'tweets': 'yes'},
success: function(response) {
$("#results").html(response.result);
},
error: function(xhr) {
//pass
}
});
});
});
</script>
</html>
display_data.html:
{%for tweet in tweets%}
<div class='tweet' style='border:solid;border-color:black'>
<p>{{tweet.title}}: {{tweet.phrase}}</p>
<p>{{tweet.including}}</p>
</div>
{%endfor%}
Then, in your .py file, create the necessary flask routes:
import flask
import typing
app = flask.Flask(__name__)
class Tweet(typing.NamedTuple):
phrase:str
including:str
title:str
#app.route('/tweets', methods=['GET'])
def tweets():
return flask.render_template('home.html')
#app.route('/get_tweets')
def view_tweets():
datasets = [["apple","including phrase1: I like apple."],["banana","banana is best."]]
new_set = [Tweet(a, b, f'phrase{i}') for i, [a, b] in enumerate(datasets, start=1)]
return flask.jsonify({"result":flask.render_template('display_data.html', tweets = new_set)})

Categories