I have a image in my HTML file like this.
<img src="@routes.Assets.versioned("images/bell.png")" width="200", height="200" id = "symbolImg">
Image file is stored here.
Output
I was trying to change the image by having the following code in a typescript file.
document.getElementById("changeImageBtn").addEventListener("click", function () {
document.getElementById("symbolImg").setAttribute("src", "@routes.Assets.versioned('images/cherry.png')" );
document.getElementById("symbolImg").setAttribute("width", "300");
document.getElementById("symbolImg").setAttribute("height", "300");
});
But the image doesn't change. This is the output.
Edit 1
Also tried these ways with escape characters. Had no effect.
document.getElementById("symbolImg").setAttribute("src", "@routes.Assets.versioned(\"images/bell.png\")" );
.
document.getElementById("symbolImg").setAttribute("src", "@routes\.Assets\.versioned\(\"images/bell\.png\"\)" );
Correct and long solution
All Play URLs are managed through the router, so you can easily find and change them if you need.
In Twirl templates, you can get URL as @routes.Assets.versioned("images/bell.png")
because of the @...
is a dynamic statement that will be replaced by the server, so it became /assets/images/cherry.png
in the HTML output (well, if you will add sbt-digest
plugin, as it must be with versioned, then, in production, you will get something like /assets/images/aaf512631818fb-cherry.png
).
You can not use @
in the JavaScript client file just because it's a client and @
will not be dynamically replaced (yet, you can use it if you generate Javascript file dynamically as a Twirl template, then replacement will be done on the server in a moment of generation that JavaScript file)
The correct way to use Play routings on the client javascript is to generate them and load from the server. It's a special case described here: https://www.playframework.com/documentation/2.6.x/ScalaJavascriptRouting
In a short:
create a javascriptRoutes
action in a controller :
def javascriptRoutes = Action { implicit request =>
Ok(
JavaScriptReverseRouter("jsRoutes")(
routes.javascript.Assets.versioned
)
).as("text/javascript")
}
Add correponding route:
GET /javascriptRoutes controllers.Application.javascriptRoutes
Load the javascript routers
<script type="text/javascript" src="@routes.Application.javascriptRoutes"></script>
Now you can use them in the client javascript
document.getElementById("symbolImg").setAttribute("src",jsRoutes.controllers.Assets.versioned("images/favicon.png" ).url)
Incorrect and fast solution
Your solution is good only as a temporary fix
document.getElementById("symbolImg").setAttribute("src", "/assets/images/cherry.png" );
Be aware, in the case, if the project will run in a production environment with sbt-digest
plugin then your /assets/images/cherry.png
will be 404.
document.getElementById("symbolImg").setAttribute("src", "@routes.Assets.versioned('images/cherry.png')" );
instead of this try this
document.getElementById("symbolImg").src='your image path';