My issues with JavaScript using $.(get) request in Flask App - javascript

Hello: I'm a newbie in programming so this problem may turn out to be trivial.
I have programmed a dice game (called 10,000) to teach myself python. I now want to make a simple web app re-using some of that python code. I'm using a Flask framework (+ Pythonanywhere as my web dev). I was able to put a simple CSS grid together with a CSS stylesheet and inserted a couple of JS buttons and a few HTML objects. I added a Jquery GET request to the button to get some values from the python code. So far, so good.
When I click the button though, the grid is duplicated (i.e. everything on the page appears twice); and, weirdly, only one of the buttons seems to work and returns the random values.
Now I'm not sure what I'm doing wrong. I don't see any errors popping up in the developer tool and I see the random numbers appear on the screen. Could you help me find where I messed up?
my flask app:
import random
from flask import Flask, render_template, request
app = Flask(__name__)
#app.route('/')
def hello():
data = random.randint(1,6)
if request.method == "GET":
return render_template('main.html',data=data)
if __name__ == '__main__':
app.run()
HTML template:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to- fit=no">
<meta name="description" content="">
<meta name="author" content="">
<link rel="stylesheet" linkhref="/static/css/styles.css">
</head>
<body>
<div class="grid">
<div class="title">
<h1>10,000</h1>
</div>
<div class="dice">
<div class="card" id="card1">
<p>{{ data }}</p>
</div>
</div>
<div class="roll">
<div class="round-button" id="roll-button">
<div class="round-button-circle">
<a class="round-button">Save</a>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script>
$(function() {
$('#roll-button').click(function() {
$.get('/', function(data){
var data = data;
document.getElementById("card1").innerHTML = data;
});
});
});
</script>

in the app you need add check for ajax, and return json:
from flask import Flask, render_template, request, jsonify
# add jsonfy to ipmport ^^^^^^^
def hello():
data = random.randint(1, 6)
# add next two line
if request.is_xhr:
return jsonify(data=data)
if request.method == "GET":
return render_template('main.html', data=data)
in the html use data.data
document.getElementById("card1").innerHTML = data.data
<!-- ^^^^^^ -->

Related

Without reloading , dynamically update data in flask using ajax

I'm trying to update data in flask without reloading. Using ajax and javascript , I got the updated value in python , but it didn't make changes to html template which is rendered. Note that I also used Modular Apllications with Blue Print but I feel that is not the reason. Not to confuse with too much codes , I briefly changed and uploaded simple version. Please explain and point out my mistake or error why I'm not getting my expectation.
In app.py
from flask import render_template, request, Flask
app = Flask(__name__)
#app.route("/")
def home():
if request.args.get("field_changes"):
inps = request.args.get("field_changes")
else:
inps = 2
print(inps)
return render_template("home.html",num = inps)
if __name__ == "__main__":
app.run()
In home.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<input type="number" name="dynamic_inps" max="10" min="2" id="add_inps">
<h3>Your update value is : {{ num }}</h3>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.6.3.min.js">
inps = document.getElementById("add_inps")
$(document).on("input",'#add_inps',function(){
fields = $("#add_inps").val()
$.ajax({
type:"get",
url:"/calculations",
data : {field_changes:fields},
})
})
</script>
</body>
</html>
Although the value is changed in python script , it is not changed in html " Your update value is : ".

"Javascript not available on browser" when Flask server receives an HTML Response from API

I spun up a local Flask server in order to create a Web UI for managing some of my network devices. When my networking device replies to my Flask server to ask for sign-in credentials, I receive this response (edited for security reasons):
Web-Browser: Google Chrome
<!DOCTYPE html>
<html>
<head>
<title>
</title>
</head>
<body class="vega signin-body">
<div id="root"></div>
<noscript>
<div class="signin-page">
<div class="panels">
<div class="panel signin">
<h2 class="important">Error: JavaScript not available</h2>
<div class="panel-content corner-bottom">
<p>
This web interface requires a modern browser with JavaScript
enabled.
</p>
</div>
</div>
</div>
</div>
</noscript>
<script src="/static/vega-app-70224f965ab5fa468768.js" type="text/javascript"></script>
<script src="/static/vega-vendor.bundle-70224f965ab5fa468768.js" type="text/javascript"></script>
</body>
</html>
My Code: I know that all of my Utils functions work as intended, but my main issue is receiving the html/javascript response
Server.py:
from flask import Flask, request, jsonify
from utils import ngrokWebhook, indexHTML, book_room, book_meeting
app = Flask(__name__)
#app.route('/')
def index():
return indexHTML()
#app.route('/book', methods=["POST","GET"])
def book():
meeting_title= request.form['meeting_title']
time = request.form['time']
ip_address = request.form['ip_address']
test = book_room(ip_address, meeting_title, "2019-12-09T20:45:00", "2019-12-09T21:00:00")
print(test)
return test
if __name__ == "__main__":
app.run(host = '0.0.0.0', port=80, use_reloader=True, debug=True)
Utils.py:
def getStatus(url, payload, query):
response = requests.request("POST", url, data=payload, params=query, verify = False)
return response.text
def book_room(url, meeting_title, start_time, end_time):
response = getStatus(
url,
book_meeting(meeting_title,start_time, end_time, ""),
"bookingsputxml")
return response
How can I respond to the Authentication HTML response that I receive?

Trying to invoke python function from js using jQuery and Flask

I'm trying to design an interactive website for a presentation I'm making. I'm new at all this flask stuff, and I'm having some hard time understanding why my code doesnt work.
I'm trying to create a website, that every line in it is clickable, and on click I want to bind a python function that according to the text of the line do some calculation and replaces that text.
For that I have build a simple html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>click demo</title>
</head>
<body>
<p>2016-04-21 09:12:59</p>
<p>Second Paragraph</p>
<p>2016-04-21 09:12:59 bla bla</p>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$( "p" ).click(function() {
$.getJSON('/background_process', {
line: $(this).text(),
}, function(data) {
$(this).text(data.result);
});
return false;
});
</script>
</body>
</html>
I also wrote flask code that should be binded once I click some line on my web page:
from flask import Flask, jsonify
app = Flask(__name__)
from flask import render_template
import re
#app.route("/")
def index():
return render_template('index.html')
#app.route("/background_process")
def background_process():
try:
lang = request.args.get('line', 0, type=str)
string = lang.split()[0]
if re.match(r'\d\d\d\d-\d\d-\d\d',string):
return jsonify(result=string)
else:
return jsonify(result="Doesnt start with a date")
except Exception as e:
return str(e)
if __name__ == "__main__":
app.run()
The problem is that the function does not work for some reason unless i'm specifying which spot to put the text by id of a slot in my html page, and I cant understand what went wrong.
You have two problems in your app.
The first one is that you are not importing the request module:
from flask import Flask, jsonify, request
Second, in your template, you are referring to this that is out of scope.
This should work:
$( "p" ).click(function() {
var this_p = this;
$.getJSON('/background_process', {
line: $(this_p).text(),
}, function(data) {
$(this_p).text(data.result);
});
return false;
});

d3 pie chart with flask server

I'm using the built-in flask server and I want to show an animated pie chart, like here:
http://codepen.io/tpalmer/pen/jqlFG
or
http://jsfiddle.net/thmain/xL48ru9k/1/
For simplicity, I use the latter one.
The python flask server code is:
from flask import Flask, render_template, request, flash
from forms import ContactForm
app = Flask(__name__)
app.secret_key = 'blah'
#app.route('/', methods = ['GET', 'POST'])
def test():
return render_template('test.html')
if __name__ == '__main__':
app.run(debug = True)
I did copy the javascript code provided on the webpage to the file static/script2.js
and the css code to static/css/style_d3.css
My HTML code is
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="//style_d3.css" type="text/css">
</head>
<body>
<p>test</p>
<div class="animated-ring">
<svg></svg>
</div>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="//script2.js"></script>
</body>
</html>
I run the webpage through the flask server. But I get a webpage that just says "test", there's no chart.
What do I do wrong?
I'd really appreciate if someone could help me.
You only render the test.html at "/" path, the script2.js needs to be rendered too at "/script2.js".
Try this one liner at your project's root directory to host all files:
python -m SimpleHTTPServer
I think you need to set to a path your js file. In your app dir create a static folder then put your script2.js file and when you call this file at html use flask url_for() function
src="{{url_for('static', filename='script2.js'}}"

Call python function with javascript and display returned string on web page

I have a simple appengine/python application that allows the user to click a button to display a random-generated sentence. So far, I have pieced together the main python file as follows:
import jinja2
import os
import webapp2
import generator # My random sentence generator module; its make_sentence() function returns a string
class MainPage(webapp2.RequestHandler):
def get(self):
template = jinja_environment.get_template('main.html')
self.response.out.write(template.render(dict(sentence = generator.make_sentence())))
jinja_environment = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.path.dirname(__file__))
)
application = webapp2.WSGIApplication([
('/', MainPage),
], debug=True)
In main.html:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css">
<link rel="stylesheet" href="css/custom.css">
<title>Random Sentence Generator</title>
</head>
<body>
<div class="jumbotron">
<p class="lead">{{ sentence }}</p>
<a class="btn-lg btn-info" onclick="makeSentence();return false;" href="#">Generate sentence!</a>
</div>
<script>
function makeSentence(){
location.reload();
}
</script>
<script src="http://code.jquery.com/jquery.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.2/js/bootstrap.min.js"></script>
</body>
<html>
In case it will be important for the question, here is app.yaml as well:
application: sentence-generator
version: 1
runtime: python27
api_version: 1
threadsafe: true
handlers:
- url: /css
static_dir: css
- url: /.*
script: sengen.application
libraries:
- name: jinja2
version: latest
This works okay (in fact, one can try it out here :-) ), but I would like to be able to generate a new sentence without refreshing the page each time.
From this question, it looks like I can use Ajax for this. But I'm not sure how to put it all together. I'm thinking I can replace the contents of makeSentence() with something like the top answer in the previous link, but I'm not sure how to incorporate the "response" with what I display on the web page.
You are on the right track. Instead of calling location.reload(), you can use ajax to get the output and put it in the paragraph instead. To begin with, put an identifier to the paragraph where you place your sentence:
<p id="sen1" class="lead">{{ sentence }}</p>
Now all that remains is using AJAX to get your current page output and display it in sen1. You can do something like this in makeSentence. (This will alert the response of your main page reload in ajax. You might want to extract the infomation you need from it.)
function makeSentence() {
$.ajax({
url:'http://sentence-generator.appspot.com'
}
)
.done(function(data) {
alert(data);
})
.fail(function(){
alert('error');
})
.always(function(){
//alert('always');
})
;
}

Categories