How to add Javascript into Django? - django

I recently got my static files working for my project directory. I wrote a separate file with a javascript function called my function. I have a in html that calls a function in my javascript, but chrome is returning a function is not defined error.
Does anyone know how to resolve this?
{% load static %}
{% block content%}
<h1 id="change" onclick="myFunction()"> hi! </h1>
{% endblock %}
function myFunction(){
var count = 0;
console.log(count);
}
Chrome Error
(index):55 Uncaught ReferenceError: myFunction is not defined
at HTMLHeadingElement.onclick ((index):55)

The tag {% load static %} doesn't create script tags for you; you still need to define them:
{% load static %}
{% block content%}
<h1 id="change" onclick="myFunction()"> hi! </h1>
<script type="text/javascript" src="{% static 'someFile.js' %}"></script>
{% endblock %}

Related

Adjust bootstrap within jinja template (Flask Framework)

I would like to adjust default bootstrap class formatting within jinja template. The only thing, what I want to do, is to change the color of the h1 element. But unfortunately, it is still black.
I am using flask and render_template module.
I have following code in template:
{% extends "bootstrap/base.html" %}
{% block head %}
{{ super() }}
<link rel="stylesheet" type="text/css" href="bootstrap_adjust.css">
{% endblock %}
{% block content %}
<div class="container">
<div class="page-header">
<h1>Hello, Vaclav!</h1>
</div>
</div>
{% endblock %}
boostrap_adjust.css looks like this:
h1{
color:blue;
}
Thank you for any advice!
Vaclav
I ll try to answer the question "how to adjust an element using a .css file instead of styling it directly?"
Go in your base.html file, i.e. the file you extend from, and in the header tag, at the end of all the other stylesheets create a Jinja2 block like so
{% block stylesheets %}
{% endblock stylesheets %}
Second step would be to call this block in your child templates and pass your .css files in there instead of passing it in the head block.
{% block stylesheets %}
<link rel="stylesheet" type="text/css" href="bootstrap_adjust.css">
{% endblock stylesheets %}
Give it a try and let us know!
I finally found working solution here:
https://stackoverflow.com/questions/34664156/flask-bootstrap-custom-theme
So in my case this works:
{% block styles %}
{{ super() }}
<link rel="stylesheet" type="text/css" href="{{url_for('static', filename='bootstrap_adjust.css')}}">
{% endblock %}
.css file is placed in the folder static. But be careful, static is not part of the path in filename parameter, because url_for('static') looks automatically in this folder.
Thank you all for your willing to help!
Adding a custom CSS file:
{% block styles %}
{{super()}}
<link rel="stylesheet"
href="{{url_for('.static', filename='mystyle.css')}}">
{% endblock %}
Please Read the documentation on Flask-Bootstrap and have a good understanding of super classes.
This is the Link - Flask-Bootstrap

Do I need to use 'load static' twice on overall layout and header in Django?

I'm on a project in Django, and the problem is like this.
My site have a overall layout like 'layout.html' which includes some static files, links in and 'header.html' including navigator, 'footer.html' including some links in . But Both of 'layout.html' and 'header.html' uses static files so I think one command {% load static %} on first line in 'layout.html' can affect both 'layout.html' and 'header.html' because 'layout.html' includes 'header.html'! But it doesn't work, it works only when {% load static %} in both files.
Maybe my explanation is hard to understand, so I will write my code very shortly.
'layout.html'
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<link href="{% static 'onepage-scroll.css' %}" rel="stylesheet" type="text/css">
</head>
<body>
{% include 'header.html' %}
{% block content %}
{% endblock %}
{% include 'footer.html' %}
</body>
</html>
'header.html'
{% load static %}
<nav id="navi">
<h3><img src="{% static 'logo.jpg' %}"></h3>
</nav>
I think this is not a good implementation because there are 2 times of loading staticfiles. Is there another way to solve this?
I think you may be misunderstanding what {% load static %} does. It just gives your template access to the associated {% static %} tag. It does not result in the static files themselves being reloaded or any significant burden in terms of extra code being ported.
You're using the tag exactly as intended. If you need static files, you need to load the tags to do that with.

Django template block from within template tag template

I have a template called base.html. This template contains a block called pagescripts at the bottom after jQuery has been loaded, like this:
<div class="container-fluid">
{% block content %}
{% endblock %}
</div>
<script src="https://code.jquery.com/jquery-3.3.1.min.js" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js" integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js" integrity="sha384-alpBpkh1PFOepccYVYDB4do5UnbKysX5WZXm3XxPqe5iKTfUKjNkCk9SaVuEZflJ" crossorigin="anonymous"></script>
<script defer src="https://use.fontawesome.com/releases/v5.0.10/js/all.js" integrity="sha384-slN8GvtUJGnv6ca26v8EzVaR9DC58QEwsIk9q1QXdCU8Yu8ck/tL/5szYlBbqmS+" crossorigin="anonymous"></script>
{% block pagescripts %}
{% endblock %}
Next, I have a template tag that is an inclusion tag for displaying a fancy-looking boostrap 4 card for a particular news article, like this:
#register.inclusion_tag('long_article_card.html', takes_context=True)
def show_long_card(context, article):
try:
contextForm = context['form']
except KeyError:
contextForm = None
return {'article':article, 'form': contextForm}
Now, within that long_article_card.html, I want to add a script to the pagescripts block from base.html. So, in long_article_card.html, I have this:
<div class="target">TARGET HERE</div>
<a class="dropdown-item" id="lean-vote-xl" href="#">Extreme Left</a>
{% block pagescripts %}
<script>
$(document).ready(function(){
$("#lean-vote-xl").on('click', function(){
$.ajax({
url:'/webproxy/v/?i=a&pk={{article.id}}&t=1&v=3',
type:'get',
dataType:'html',
crossDomain:true,
success:function(data)
{
var outputCard = "<div class=\"target\"><br><h2>That worked</h2></div>";
$(".target").html(outputCard);
},
error: function(data) {
var outputCard = "<div class=\"target\"><br><h2>Load Error</h2></div>";
$(".target").html(outputCard);
}
});
}); // end id_url_text
});
</script>
{% endblock %}
That template tag is then called from an article detail template called article/detail.html, which extends base.html.
{% extends 'base/base.html' %}
<div class="row">
{% show_long_card article %}
</div>
But that results in the javascript in long_article_card.html being rendered at the end of long_article_card.html, which means it is rendered before jQuery is loaded at the bottom of the page, therefore the script doesn't work because $ is not defined yet. What I need to happen is for the block pagescripts from long_article_card.html to be rendered at the very bottom of the page, essentially at the bottom of base.html. I need django to take the block pagescripts from long_article_card.html, pass it up to article/detail.html, and then article/detail.html to pass it up to base.html, then base.html includes it in its pagescripts block that is at the very bottom of base.html after jQuery is loaded.
I can't have long_article_card.html extend the article/detail.html because it causes a recursion error. Is there any way for long_article_card.html to add things to base.html's pagescripts block?
Thank you.
django-sekizai was built for this use case. It may be of use to you

Django templates, including page(s) that injects code into parent block

Is it possible to include a template (with include django template tag) within another template and "inject" some content to the page that includes (parent) through block tag, or something similar?
Let's say I have the following file structure within my project:
App/
(...)
templates/
base.html
index.html
_include1.html
_include2.html
_include3.html
_include4.html
Code for base.html:
<!DOCTYPE html>
<html>
<head lang="en">
(...)
</head>
<body>
<script type="application/javascript">
$(function () {
{% block extra_script %}
{% endblock %}
});
</script>
Code for index.html:
{% extends "base.html" %}
{% load static %}
(...)
<div class="row gutter">
<div>
{% include "_include1.html" with object=object%}
</div>
<div>
{% include "_include2.html" with object=object %}
</div>
<div>
{% include "_include3.html" with object=object %}
</div>
<div>
{% include "_include4.html" with object=object %}
</div>
</div>
And in each _include*.html I would like to call some specific JS function (for example), but I want to place it in the parents (index.html or base.html, doesn't matter in my case) extra_script block. I searched in the documentation, other questions and didn't find a way to do this with the include syntax.
I've done something similar but through extends tag. However I don't want to define a block in the index.html or base.html for each page that I need to include ({% bloc include_* %}.
So the solution that I have now (and works) is to define a script in each included page like this (_include1.html):
<div>
(...)
</div>
<script>
$(function () {
//Code that should be placed within parents script page (this is just an example)
var a = function (){
(...)
};
a();
});
</script>
However I think there's a better way to do this, by making use of django templates engine, and without having to define a block for each page that needs to be included. Also I would like to have all my js code in a single place (parents <script> tag) instead of being scattered all over the place (like it is with the presented solution).
Can anyone give some input or ideas towards this?
Thanks!
Try to use django-sekizai for that purpose.
With sekizai, you can define a JavaScript block just before the </body>:
{% render_block "js" %}
And then whenever you need to add JavaScript to that block, you write this:
{% addtoblock "js" %}
<script type="text/javascript">
// your JavaScript
</script>
{% endaddtoblock %}
If there are duplicates of the content in the {% addtoblock %} blocks, they will be used only once.

How to call several addOnLoad functions in dojo?

I'm trying to define several dojo elements from several (inherited) HTML pages , and each defines addOnLoad of his own, which causes only the latest function to be executed, since they are overridden.
Is there a way to overcome this problem?
Thanks.
You can use blocks to replace inherited elements
in template-base:
<head>
<script type="text/javascript" src=""></script>
{% block extra-header %}
#code default
...
{% endblock %}
</head>
in template:
{% block extra-header %}
{{ block.super }}
#replacement code
...
<script type="text/javascript" src=""></script>
{% endblock %}
for more information see https://docs.djangoproject.com/en/1.3/topics/templates/#template-inheritance