Send data from server to client - ajax - javascript

I need to call some python function and show its results (actually a couple of list objects) in the div id="places" section. I'm trying to do this in Javascript function show_sec() but i can't find out how to catch the data from server and process it on client.
My task is really simple and basic but since it's my first web project I need some help with ajax. Please, help me.
This is a part of my code:
.html
{% include "header.html" ignore missing %}
<!-- contents of nearest banks page -->
<section id="ask_user">
<div id="question">Разрешить приложению определить Ваше место расположения для нахождения ближайших банков?</div>
<div id="buttons">
<input type="button" name="yes" value="Да, разрешить" onclick="show_sec()"/>
<input type="button" name="no" value="Нет, не разрешать" onclick="dnt_show_sec()"/>
</div>
</section>
<section id="allowed" style="display:none;">
<div id="map_canvas"></div>
<div id="nearest_banks">
<form action="/nearest_banks/radius" method="get" id="send_radius">
Курс ближайших банков на сегодня в радиусе
<input type="text" name="radius" id="radius" size="5" value={{radius}} >
<input type="submit" class="button" value="V">
метров
</form>
<div id="check"> {{output}}</div>
<div id="places"> </div>
</div>
</section>
<section id="not_allowed" style="display:none;">
<div class="question"> Приложение не имеет возможности определить близ лежащие банки.<div>
</section>
</body>
<script type="text/javascript">
/* frm.submit(function () {
$.ajax({
type: frm.attr('method'),
url: frm.attr('action'),
data: frm.serializeArray(),
cache: false,
success: function () {
$("#check").html("OK!!!");
},
error: function(data) {
$("#check").html("Something went wrong!");
}
});
return false;
}); */
function show_sec() {
document.getElementById('allowed').style.display = "block";
document.getElementById('ask_user').style.display = 'none';
$.ajax({
type: "get",
url: "/nearest_banks/radius",
}).success(function(data) {
$("#places").html(data);
/*alert ("OK !!!"); */
});
}
function dnt_show_sec() {
document.getElementById('not_allowed').style.display = "block";
document.getElementById('ask_user').style.display = 'none';
}
$(document).ready(function(){
$("button#yes").click(function(){
//alert("demo_test");
$("section#allowed").show();
});
});
</script>
python function i try to call:
*def get(self):
default_radius = 1000
radius = get_radius(self)
exceptions = [u'', 'error', 0] # invalid values for radius
if any([radius in exceptions]):
radius = default_radius
#warning = "Вы ввели неверный радиус. Система автоматически заменила его на стандартный."
output = radius # заменить на вывод банков
else:
#warning = ''
output = radius # заменить на вывод банков
names, location = Findplaces(self, radius)
body_values = {
'names': names,
'location': location,
'radius': radius,
'output': output,
#'warning': warning,
}
template = jinja_env.get_template('nearest_banks.html')
self.response.out.write(template.render(body_values))*
In short my goal is to display names and location in the tag div id="places" after clicking on Yes button.
Or maybe i can initiate displaying specific tags from server side by using jinja2 in my python function.
Please, help me. I've spent time on it still can't get it working nicely. Thanks in advance !
EDIT:
When I click on Yes button the show_sec function loads section with id allowed.
The problem: the action in form is not processed. So Only html is shown but data from server is not received.

Since the url is "/nearest_banks/radius" and it's a get, try opening that in a browser to see what appears. You may need to view source on the page returned to view it properly. You should verify functionality of the web service first, that it returns something, and returns the correct thing.
Following that, in your show_sec function, do trial and error to see what happens. If you move the requested content to the same path as the executing page, does that make a difference?

Related

Get user input and output Flask and HTML

I'm trying to develop a web-app with Flask and HTML and right now I need to get the user input, pass it to the Python back-end, execute a function and return its output, placing it inside an HTML element. I also want this to happen without refreshing the HTML page.
How can I do this?
Bellow I have the code that I've developed so far but it's not working correctly:
My HTML:
<div id="ThroughputRate" class="data_entry">
<form action="{{ url_for('background_check_throughputrate') }}" method="post">
<input name="throughput_rate_text" class="input_box">
<input id="checkThroughputRate" type="submit" class='new-button-data' value="Check Throughput Rate">
<output name="throughputRateResult" class="result_box" ></output>
</form>
</div>
My Flask backend:
#app.route('/background_check_throughputrate', methods=['GET', 'POST'])
def background_check_throughputrate():
if request.method == 'POST':
text = request.form['throughput_rate_text']
processed_text = str(text)
throughput = transition_throughput_rate(processed_text)
return jsonify(throughput)
My HTML (continuation to get the output of the function executed on Flask):
<script type=text/javascript>
$(function() {
$('a#checkThroughputRate').bind('click', function() {
$.getJSON('/background_check_throughputrate', function(data) {
console.log(data);
document.getElementById('throughputRateResult').innerHTML = data;
});
return false;
});
});
</script>
The idea behind my execution is that the user uses the first snippet of code (in HTML) to insert the input, this input is passed onto the second snippet of code (in flask) and finally, the output of the function is passed onto the last snippet of code (in JS inside HTML) so that it can be displayed on the corresponding HTML element.
So far, the input is being correctly processed inside flask but the issue is that when the function returns the jsonify, it appears on the screen, instead of sending it into the frontend. What am I doing wrong?
Thank you all
$.getJSON is designed to load the JSON data from endpoint using GET request, however, your Python code example responds to only POST requests.
Here is the working code:
HTML
<div id="ThroughputRate" class="data_entry">
<form action="{{ url_for('background_check_throughputrate') }}" method="post" id="throughputRateForm" enctype="multipart/form-data">
<input name="throughput_rate_text" class="input_box">
<input id="checkThroughputRate" type="submit" class='new-button-data' value="Check Throughput Rate">
<output id="throughputRateResult" class="result_box" ></output>
</form>
</div>
Python
#app.route('/background_check_throughputrate', methods=['GET', 'POST'])
def background_check_throughputrate():
if request.method == 'POST':
text = request.form['throughput_rate_text']
processed_text = str(text)
throughput = transition_throughput_rate(processed_text)
return jsonify(throughput)
JavaScript
<script type="text/javascript">
$(function () {
$('#throughputRateForm').on('submit', function (e) {
e.preventDefault();
var form = $(this)[0];
var formData = new FormData(form);
$.ajax({
url: '/background_check_throughputrate',
method: 'POST',
data: formData,
processData: false,
contentType: false,
success: function (data) {
console.log(data);
document.getElementById('throughputRateResult').innerHTML = data;
}
});
});
});
</script>
Also, this code blindly trusts the user input and displays it on the webpage which can result to Cross-Site Scripting (XSS) and that is not good!
Avoid using innerHTML property when displaying user input, because it can be used to inject malicious HTML tags (e.g. <script>), i would highly recommend using innerText property instead.

FLASK - AJAX GET data from database

I am making a "write anything here" webpage where users can write anything in a textbox then post it and it is visible to everyone. It worked fine till I found out that when any user writes and submits, all the others have to refresh the page so as to get the new data from database. So a solution to this was to call ajax continuously in some intervals. This would check if there are new entries in the table. If yes, then it would render it to the html without refreshing the whole page. Now I am pure ajax noob and after hours of research I am unable to find out how to do it.
Here is the html code
<div id="textArea">
<form action="http://127.0.0.1:3000" method="POST">
<br>
<textarea minlength="3" name="comment" placeholder="Enter Text Here.." required></textarea>
<input id="postButton" type="submit" name="" value="POST">
</form>
</div>
</div>
<div class="show">
{% for item in data %}
<div id="auto" class="disPost">{{item[0]}}</div>
{% endfor %}
</div>
Here the textarea is in a form and it submits the text to database via flask server.
Also, all the comments that users wrote are shown in "div.show"
Now the flask code is like this
#app.route('/', methods = ['POST', 'GET'])
def home():
if request.method == 'POST':
post = request.form["comment"]
myquery = "select p_id from posts order by p_id desc limit 1"
mycursor.execute(myquery)
new_p_id = mycursor.fetchone()[0] + 1
myquery = "select exists(select * from posts where p_des=%s)"
rec_tup = (post,)
mycursor.execute(myquery, rec_tup)
if mycursor.fetchone()[0]==0:
myquery = "insert into posts values(%s, %s)"
rec_tup = (new_p_id, post)
mycursor.execute(myquery, rec_tup)
mydb.commit()
mycursor.execute("select distinct p_des from posts order by p_id desc")
data = mycursor.fetchall()
return render_template("homepage.html", data=data)
"mydb" is the connector & "mycursor" is the connector's cursor
Now I am stuck somewhere in how to call AJAX function. I am not able to write beyond this ..
$(document).ready(function() {
setInterval(function() {
$.ajax({
url: '',
type: 'GET',
data: //something must be here,
success: function(data) {
//here "div" must be added to the "show" class - that is comment of other users
}
})
}, 3000);
});
I know that I have to do something like this but am literally not able to solve it.
I know this is not good question and I must look at tutorials first. But believe me I had it all. I am not able to solve this problem at all.
Thank you for seeing this :)
I did this on my latest project, you can try it too. But make sure to refresh only div element you want the data show, not all the page.
$(document).ready(function() {
function getData(){
$.ajax({
url: '',
type: 'GET',
data: //something must be here,
success: function(data) {
//here "div" must be added to the "show" class - that is comment of other users
}
});
}
getData();
setInterval(function() {getData()},2000);
});

How can I improve my Ajax?

I'm trying to figure out if what I'm doing is the right way. I have a comment form and when it gets clicked I'm appending the comment into a div element through Ajax. When the page is refreshed then of course that would disappear and instead of it I have a foreach loop that runs and echos the comments. Since they both have the same CSS attributes they look the same to the user. The reason I'm doing it this way is because the foreach loop gets updated only after a refresh. Is there a better way? Can I update the page directly from the database without refresh? I basically need that every time a user clicks on the comment button that the foreach loop will run again but I couldn't find how to do it. I feel like I'm covering a gun shot with bandage the way I do it at the moment.
Loop:
#foreach($comment as $comments)
#if($comments->image_id == $image->id)
<div id="{{$comments->id}}" class="col-md-5 ajaxrules">
<div class="deletecomment">
<i class="fa fa-trash-o"></i>
</div>
<div class="col-md-2">
<img src="{{$comments->user_avatar}}" class="img-circle buddy">
</div>
<div class="hello col-md-10">
<h4>{!! $image->user_name !!}</h4>
<p class="left">{!!$comments->body!!} </p>
</div>
</div>
#endif
#endforeach
//Where I append the comments through Ajax until the refresh that replaces it with the loop
<div class="man">
</div>
Ajax:
<script>
$(document).ready(function(){
$('.send-form').click(function(e){
e.preventDefault();
var username = "{{ $username }}";
var one = $('textarea[id="{{$image->id}}"]').val();
var value = "{{$image->id}}";
var begin = '<div class="col-md-5 addavatar">'+'<div class="deletecomment">'+'<i class="fa fa-trash-o">'+'</i>'+'</div>'+'<div class="col-md-2">'+'<img src="{{$profile}}" class="img-circle">'+'</div>'+'<div class="hello col-md-10">'+'<h4>' + username +'</h4>'+'<p>'+one+'</p>'+'</div>'+'</div>';
if(one.length > 0){
console.log(username);
$('textarea[id="{{$image->id}}"]').val('');
$.ajax({
url: 'comment',
type: "post",
beforeSend: function (xhr) {
var token = $('meta[name="csrf_token"]').attr('content');
if (token) {
return xhr.setRequestHeader('X-CSRF-TOKEN', token);
}
},
data: {'id': value, 'comment': one},
success:function(data){
$( ".man" ).append([begin]);
},error:function(){
console.log("error!!!!");
}
});
}
});
});
</script>
You are killing yourself.
Manipulate the DOM via javascript code like you do it's really hard work!
You are not suppose to write html inside javascript strings, there must be another way!
And there is... Welcome to AngularJS!
In angular you can write your html and assign a javascript controller to it, perform ajax request and after the ajax complete you can bind the returned data to the html automatically! That means the angular refresh your html and do all the work for you. Even perform loop of let's say, row in a table, etc...

Ajax posted php content not read by javascript

GET-variable called brand.
A few hours ago when I had not implemented the ajax search box, everything worked fine.
The js part looks like this:
$('.mutliSelect input:checkbox').change(function() {
var brand = $("#brand_select input:checkbox:checked").map(function() {
return this.value;
}).get().join(',');
$(".submit_checkboxes").find("a").attr('href', 'index.php?brand=' + brand);
}).change();
Now, having implemented the ajax search box, the var brand does not seem to get filled with any value anymore.
This is the corresponding part of index.php:
<div class="mutliSelect" id="brand_select">
<ul>
<div class="search_view">
<section class="drop_search">
<input type="text" placeholder="Suche" id="search_brand" name="search_brand">
</section>
</div>
<div id="results">
//ajax-php result gets posted in here
</div>
<div class="button submit_checkboxes_button submit_checkboxes">
<a href""><span>Anwenden</span></a>
</div>
</ul>
</div>
and this is a part of search.php (this is the script that is called by ajax and posts the results):
$result = mysql_query($query);
while($brand = mysql_fetch_array($result)){
echo
'<li><input type="checkbox" id="'.$brand['Brand'].'" value="'.$brand['Brand'].'"'; if(strpos($_SESSION['brand'],''.$brand['Brand'].'') !== false){ echo 'checked="checked"';} echo' />
<label for="'.$brand['Brand'].'" class="checkbox_title">'.$brand['Brand'].'</label></li>';
It seems like the very last two lines (everything between <li></li> tags) does not get "noticed" by the upper js-function. When I put exactly these <li></li> tags into index.php - along with all php parts - however, it works fine.
Please let me know if this is clear.
Does anybody have an idea on how to fix this issue?
Thank you!
ajax call:
$(document).ready(function() {
// Live Search
// On Search Submit and Get Results
function search() {
var query_value = $('input#search_brand').val();
$('b#search-string').text(query_value);
$.ajax({
type: "POST",
url: "php/search_brand.php",
data: { query: query_value },
cache: false,
success: function(html){
$("div#results").html(html);
}
});
}
[...]

Only slideUp the deleted message

I'm using a PM system and added the delete-message feature. I've got a form which checks for the message_id and message_title. The form posts to delete_message.php page which contains the query to delete the message. This has been done via Javascript as I dont want the page to refresh.
I've got two functions for this:
function deleteMessage() {
$.ajax({
url: "message/delete_message.php",
type: "POST",
data: $("#delMsgForm").serialize(),
success: function(data,textStatus,jqXHR){ finishDeleteMessage(data,textStatus,jqXHR); }
});
}
function finishDeleteMessage( data , textStatus ,jqXHR ) {
$(".inboxMessage").slideUp('slow');
}
Currently when I click on the delete button (image of a trashcan) it deletes the message without reloading the page, as a finishing touch, it slidesUp the divclass (inboxMessage) the message is in. Since I tell it to slide up this class, it slides up every message. This is my piece of code containing the classes and the form:
<div class="inboxMessage">
<div class="inboxMessageImg NoNewMsg"></div>
<div class="inboxMessageHeader">
<a id="ajax" class="inboxMessageLink" onclick="showMessage('.$row['message_id'].')">'.$row['message_title'].'</a>
<p class="inboxMessageStatus Read">'.$inboxMessageStatus_Read.'</p>
</div>
<div class="inboxMessageDescription">'.$inboxMessageDescription.'</div>
<div class="inboxMessageActions">
<form id="delMsgForm" name="delMsgForm" action="message/delete_message.php" method="post">
<input type="hidden" id="msgTitle" value="'.$row['message_title'].'" name="message_title">
<input type="hidden" id="msgID" value="'.$row['message_id'].'" name="message_id">
</form>
<input type="submit" id="ajax" value="" name="deleteMessageButton" class="deleteMessageIcon" onclick="deleteMessage()">
</div>
</div>
What I want it to do is to slideUp only the message which has just been deleted by the user. I know this has to be done by telling javascript to only slideUp the deleted message which contains the message_id and/or message_title.
I've tried several things, but no love whatsoever. I'm also not that familiar with javascript/ajax. Any help would be highly appreciate.
Cheers :)
where do you call deleteMessage from? indirect the function call through another function which knows the parent of your "trash can", and can call slide up on that specific one.
function deleteMessage (element) {
//element will be clicked button
var container = $(element).closest("div.inboxMessage"),
//container div including the trashcan
$.ajax({
url: "message/delete_message.php",
type: "POST",
data: $("#delMsgForm").serialize(),
success: function(data,textStatus,jqXHR){
finishDeleteMessage(container);
}
});
});
and this will be your button
<input type="submit" id="ajax" value="" name="deleteMessageButton" class="deleteMessageIcon" onclick="deleteMessage(this)">
Apparently, you've got more divs with class inboxMessage. Since you're adding this code:
$(".inboxMessage").slideUp('slow');
.. all divs with that class will remove. If you want just one div to remove, give it a unique ID or data-attribute and hide it that way.
For example: add the message-id to the div..
<div class="inboxMessage" id="(message_id)">
..and use..
$(".inboxMessage#message_id").slideUp('slow');
.. to slide up the right div.
Edit:
Add your message ID to the div and to the function deleteMessage(), so it will be deleteMessage(message_id).
function deleteMessage(message_id) {
$.ajax({
url: "message/delete_message.php",
type: "POST",
data: $("#delMsgForm").serialize(),
success: function(){ finishDeleteMessage(message_id); }
});
}
function finishDeleteMessage(message_id) {
$(".inboxMessage#"+message_id).slideUp('slow');
}

Categories