Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PlayFramework HTML, variable into Javascript?

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 ?

like image 564
ticofab Avatar asked Jun 07 '15 12:06

ticofab


People also ask

How set HTML variable in JavaScript?

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.

Can HTML access JavaScript variable?

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.

How do you load a variable in HTML?

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.


2 Answers

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.

like image 67
Salem Avatar answered Sep 22 '22 22:09

Salem


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.

like image 30
bjfletcher Avatar answered Sep 22 '22 22:09

bjfletcher