Imagine a simple Play Action defined as
def reactTest = Action {
request => Ok(views.html.hello("JOHN"))
}
and the hello.scala.html
looks like this, using a basic React.js example:
@(name: String)
....
<div id="example"></div>
<script type="text/jsx">
React.render(
<h1>Hello, @name!</h1>, <---- NAME PARAMETER USED HERE
document.getElementById('example')
);
</script>
This works fine and the result will be a 'Hello, JOHN!' page. Now, I know that the Scala code is executed on the server and the JS code on the client, but I am wondering if there would be a way to pass the @name
parameter to the same javascript (jsx) code if such code was in a separate .js file, and the <div>
would look like:
<div id="example"></div>
<script type="text/jsx" src="@routes.Assets.at("javascripts/hello.js"></script>
Would there be a way to pass the @name
parameter to the script in hello.js
?
To add the content of the javascript variable to the html use innerHTML() or create any html tag, add the content of that variable to that created tag and append that tag to the body or any other existing tags in the html.
In JavaScript, variables can be accessed from another file using the <script> tags or the import or export statement. The script tag is mainly used when we want to access variable of a JavaScript file in an HTML file.
Use the <var> tag in HTML to add a variable. The HTML <var> tag is used to format text in a document. It can include a variable in a mathematical expression.
You can save whatever you want in a global JS variable and then access it whenever you need.
For example, suppose you want to use a user object in your script. Having this html template
@(user: User)
<html>
<body>
<script>
var MyUserObject = {};
MyUserObject["name"] = "@user.name";
MyUserObject["age"] = @user.age;
</script>
<!-- ... -->
<script src="your_component.js"></script>
</body>
then in your included js you could do something like this:
(function(user) {
alert("Hello " + user.name + ". You are " + user.age + " years old");
})(MyUserObject);
You can then improve this using a map of the values you want to use or maybe rendering your object as JSON and parsing it on JS side:
def reactTest = Action {
request => Ok(views.html.hello(Json.toJson(user)))
}
// and then
@(user: String)
<html>
<body>
<script>
var MyUserObject = JSON.parse("@user");
</script>
<!-- ... -->
<script src="your_component.js"></script>
</body>
Not perfect, but better than rendering that on the JS files IMO.
The @routes...
in:
<script type="text/jsx" src="@routes.Assets.at("javascripts/hello.js"></script>
can be changed to:
@routes.YourController.withModel("javascripts/hello.js", model)
Then in YourController.withModel
you can preprocess hello.js
(such as using a templating sbt-web
plugin) with the model.
You can alternatively preprocess the JS
with the model before passing into this Scala HTML template.
If CPU/memory is a major concern, this can become advanced: e.g., mapping between predetermined models and preprocessed static JS
files, and referencing them instead. Or use other caching/CDN techniques.
So, these are just ideas in addition to the other answers given here. Enjoy.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With