Is it possible to import/add a simple JS function defined in frontend/scripts/exampleFile.js to Java Element so it is available in elements scope and possible to be called using Element::callJsFunction?
@JavaScript("./scripts/exampleFile.js")
public class T1 extends TextField {
public T1() {
getElement().callJsFunction("exampleFunction");
}
}
Of course this does not work, because importing exampleFile.js is gonna throw an error that ‘this’ is undefined (i would hope there is a way to reference the element). Even if it was var exampleFunction = ()... It would be defined in the global scope not in the element scope.
The use case is that i want to import a simple yet long JS function for an element that has direct acces to its DOM tree and properties.
What is the most elegant and simple solution to this problem? Is it even a good practice to do something like this?
It currently is possible to delcare a function using:
But the problem is that the actual function that I want to declare is several lines long and it would be broken over multiple concatenated strings in a Java file. Moreover i belive it is slower to send this whole function from server to the client side.
Below is how it looks like in practice. Another problem is maintaining this code is harder than JS.
Hi, one way would be to define your functions in the global scope (the window object) and then passing the this reference as an argument when calling them:
public class T1 extends TextField {
public T1() {
getElement().executeJs("myFunctions.exampleFunction(this)");
}
}
If you specifically need to use callJsFunction (I’d recommend the above instead), you could define a function that patches the given element reference and adds the functions to it.
Thanks Tomi. I wanted to add that when I created the topic I wasn’t aware that Java has Text Blocks. It allows to write one string over several lines which simplifies writing JS code in Java file.
Another approach is to use String blocks when you have Java 17 or 21 in use.
Here the caveat is that when executeJs is used the whole String is sent to client each time called. So this makes sense only when you have something like I have in the example which is called only when the component is attached.