Use diffrent javascript files in Laravel blade template - javascript

I'm creating an app with Laravel 7 and I want to have common js files imported in the main layout and specific js file imported in each view, or use the script tag directly. My Code looks like this:
Layout body
<body>
<main>
#yield('content')
</main>
<script src="{{ asset('js/common.js') }}"></script>
#stack('script')
</body>
And one of the files looks like this:
#section('content')
<div class="game-version-list">
<ul>
#foreach ($list as $element)
<li>
{{ $element['text'] }}
<div>
<span class="info-btn" data-key="{{ $element['key'] }}">?</span>
<div class="game-info"></div>
</div>
</li>
#endforeach
</ul>
</div>
#endsection
#push('script')
{{-- <script src="{{ asset('js/common.js') }}"></script> --}}
<script>
const btns = document.querySelectorAll('span');
btns.forEach(element => {
element.addEventListener('click', getGameInfoMobile);
});
</script>
#endpush
When I load the page it tells me that the function getGameInfoMobile is not defined (the function is in the common.js file).
I've tried also to import the common file in the stack but there's no difference, it only works if I put evereything in the common.js file.
I don't what to import the all script file in the app.js and I really need this approach because there are a lot of function that I need to use multiple times. Anyone knows what I'm missing?

Related

How to use a separte js file in Laravel Blade Html?

How to use a js file outside Laravel Blade html?
Besides my layouts file, I have a single file welcome.blade.php for the html and it requires a fair amount of scripts. To improve neatness, I wanted to move the <scripts> from the bottom of welcome.blade.php into a separated .js file.
See below for current code, mainly a test to get things working.
welcome.blade.php
#extends('layouts')
#section('content')
<div>
Body Content
</div>
#endsection
// Script added to the bottom of welcome.blade
// How to move into a separated file, like in resources/js/welcome.js
// <script src='/js/welcome.js'></script> doesn't work
<script>
alert('js works');
</script>
Even when I create a new welcome.js script inside the resources/js folder, linking via src or assets doesn't work.
I don't want to put it in the app.js (default laravel install folder structure), because then it'll load in for EVERY page, instead of just welcome.js.
I've tried using stack, but the file doesn't exist when using asset. However, it does work when writing the script itself into the push block. But then that's not using a separate .js file anyway...
layouts.blade.php
<body>
...
#stack('scripts')
</body>
</html>
welcome.blade.php
...
#push('scripts')
// Works when directly writing the script here
// Trying to use `<script src="{{ asset('js/welcome.js' }}"></script>` fails
// No js/welcome.js found.
<script>
alert('js works');
</script>
#endpush
How can I use a separate .js file inside a Laravel Blade HTML Template?
Edit
Did I actually need to make the welcome.js script public in webpack mix? It seems to work now after adding the additional .js line.
See answer.
Versions: Laravel 8
Issue was that the separated .js file didn't exist anywhere, hence couldn't be by welcome.blade.php. Solved by outputting the script to public in webpack mix
Script file, welcome.js
alert('js works');
welcome.blade.php
#push('scripts')
<script src="{{ asset('js/welcome.js' }}"></script>
#endpush
layouts.blade.php
<body>
...
#stack('scripts')
</body>
</html>
webpack.mix.js
mix.js('resources/js/app.js', 'public/js')
.js('resources/js/welcome.js', 'public/js')
.postCss('resources/css/app.css', 'public/css', [
//
]);

HTML/JavaScript - Replace onClick() (in HTML) with JavaScript (addEventListener not working)

I've tried a few solutions on here already, but I just can't seem to make them work.
I have a Flask app that uses HTML combined with JavaScript to display a handful of web pages.
Right now, I still have some inline code (which also prevents me from setting a proper CSP-Header), namely <... onClick="function()">.
Right now my HTML looks like this:
<html>
<head>
<...other stuff...>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.21.1/axios.min.js"></script>
<script type="text/javascript" src="{{ url_for('static', filename = 'admin.js') }}"></script>
</head>
<body>
<div class="topnav">
<b>Logout</b>
AdminView
Show TAN
</div>
<...other stuff...>
</body>
</html>
JavaScript like this:
bunchOfFunctions
function logout() {
window.location.replace(URL_SLO)
}
function adminView() {
window.location.replace(URL_ADMIN_BASE)
}
function tanView() {
window.location.replace(URL_TAN)
}
I have attempted to import the Script at the bottom of the HTML file and then add Eventlisteners like so:
document.getElementById("logout").addEventListener("click", logout)
But all that does is do nothing when I click on the buttons again, not even an error.
On a related note, it'd be cool if I could download the Axios script and use it locally, since, y'know, security. But when I merely copy the content of the link and try to integrate it that way, the imports don't work.
Edit: Copied the working version of the snippet, not the broken one.
It now only works in one script, the other one doesn't.
tan.html:
<html lang="en">
<head>
<... other stuff ...>
</head>
<body>
<div class="topnav">
<b>Logout</b>
{% if isAdmin %}
<b>AdminView</b>
{% endif %}
</div>
<... other stuff ...>
<script type="text/javascript" src="{{ url_for('static', filename = 'tan.js') }}"></script>
</html>
and the corresponding JS file:
function logout() {
window.location.replace(URL_SLO)
}
function adminView() {
const URL_ADMIN_BASE = URL_BASE + "api/adminsans/";
window.location.replace(URL_ADMIN_BASE)
}
function mount() {
...other stuff
document.getElementById('logoutButtonTAN').addEventListener('click', logout);
document.getElementById('adminViewButtonTAN').addEventListener('click', adminView);
}
window.onload = mount
other stuff...
onclick
The onclick attribute fires on a mouse click on the element.
getElementById
Get the element with the specified ID
You must use ID
document.getElementById('logout').addEventListener('click', function(e) {
e.preventDefault();
alert('logout');
});
<div class="topnav">
<b>Logout</b>
AdminView
Show TAN
</div>

How to render a React component with Python Tornado template?

I'm trying to modify login page UI (with React) in JupyterLab, it seems like its server consists of Python Tornado and renders login.html as one of templates. (literally stored in templates directory. ...jupyter_server\templates\) It might also render others like 404.html, error.html respectively in terms of contexts.
I simply followed https://reactjs.org/docs/add-react-to-a-website.html like below so:
page.html
<head>
<meta charset="utf-8">
<title>{% block title %}Jupyter Server{% endblock %}</title>
:
:
<!-- We will put our React component inside this div. -->
<div id="like_button_container"></div>
<!-- Load React. -->
<!-- Note: when deploying, replace "development.js" with "production.min.js". -->
<script src="https://unpkg.com/react#17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom#17/umd/react-dom.development.js" crossorigin></script>
{% block login %}
{% endblock login %}
</body>
</html>
logint.html
{% extends "page.html" %}
{% block login %}
<script src="like_button.js"></script>
<script>console.log('This is Login page.')</srcipt> // logs shows fine
<h1>This is Login Page.</h1> // tag shows fine
{% endblock login %}
As I understand so far, when the url hit as login, login.html renders with appending its contents to page.html.
I was expecting the like_button.js component renders fine but it is the only thing excluded. The log and h1 are visible correctly meanwhile.
Have I missed something? any ideas welcome.
The src of the script isn't correct. In Tornado, you put your static files in a folder called static and then set the src like this:
<script src="{{ static_url('like_button.js')"></script>
If you put the file in a subfolder such as static/js/, then provide its relative path:
<script src="{{ static('js/like_button.js') }}"></script>

Functions imports after splitting a single JS file are no more aware of the object they take as parameter

I have a more than 800 lines single JS file using OpenLayers to create web map. It's definitely too much! The file is written in vanilla JavaScript.
It is simply structured as follow:
const function1 = (featurePassedFromFlask) {
do stuff
return someVectorLayers;
}
const function2 = (otherFeaturePassedFromFlask) {
do stuff
return aPoint;
}
const map = (vectorLayers, myPoint) => {
do stuff to build the map, no returned value.
}
vectorLayers = function1(featurePassedFromFlask);
myPoint = function2(otherFeaturePassedFromFlask);
map(vectorLayers, myPoint);
As you can see, I have three main functions in there, so I decided to split it in three files, one for each function after reading https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import and https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export:
File function1.js:
const function1 = (featurePassedFromFlask) {
do stuff
return someVectorLayers;
}
export { function1 };
File function2.js:
const function2 = (otherFeaturePassedFromFlask) {
do stuff
return aPoint;
}
export { function2 };
and file map.js with the remaining code + these two new lines at the top:
import { function1 } from './function1.js';
import { function2 } from './function2.js';
The "problem" is that in my Flask template map.html (jinja2) I only load the map.js file as:
<!-- Pass first result object from Python to JS here -->
{% if resultsObjectFromRoute1 %}
<script type="text/javascript">
var featurePassedFromFlask = {{ resultsObjectFromRoute1|tojson }};
</script>
{% endif %}
<!-- Pass second result object from Python to JS here -->
{% if resultsObjectFromRoute2 %}
<script type="text/javascript">
var otherFeaturePassedFromFlask = {{ resultsObjectFromRoute2|tojson }};
</script>
{% endif %}
<script src="{{ url_for('static', filename='js/ol.js') }}" type="application/javascript"></script>
<script src="{{ url_for('static', filename='js/map.js') }}" type="application/javascript"></script>
The browser first complained: Uncaught SyntaxError: import declarations may only appear at top level of a module so I browse a little to figure out I have to change the last line to:
<script src="{{ url_for('static', filename='js/map.js') }}" type="module"></script>
It doesn't complain anymore but not the page is not properly working:
Uncaught ReferenceError: assignment to undeclared variable geom
I also tried to import my two functions files in map.html without any changes to the previous error message:
<script src="{{ url_for('static', filename='js/function1.js') }}" type="module"></script>
<script src="{{ url_for('static', filename='js/function2.js') }}" type="module"></script>
<script src="{{ url_for('static', filename='js/map.js') }}" type="module"></script>
Maybe it would have worked if the function 1 and 2 didn't had to processed an argument, so I know I broke something related to that, because now those files "function1.js" and "function2.js" are no longer aware of the existence of the object they have to take into account as argument to the function defined in there. So how could I bring up that link again, just like when all was encapsulated in a single file?
ps: sorry for the probably bad - to very bad - wording, I'm not an expert in JS (that's also probably why I didn't succeed to find some helpful material).
I finally figure it out.
There are two possibilities.
1. as classical "type=application/javascript" imports within the HTML
Like #Kajbo suggested in the comments above, removing all export/import syntax and loading all the JS files in one by one in the HTML, with the main one (map.js) being loaded last in the template does work:
<script src="{{ url_for('static', filename='js/function1.js') }}" type="application/javascript"></script>
<script src="{{ url_for('static', filename='js/function2.js') }}" type="application/javascript"></script>
<script src="{{ url_for('static', filename='js/map.js') }}" type="application/javascript"></script>
but it doesn't work if they are loaded as "module", as I initially did.
The main disadvantage of this way of doing is that if you end up having 180 JS files, it meas 180 imports in your HTML. I was not very enthusiastic.
2. as modern "type=module" imports within the HTML
In fact, I noticed that the error I had on geom was due to this line in my code:
geom = new ol.format.GeoJSON();
If this lazy way of declaring a variable worked before when loading the JS file with "type=application/javascript", it doesn't work when you load them as "type=module". Indeed, modules seem to be more ticklish and you really have to declare your variables properly now:
let geom = new ol.format.GeoJSON();
I've had many other similar mistakes, so I cleaned up my code with proper declarations and that's it! It's working now with the export/import ES6 logic, hence you can keep your HTML clean by only importing the main JS file (all JS logic stays in the JS files; that's much cleaner)!

external JS not loading properly in child views in Laravel5.6

I am new to Laravel5.6 . I added the JS files in Layout page like this
with jquery CDN
<script src="{{ asset('js/app.js') }}"></script>
#yield('script');
and in Child View added like this
#extends('layouts.client')
#section('content')
*Some HTML CODE Here*
#endsection
#section('script')
<script src="{{ asset('js/jquery.easing.js') }}" />
<script src="{{ asset('js/jqueryFileTree.js') }}" />
<script type="text/javascript">
$(document).ready( function() {
alert('hi');
});
</script>
#endsection
and when i look the source using F12 then i found
enter image description here
jqueryFileTree.js file is not showing in JS folder with other js in Network tab but in source, showing with black color(behave like simple text) unlike blue color link, shown in red circle.
Also doument.ready function not working. If i remove the both external js then ready function work well.
What going wrong ?, i am fail to catch.
Thank's in advance...

Categories