inline javascript with embedded variable

classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

inline javascript with embedded variable

hgrimm
Hi,
I'm trying to get thymeleaf to process a server side variable into inline javascript as below.

This works:
var company = /*[[${#authentication.details.company}]]*/ "defaultcompanyname";

This works:
var url =/*[[@{/c/companyplaceholder/a/users}]]*/ "companyurl";

This doesn't work, outputs var url =[[@{/c/${#authentication.details.company}/a/users}]];
var url =/*[[@{/c/${#authentication.details.company}/a/users}]]*/ "companyurl";

Thanks from a newbie,
Holly
Reply | Threaded
Open this post in threaded view
|

Re: inline javascript with embedded variable

Emanuel
Administrator
This post was updated on .
I'm not sure if you can put ${} expressions within @{} expressions (if they're not within brackets for creating query strings), so you might need to break them out and concatenate the separate pieces instead:

var url = /*[[@{/c/} + ${#authentication.details.company} + '/a/users']]*/ "companyurl";
Reply | Threaded
Open this post in threaded view
|

Re: inline javascript with embedded variable

hgrimm
It worked. Thanks, Emanuel!
Reply | Threaded
Open this post in threaded view
|

Re: inline javascript with embedded variable

blandger
Can someone give an advice.
How to create JS array with thymelead?
I have JS block I filled with data by JSTL <c:forEach....):

< script type="text/javascript" th:inline="javascript">
    var availableTypes = [
            <c:forEach items="${someTypes}" var="item">
                '${item.someName}',
            </c:forEach>
    ];
.... usage availableTypes variale
< /script>

'someTypes' is 'model attribute' List variable from web-flow.

How can I replace that with thymeleaf in HTML ?? Or is another painless approach possible?
Reply | Threaded
Open this post in threaded view
|

Re: inline javascript with embedded variable

blandger
As I got from thread - http://forum.thymeleaf.org/Dynamic-Javascript-generation-td4025091.html
there is not ability iterate over list equal to JSTL <c:forEach....

So I had to take suggested approach.
I change method for 'model attribute' List to be returned as simple String in Controller.
Internal method code is changed to JSON serialization of list (by gson).
Returned string inlined into HTML as variable:
< script th:utext="'var data = ' + ${jsonData}" >< /script >

Now it works as expected.
Reply | Threaded
Open this post in threaded view
|

Re: inline javascript with embedded variable

danielfernandez
Administrator
In reply to this post by blandger
@blandger

With a "normal" collection, Thymeleaf should automatically convert your collection into a JavaScript array. No need to iterate:

    <script type="text/javascript" th:inline="javascript">
      var availableTypes = /*[[${myCollection}]]*/ ['one_to_test','two_to_test'];
    </script>

(the "one_to_test" array is just there for javascript prototyping purposes, so that you can execute your script statically, without your server being running)

But you don't exactly want that, because you want to extract the "someName" property from each of the items in your collection, so you need to project it. And the syntax for that will depend on the expression language you are using.

So, if you are using Spring with Thymeleaf you will be using SpringEL as an expression language. And in this case, you will need:

    <script type="text/javascript" th:inline="javascript">
      var availableTypes = /*[[${someTypes.![someName]}]]*/ ['one_to_test','two_to_test'];
    </script>

Regards,
Daniel.
Reply | Threaded
Open this post in threaded view
|

Re: inline javascript with embedded variable

danielfernandez
Administrator
In reply to this post by hgrimm
@hgrimm

JavaScript inlining should work perfectly with @{...} expressions. Maybe in your first attempt you forgot to add the "th:inline="javascript"" attribute in your <script> tag?

Regards,
Daniel.
Reply | Threaded
Open this post in threaded view
|

Re: inline javascript with embedded variable

hgrimm
Hi Daniel,
Yes, I was using the th:inline="javacript" attribute.  The @{} expression worked fine, but I was trying to  place a ${} expression within a @{}.

I used the workaround suggested by @Emanuel , concatenate the @{} and ${} and it worked great.

Thanks for all your hard work on the project,
Holly
Reply | Threaded
Open this post in threaded view
|

Re: inline javascript with embedded variable

danielfernandez
Administrator

@hgrimm

Understood.

Expressions inside @{...} are allowed. But your expression didn't have the correct syntax. It should be:

    var url =/*[[@{'/c/' + ${#authentication.details.company} + '/a/users'}]]*/ "companyurl";

Regards,
Daniel.
Reply | Threaded
Open this post in threaded view
|

Re: inline javascript with embedded variable

blandger
In reply to this post by danielfernandez
@Daniel
Thank you for:
<script type="text/javascript" th:inline="javascript"> 
      var availableTypes = /*[[${someTypes.![someFieldName]}]]*/ ['one_to_test','two_to_test']; 
    </script> 
I switched controller's 'model attribute' methods back to returning 'full object' instances and that expression magically works!
I definitely need more time for digging into SpringEL docs and examples, because I don't understand why it works correctly.
Can you recommend something else in addition to:
http://static.springsource.org/spring/docs/3.0.x/reference/expressions.html
???
Reply | Threaded
Open this post in threaded view
|

Re: inline javascript with embedded variable

danielfernandez
Administrator
blandger wrote
Can you recommend something else in addition to:
http://static.springsource.org/spring/docs/3.0.x/reference/expressions.html
???
I'm afraid there is not much more documentation regarding Spring EL, other than that. But it should be no problem, because Spring EL is a quite compact expression languages, and that page basically explains the whole lot of possibilities.

Regards,
Daniel.