Twig variable in external JS file
There a two approaches when you need to pass a twig variable to an external javascript file
- Define the variables inside a script block in the twig template
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<script>
var my_twig_var = {% if twig_var is defined %}'{{ twig_var }}'{% else %}null{% endif %}
</script>
<script src="scripts/functions.js"></script>
</body>
</html>
For this approach I usally add a block called "javascript" block in my main/base templatebase.twig.html
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
{% block body %}
{% endblock %}
{% block javascript %}
{% endblock %}
</body>
</html>
page.html.twig{% extends base.twig.html %}
{% block body%}
<h1>Hello World</h1>
{% endblock %}
{% block javascript %}
<script>
alert('{{ twig_var|default('Hello World') }}');
</script>
{% endblock %}
- Pass the variables to javascript with the aid of
data-*
attributes
<div data-foo="{{ foo }}">...</div>
$(function() {
$(document).on('click', '.button', function(e) {
console.log($('div[data-foo]').data('foo'));
});
});
Sidenote: if you want to pass an object or an array to
twig
you can always use the json_encode
filter, which will convert the variable to a valid javascript objectIf you want to have control over which object properties are exposed by the json_encode
filter you can always implement the interface Serializable
Use Twig variables in external js file
You can use two tricks for this.
a. Use classes or specific attributes in your form elements, and access to them with global selectors.
<?php
namespace App\Form;
class MyForm extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add("descriptionText", null, [
"attr" => [ "class" => ["trumbowygable"]],
...
]) ;
... or ...
$builder->add("otherField", null, [
"attr" => [ "data-other-thing" => 1]],
...
])
}
}
And JS looks like ...$('input.trumbowygable').trumbowyg(trumbowyg_config);
// or
$('input[data-other-thing]').on("someEvent", bla bla bla);
b. Create a global javascript function that receive id elements by parameters.function buildTrumbowyg(id_one, id_two) {
$('#' + id_one).blaBlaBla( ... )
}
How can I use javascript code in an external file with twig elements?
First of all (as the comments already said) it is not a good idea to mix JavaScript with Twig.
- Makes your code hard to maintain, hard to read and hard to understand
- Syntax errors and JavaScript errors might happen quite easily
- Probably messes up syntax highlighting in IDEs
- etc.
var output = {{ output|json_encode() }};
Within script.js you might do something like:$(document).ready(function () {
let options = { "repsonsive": true };
if(output.json === true) {
options.serverSide = true;
options.ajax = { ... }
} else {
options.data = output.data
}
var table = $('.datatable').DataTable(options);
});
Use this process of refactoring also to clean and restructure your code and especially keep JavaScript and CSS seperated from the Twig files as good as possible. Pass variable from twig to js
Assign the variable in the template and pick it up with javascript...
<script>
var foo = '{{ foo }}';
alert(foo);
</script>
Call js function from external file Symfony Twig
I hope everyone is doing great during this troubles times ! France started containment last week so I had plenty of time finding the solution.
Dumbest thing ever but I didn't know that..
In your js external files, you have to declare your functions like this :
window.myfunction = function myfonction(){}
That's all.. Could that potentialy cause security issues ? I don't know so I'm asking xD
How to make twig globals accessible in javascript library
I used a bad example above. I was using in my html something more like
<div id="twig-vars" data-newRoute="{{ URL_Symfony_dev }}"></div>
And so the js was :var test= $('#twig-vars').data('newRoute');
alert(test);
Which didn't work. But the problem (camel case in names) couldn't be detected with the example i gave. My apologiesI noticed it after some rewording with data-test worked so i ended up with this in the html.
<div id="twig-vars" data-newroute="{{ URL_Symfony_dev }}"></div>
And in my JS:var test= $('#twig-vars').data('newroute');
alert(test);
And THAT WORKS. I am new to this place and i dont know if i should edit the original question. Any help for it also appreciated.
EDIT: Using class(.) instead of id(#) will only capture the first html even if the attribute name is different. This means:
<div **class**="twig-vars" data-**test1**="{{ URL_Symfony_dev }}"></div>
<div **class**="twig-vars" data-**test2**="{{ URL_Symfony_dev }}"></div>
<div **class**="twig-vars" data-**test3**="{{ URL_Symfony_dev }}"></div>
var test1= $('.twig-vars').data('test1');
var test2= $('.twig-vars').data('test2');
var test3= $('.twig-vars').data('test3');
alert(test1);//output-> correct result
alert(test2);//output-> undefined
alert(test3);//output-> undefined
Related Topics
How to Call a Dynamically-Named Method in JavaScript
Why Is 'This' Undefined Inside Class Method When Using Promises
Jquery Smooth Scroll to an Anchor
Create Regexps on the Fly Using String Variables
Understanding JavaScript Promises; Stacks and Chaining
How to Chain These Functions Together with Promises
How to Distinguish Mouse "Click" and "Drag"
Jquery "On Create" Event for Dynamically-Created Elements
Basic Authentication with Fetch
Understanding JavaScript Promise Object
Cross-Browser Bookmark/Add to Favorites JavaScript
How to Add a "Readonly" Attribute to an <Input>
Difference Between Obtrusive and Unobtrusive JavaScript
Passing a PHP Variable to JavaScript in a Blade Template