So I'm having trouble with deciding on where to place my javascript in my Flask app. I currently have my scripts on each of my templates, but was planning to put it in the static folder, however, values don't get assigned through the flask app. What I'm asking is how would I want to structure my app in terms of wanting to alter variables in my javascript. An example of how I'm currently changing variables is below in the HTML script.
File structure:
static/
css
templates/
example.html
app.py
main.py
Flask:
#app.route('/')
def index():
a = 10
return render_template("index.html", a=a)
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title> Example </title>
</head>
<body>
<!-- Javascript files -->
<!-- Contents -->
<script>
var a = {{ a }};
alert(a);
</script>
</body>
</html>
It kind of depends. I personally save javascript files like bootstrap.js and jquery.js in static/, but javascript files which need access to my routes and/or variables returned from python I often also store within the html template. You could bypass this by sending ajax requests to an api route, but that's not ideal either in a lot of cases, and add a lot of extra overhead.
Here is another way to dynamically render js, but still keep it in its own files.
test.py
from flask import Flask, render_template_string, render_template
app = Flask(__name__)
#app.route('/')
def hello_world():
js = render_js('static/test.js', a="wow")
return render_template('test.html', js=js)
def render_js(fname, **kwargs):
with open(fname) as fin:
script = fin.read()
rendered_script = render_template_string(script, **kwargs)
return rendered_script
static/test.js
var a = "{{ a }}";
alert(a);
templates/test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title> Example </title>
</head>
<body>
<h2>nice</h2>
<script>
{{js|safe}}
</script>
</body>
</html>
I don't prefer it over just rendering the js in the html directly, but it's a possibility.
It's always a good idea to keep your javascript files separated from html templates. However, sometimes you need to pass some data from python directly to javascript. The best approach at the moment, in my opinion, would be to pass the desired data as a JSON response from your FLASK app and catch that data using AJAX or Jquery, etc.
In case you want to just keep it simple, you should separate javascript code that somehow interacts with your python code from code that does not. The latter should be in a static folder, while dynamic code can be placed into special block.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title> Example </title>
</head>
<body>
<!-- Javascript files -->
<!-- Contents -->
{% block extra_js %}
<script>
var a = {{ a }};
alert(a);
</script>
{% endblock %}
</body>
</html>
Here you have a nice {% extra_js %} block inside the main template that will allow adding some javascript code in child templates easy enough.
Related
app.py
from flask import Flask, render_template, request, jsonify
app = Flask(__name__)
#app.route('/')
def home():
return render_template('index.html')
if __name__ == '__main__':
app.run('0.0.0.0', port=5000, debug=True)
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="static/index.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="scripts/jquery-1.10.2.js"></script>
<script src="/jquery/index.js"></script>
<title>Title</title>
<script>
</script>
</head>
<body>
<h1>Hello World!</h1>
</body>
</html>
index.js
$(function () {
$(document).ready(function () {
alert('Hello World');
});
}
I think I'm doing something wrong.
I want to show a message when the document is ready.
Even if I run app.py, the alert doesn't appear.
enter image description here
have you tried to embed the script directly inside the html code:
...
<script>your script code</script>
</body>
</html>
If that works, the relative path to src="/jquery/index.js" might be not correct.
Did you check logfiles from Apache (or whatever webserver you run) on errors related to index.js
This is my html and javascript code.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<p id = 'test' onclick= "switchtest()">Hello world</p>
<script src = 'phonetest.js'></script>
</body>
</html>
function switchtest(){
document.getElementById('test').innerHTML = 'Goodbye'
}
It works on visual studio code live server, but when I transfer these 2 files to my phone and open it on chrome there, the onclick function stops working. It only works if function is in the same html file. The path to my html file is "/Internal storage/TestCode/phonetest.html" and the path to my javascript file is "/Internal storage/TestCode/phonetest.js"
I read that I might need to specify file location or that I may need a xml file, but I am not sure what I must do exactly. Does anyone know a fix?
I know how to use JavaScript 'onbeforeunload' for a standard HTML file. However, in Flask, we usually have the <body></body> tag in the base.html. I want to execute an 'onbeforeunload' from just one of the pages that extends base.html. Setting it in the base.html will trigger it from all the files that extend base. How can I set it up for just one of the HTML files?
Instead of placing the onbeforeunload directly on the body tag, you can define it in the JavaScript code.
Then you'd use a block from Jinja to set it up only on the pages you want. Here's an example with base.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
{% block content %}
{% endblock %}
</body>
</html>
And then in your children you could do this:
{% extends 'base.html' %}
{% block content %}
<!-- your HTML content here... -->
<script type="application/javascript">
window.addEventListener('beforeunload', function (e) {
// Cancel the event
e.preventDefault(); // If you prevent default behavior in Mozilla Firefox prompt will always be shown
// Chrome requires returnValue to be set
e.returnValue = '';
});
</script>
{% endblock %}
The JavaScript code is taken from the MDN, but you can change it to suit your needs: https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onbeforeunload#example
If setting the JavaScript code inside the content block is inconvenient (e.g. because you're already using it for other things), you could create another block with a different name toward the end of the body tag.
I have created a Dart HttpServer which shows "HTML" code on the browser but I also want to connect "CSS" & "JS" to this HTML,
How should I do that? please help
HttpServer _server;
_server = await HttpServer.bind(InternetAddress.anyIPv4, port);
_server.listen((request) async {
request.response
..headers.contentType = ContentType.html
//HTML Code
..write('''
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<! -- <link rel="stylesheet" href="styles.css"> -->
<title>Hello World</title>
</head>
<body>
<p>Hello WOrld</p>
</body>
<! -- <script src="app.js"></script> -->
</html>
''');
await request.response.close();
}
PS 1: One Solution is to add CSS and JS codes in the HTML code which would work but is less efficient.
PS 2: I am using this dart code in a flutter project.
Just use html tag.
Don't neglect every source imported by html tag is a http request. you should handle these requests. Dart HttpServer doesn't handle these.
I'm trying to call a python function through my js program, and i'm experiencing error:
eel.say_hello_py is not a function
I just tried step by step of their docs and its not working, dont know why, what i'm missing?
my python program contains:
import eel
eel.init('web')
eel.start('index.html', mode='chrome-app')
#eel.expose # Expose this function to Javascript
def say_hello_py(x):
print('Hello from %s' % x)
my html contains:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="index.css">
<title>Document</title> </head>
<body>
<script type="text/javascript" src="/eel.js"></script>
<script src="index.js" type="text/javascript"></script> </body>
</html>
my index.js file contains:
eel.say_hello_py("Javascript World!"); // Call a Python function
my files construction:
web(folder)
-> index.html
-> index.js
python.py
what i'm missing?
find fast solution, moved the
eel.start('index.html', mode='chrome-app')
line, after the expose command.
import eel
eel.init('web')
#eel.expose # Expose this function to Javascript
def say_hello_py(x):
print('Hello from %s' % x)
eel.start('index.html', mode='chrome-app')