How to set up JS 'onbeforeunload()' in flask? - javascript

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.

Related

Why is my static CSS file working fine but not javascipt in Django?

I'm new to Django. I'm trying to add a javascript for my navbar. Browser is reading static CSS file properly. But it looks like browser is ignoring my static javascript file. Here is my code:
Settings.py
STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
Index.html
<html lang="en">
{% load static %}
<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' type='text/css' href="{% static 'style.css' %}">
<script type='text/javascript' src="{% static 'style.js' %}"></script>
<title>{% block title %}{% endblock title %}</title>
</head>
To check whether javascript is working properly I have only put a alert box. But still it is not showing alert box.
style.js
alert("Checking");

Javascript runs in template html file but not extended html file in Django application

I am writing a website in Django and Vanilla JS
I have 2 html pages, I want them both to share css but I want them to use different javascript.
Both pages extend a layout.html.
The layout.html looks begins like this
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<title>{% block title %}Social Network{% endblock %}</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<link href="{% static 'network/styles.css' %}" rel="stylesheet">
</head>
My index.html (which extends my layout.html) begins like this
{% extends "network/layout.html" %}
{% load static %}
<script src="{% static 'network/messages.js' %}"></script>
and my Javascript file looks like this:
document.addEventListener('DOMContentLoaded', function() {
console.log("page loaded!")
document.addEventListener('click', event => {
const element = event.target;
console.log("Something was clicked")
})
});
It simply prints out a line when the page is loaded and when something is clicked.
However, when I go to index.html with the code like this, the javascript file is not loaded, nothing is printed out when the page is loaded or when anything is clicked.
However, if I modify the layout.html page to be like this:
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<title>{% block title %}Social Network{% endblock %}</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<link href="{% static 'network/styles.css' %}" rel="stylesheet">
<script src="{% static 'network/messages.js' %}"></script>
</head>
where I load the messages.js, and then remove it from the index.html like this:
{% extends "network/layout.html" %}
Then the javascript works, and the page loads it properly.
The only problem with this is that it also loads it for my other pages which I do not want, I only want to load message.js for index.html and I am not sure why it refuses to load when I only include it in index.html.
I appreciate any help.
This is not how you extend templates. Django templates use a block system. So the script in the index.html isn't rendered at all. You must have an empty block in layout.html, and override that block in index.html.
layout.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>{% block title %}Social Network{% endblock %}</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<link href="{% static 'network/styles.css' %}" rel="stylesheet">
</head>
<body>
{% block content %}{% endblock content %}
</body>
</html>
index.html
{% extends "network/layout.html" %}
{% load static %}
{% block content %}
<script src="{% static 'network/messages.js' %}"></script>
{% endblock content %}
Try adding HTML to your current index.html. It won't be displayed. You must enclose everything in blocks for it to work.

Problem using Nunjucks functionalities in "index.html"

I'm trying to use Nunjucks (client-side) as the templating component of my project. I'm using xampp, apache for the server.
The problem is that when i put "nunjucks code" inside the index.html, it doesn't compile it. If i put "{% include "sidebar.html" %}" it just renders that in the DOM.
I'm being able to use the render method AFTER the DOM is loaded, and in my templates, everything works.
index.html (DOESN'T WORK):
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<!-- Meta, title, CSS, favicons, etc. -->
...
<body>
...
{% include "sidebar.html" %} // This gets rendered literally
...
</body>
...
So, basically i want to know if it's possible to use nunjucks functionalities in the first page that is served by apache (in this case, index.html).
Thanks in advance.
Try it
// index.html
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script src = "/js/vendors/nunjucks.min.js"></script>
<script>
window.addEventListener('load', function () {
nunjucks.render('index.njk', {some-data}, (err, html) => body.innerHTML = err && err.message || html);
});
</script>
<body>
<!-- Empty body -->
</body>
</html>
// index.njk
{% include "sidebar.njk" %}
...
I found a hacky workaround, where i "add another layer of htmls".
So, in index.html, i have this code:
$(document).ready( function() {
nunjucks.configure('./includes', { autoescape: true });
nunjucks.render('dashboard_main.html', {}, function(err, res) {
$("#main_content").html(res)
});
});
And then, dashboard_main.html can have nunjucks code.

Structuring Flask App with Javascript

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.

jQuery Loads in Chrome but Not Firefox, why?

I'm using Django and I have an HTML file, with this line in the head tag:
<script type="text/javascript" src="/path/to/jquery.js"></script>
This works fine in Chrome, but it seems to have no effect in Firefox 3.6.18. (When I type in $ or jQuery in the Firefox console, I get an error, whereas Chrome just shows it correctly.) The rest of my scripts can't load because of this.
I tried strace, and it seems like the file is, in fact, loaded.
What could be causing this?
More info:
I can't post a lot of the HTML, but some relevant parts:
My HTML file (Django templates):
{% extends "my_base.html" %}
{% load stuff %}
{% block head %}
{{ block.super }}
<script type="text/javascript" src="/media/jquery_listbox/js/jquery-min.js"></script>
<script type="text/javascript" src="/media/jquery_listbox/js/ui.core-min.js"></script>
<script type="text/javascript" src="/media/jquery_listbox/js/ui.dropdownchecklist-min.js"></script>
<link rel="stylesheet" type="text/css" href="/media/jquery_listbox/css/ui.dropdownchecklist.css" />
{% endblock %}
my_base.html:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<link rel="stylesheet" type="text/css" href="default.css"/>
{% block head %}{% endblock %}
</head>
...
</html>
It's hard to tell without seeing the rest of your HTML. With Firebug installed, you can check the Net tab to make sure the jQuery file is requested and returned correctly in Firefox. Or replace the src with Google's hosted jQuery which is https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js - if that works then you know it's a location problem, not a code problem.
First I'd clear the browser cache. Secondly I'd change that local js file to always pull from the Google CDN
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.js" type="text/javascript"></script>

Categories