How do I load static JavaScript files inside django framework - javascript

I know I'm doing something wrong, after consulting the docs and watching 3 YouTube videos that get it spun up in the first 7 min and copying them it still doesn't work
I'm basically trying to get to hello world from clicking a button
The Relevant lines in my HTML
{% extends 'box2.html' %}
{% load static %}
{% block content %}
<button class="btn btn-success mt-3" type="button" onclick="handle_do_thing_click()" type="">Add Planner</button>
{% endblock %}
{% block js_block %}
<script type = "text/javascript/" src="{% static 'js/doThing.js' %}"></script>
{% endblock %}
my settings.py static settings
INSTALLED_APPS = ['django.contrib.staticfiles']
STATIC_URL = '/static/'
STATICFILES_DIRS = [BASE_DIR / 'static']
my url.py file
from django.urls import path
from django.contrib.auth import views as auth_views
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = [ these work
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
and my js file which exists in app/static/js/doThing.js is hello world
function handle_do_thing_click() {
console.log("hello world");
}
The console error is
Uncaught ReferenceError:
handle_do_thing_click is not defined at HTMLButtonElement.onclick

For me, removing type="text/javascript/" from <script> tag make it work.

Related

JQuery loading after my script inside Twig template

I have some Javascript code inside a Twig template that uses jQuery. The script seems to be loading before jQuery, so it throws a $ is not defined error. I can't figure out why it's loading before the main bundle that includes jQuery (compiled with webpack-encore).
JQuery does load because I can reference it from the console or wrap the script inside a setTimeout to force it to be loaded later.
I have this base template:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>
{% block title %}Welcome!
{% endblock %}
</title>
{% block stylesheets %}
{{ encore_entry_link_tags('app') }}
{% endblock %}
{% block javascripts %}
{{ encore_entry_script_tags('app') }}
{% endblock %}
</head>
<body>
{% block body %}{% endblock %}
</body>
</html>
The page template:
{% extends 'base.html.twig' %}
{% block body %}
/// ...
<script>
$.change(/*...*/); // $ is not defined
</script>
{% endblock %}
webpack.config.js:
const path = require('path');
const Encore = require('#symfony/webpack-encore');
if (!Encore.isRuntimeEnvironmentConfigured()) {
Encore.configureRuntimeEnvironment(process.env.NODE_ENV || 'dev');
}
Encore
.setOutputPath('public/build/')
.setPublicPath('/build')
.enableSassLoader()
.addEntry('app', './assets/app.js')
.enableStimulusBridge('./assets/controllers.json')
.splitEntryChunks()
.enableSingleRuntimeChunk()
.cleanupOutputBeforeBuild()
.enableBuildNotifications()
.enableSourceMaps(!Encore.isProduction())
.enableVersioning(Encore.isProduction())
.configureBabel((config) => {
config.plugins.push('#babel/plugin-proposal-class-properties');
})
.configureBabelPresetEnv((config) => {
config.useBuiltIns = 'usage';
config.corejs = 3;
})
.autoProvidejQuery()
;
module.exports = Encore.getWebpackConfig();
app.js:
require('./styles/app.scss');
import $ from 'jquery';
global.$ = global.jQuery = $;
This was the generated HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="/build/app.css">
<script src="/build/runtime.js" defer></script>
<script src="/build/app.js" defer></script>
</head>
<body>
<main class="col p-4 content flex-grow-1">
<!-- page content -->
<script>
// $ is not defined here
</script>
</main>
</body>
</html>
NOTE: You must note that you can’t use require and import at the same
time in your node program and it is more preferred to use require
instead of import as you are required to use the experimental module
flag feature to run import program.
--https://www.geeksforgeeks.org/difference-between-node-js-require-and-es6-import-and-export/
The article above also mentions that with require "you can directly run the code" in this case the code is defining the $ function, so you want to run that.
My projects are as follows with no problems:
app.js:
require('./styles/app.scss');
const $ = require('jquery');
window.$ = $;
Comment the following line in webpack.config.js:
//.autoProvidejQuery()
The problem was found in these lines from the generated HTML:
<script src="/build/runtime.js" defer></script>
<script src="/build/app.js" defer></script>
The defer attribute forces the Javascript files where jQuery is defined, to be loaded after the page is rendered. Since I'm adding inline Javascript in the page, it's loaded before app.js.
Since there is no way to add deferred inline Javascript in HTML, there are two alternatives:
Set the following configuration in config/packages/webpack_encore.yaml:
script_attributes:
defer: false
This disables the behavior described. This solution is not ideal because using defer is desirable in my case.
Define Javascript code outside of the template (import it with encore_entry_script_tags).
Save your Javascript file in assets/ and, if you have a similar base template as the one in the question, import it in your page template like this:
{% block javascripts %}
{{ parent() }}
{{ encore_entry_script_tags('your_file') }}
{% endblock %}
In webpack.config.js:
Encore
//...
.addEntry('your_file','./assets/your_file.js');

Javascript File not working in symfony twig

In my symfony project my css is well linked, but my javascript is not working and I can't find why. I guess something stupid I missed ...! I tried with the encore webpack at firt since I'm runninh Sass, but I gave up and switched to the classi src=""
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{% block title %}Welcome!{% endblock %}</title>
{# Run `composer require symfony/webpack-encore-bundle`
and uncomment the following Encore helpers to start using Symfony UX #}
{% block stylesheets %}
{# {{ encore_entry_link_tags('app') }}#}
{# {{ encore_entry_script_tags('app') }}#}
<link rel="stylesheet" href="{{ asset('bundles/mercuryseriesflashy/css/flashy.css') }}">
<link rel="stylesheet" href="{{ asset('./build/app.css') }}">
{% endblock %}
{% block javascripts %}
{# {{ encore_entry_script_tags('app') }}#}
<!-- Flashy depends on jQuery -->
{% endblock %}
</head>
<body>
{% block navbar %} {% include 'inc/navbar.html.twig'%}{% endblock %}
{% block body %}{% endblock %}
{% block footer %}{% endblock %}
<script src="{{ asset('./build/app.js') }}"></script>
<script src="//code.jquery.com/jquery.js"></script>
</body>
</html>
/*
* Welcome to your app's main JavaScript file!
*
* We recommend including the built version of this JavaScript file
* (and its CSS file) in your base layout (base.html.twig).
*/
// any CSS you import will output into a single css file (app.scss in this case)
import './styles/app.scss';
import './bootstrap';
// start the Stimulus application
const logoMenu = document.querySelector('.logoMenuImg');
const contItems = document.querySelector('.contItems');
const arrItems = document.querySelectorAll('.items');
console.log(logoMenu);
console.log(contItems);
console.log(arrItems);
console.log('arrItems');
alert('hello world');
Thank you for your help
p.s: in the inspector it's blank no erros
If you are using encore_entry_script_tags i assume you have add your JS file in your webpack configuration ?
I see you're using assetic, if you are in Symfony 4.4 and more, remove it, it's deprecated. Use Webpack encore.
let Encore = require('#symfony/webpack-encore');
let CopyWebpackPlugin = require('copy-webpack-plugin');
//let TerserPlugin = require('terser-webpack-plugin');
Encore
// directory where compiled assets will be stored
.setOutputPath('public/build/')
// public path used by the web server to access the output path
.setPublicPath('/build')
.cleanupOutputBeforeBuild()
.enableSourceMaps(!Encore.isProduction())
.addEntry('app', './assets/js/app.js')
.enableSingleRuntimeChunk()
;
module.exports = Encore.getWebpackConfig();
And run with npm run build or yarn encore <env>
Look at documentation: https://symfony.com/doc/current/frontend.html

Flask - Different Javascript file for each template

I'm working on an application built with flask and using templates. I have a layout.html file with head tags and js/css links which I'm importing on each page using:
{% extends "layout.html" %}
{% block content %}
{# My content #}
{% endblock content %}
This works but I now need to link to other JS files only for specific html files and wondering what is the correct way of doing it using flask.
You can simply include your <script> tags in the HTML file where you need them. This way, the javascript will be imported only when that specific page is loaded.
An example is:
{% extends "layout.html" %}
{% block content %}
{# My content #}
{% endblock content %}
{% block scripts %}
<script scr="..."></script>
{% endblock scripts %}
If I am not wrong, you want some of your HTML pages to have a link to JavaScript code.
To achieve this just add the <script> tag in that particular HTML page as follows:
<script src="{{ url_for('static', filename='JS/some_file.js') }}"></script>
where-
JavaScript file is kept at: static->JS->some_file.js
{% block javascript %}
<script type="text/javascript">
{% include "some-js-file.js" %}
</script>
{% endblock %}
Create a code block like the block above.
For completeness, you can also reference this SO question: Loading external script with jinja2 template directive
You can have all the unique Javascript tags in the layout.html file then for each endpoint use if else statements to render the tag you want for each page. The endpoint is simply the name of the view function.
{% if request.endpoint == 'index' %}
<script src="{{ url_for('static', filename='JS/file.js') }}"></script>
{% elif request.endpoint == 'another-endpoint' %}
<script src="{{ url_for('static', filename='JS/some_other_file.js') }}"></script>

Use JS library with Django

I have a problem using a js library with django. I am trying to use the particle.js library to generate a particle background for the home page and I have tried following this tutorial.
I have created a particle.json and style.css in my static folder.
UPDATED VERSION (with static files)
home.html
<!-- templates/home.html -->
{% load socialaccount %}
{% load account %}
{% load static %}
<head>
<link rel="stylesheet" href="{% static 'style.css' %}"> </head>
<body>
<div id="particles-js">
{% if user.is_authenticated %}
<p>Welcome {{ user.username }} !!!</p>
<a href="/accounts/logout/" >Logout</a>
{% else %}
Log In with Github
Log In with Twitter
Log In with Facebook
Log In with LinkedIn
{% endif %}
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/particlesjs/2.2.2/particles.min.js"></script>
<script>
particlesJS.load('particles-js', '{% static 'particles.json' %}', function(){
console.log('particles.json loaded...');
});
</script> </body>
defined the static path in settings.py
STATIC_URL = '/static/'
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'artemis/static')
]
and im my urls.py file
urlpatterns = [
url(r'^admin/', admin.site.urls),
url('accounts/', include('allauth.urls')),
url('', views.Home.as_view(), name='home'),
] + static(settings.STATIC_URL)
When i start the server, I get the following errors in the console:
GET http://127.0.0.1:8000/static/ net::ERR_ABORTED
Uncaught ReferenceError: particlesJS is not defined
The project structure:
I just started learning django so I know this might sound like a stupid question but any idea what might be going wrong here?
Django can not parse the remainder:
{% static style.css %} this should be {% static 'style.css' %} with quotes
{% static particles.json %} should be {% static 'particles.json' %} with quotes

django how to include javascript in template

I'm starting a project and following the documentation I didn't succeed to include javascript.
Here is my settings:
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, "static"),
)
STATIC_ROOT = '/static/'
TEMPLATE_DIRS = (
os.path.join(BASE_DIR, 'templates'),
)
So I have a static folder create in my project with a javascript file.
myproject/static/app.js
my urls.py:
urlpatterns = [
url(r'^$', 'app.views.home'),
url(r'^admin/', include(admin.site.urls)),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
and in my template:
this is myproject/templates/base.html:
<!DOCTYPE html>
<head>
{% load static %}
<script src="{% static 'app.js' %}"></script>
<title>Site</title>
</head>
<body>
<img src="{% static 'img.png' %}" alt="Mon image" />
{% block content %}{% endblock %}
</body>
</html>
My other template:
{% block content %}
hello world
{% endblock %}
I have the "hello world" on
http://127.0.0.1:8000/
but i do not have my image or script.
I tried so many different things but I never succeed
urls.py
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
]
settings.py
STATICFILES_DIRS = (
os.path.join(BASE_DIR, "static"),
)
STATIC_URL = '/static/'
# remove STATIC_ROOT
base.html
Your title tag was not closed.
<!DOCTYPE html>
<head>
{% load static %}
<script src="{% static 'app.js' %}"></script>
<title>Site</title>
</head>
<body>
<img src="{% static 'img.png' %}" alt="Mon image" />
{% block content %}{% endblock %}
</body>
</html>
Your template should say {% load staticfiles %} instead of {% load static %}
Source:
https://docs.djangoproject.com/en/1.8/howto/static-files/
Also, os.path.join(BASE_DIR, "static"), only looks for static files in your apps, as in app/static/app/static.js. If you have static files that do not belong to any specific app, but rather to the project, you need to add the folder explicitly. See point 4 of 'Configuring static files' on the docs page I mentioned.
From my understanding, the STATICFILES_DIRS should be in the settings.py and defined like this:
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
]
Please check the documentation.
I am new at programing thus take my points with a pinch of salt. There i go. maybe you have more apps meaning you gotta check your tree as it should go as the django documentations points.
meaning that you should have your_app/static/your_app/in here you must put three more folders corresponding to css, images and js all with their respective files.
Also notice that your static url should be named diferent than your static root.
Once you have done this you must tell django where to find the statics for each app thus you gotta state it within the STATICFILES_DIRS.
After all this then you gotta run the collectstatic command.
I´m still missing the part in which you connect the js files of each app to the template.. so I cannot further help you dude.... hope it helps a little bit
Create directory named 'static' at base directory. i.e. at similar level to project directory.
Then add following in settings.py
STATIC_URL = '/static/'
#setting for static files
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'),) code here

Categories

Resources