Chris Wood
Chris Wood

Reputation: 65

Thymeleaf restrictions on onmouseover handler

I'm translating an ancient Struts/JSP application to use Spring 5 and Thymeleaf. The original application had a logic:iterate tag over the variable tt for rows in a table, and the cell was displaying a timestamp formatted on the back-end into the user's time zone, with a hover-over for UTC, like this:

<td style="cursor: pointer; cursor: hand"
    onmouseover="return escape('<bean:write name="tt"  property="ts_UTC" />' + ' UTC')">
    <bean:write name="tt" property="ts_User" /></td>

It generates output that looks like this:

<td style="cursor: pointer; cursor: hand"
    onmouseover="return escape('04/06/2020 11:14:50 AM' + ' UTC')">
    04/06/2020 07:14:50 AM</td>

After a few attempts and reading https://github.com/thymeleaf/thymeleaf/issues/705 and https://github.com/thymeleaf/thymeleaf/issues/707, I translated it to thymeleaf as follows:

<td style="cursor: pointer; cursor: hand"
    th:onmouseover="return escape( '[[${tt.ts_UTC}]] UTC');"
    th:text="${tt.ts_user}"></td>

The problem is the generated output looks like this:

<td style="cursor: pointer; cursor: hand"
    onmouseover="return escape( &#39;&quot;05\/04\/2015 08:05:24 PM&quot; UTC&#39;);"
    >05/04/2015 04:05:24 PM</td>

I have no idea where the &quot; is coming from, and I really want the &#39's to turn back into apostrophes. I'm stumped. How do I do this?

Upvotes: 0

Views: 1523

Answers (1)

andrewJames
andrewJames

Reputation: 22062

I don't know if this is a full solution - because I don't know how the text ends up being displayed by the mouseover event. But...

I suggest moving the event handler to a separate JavaScript function, to keep things a bit cleaner & more flexible.

Start with this:

<div style="cursor: pointer; cursor: hand"
     th:onmouseover="showMouseoverText( /*[[${tt.ts_UTC}]]*/ );"
     th:text="${tt.ts_user}">
</div>

What is that /*[[${tt.ts_UTC}]]*/ doing? It uses the escaped form of JavaScript inlining - the double-bracket notation. But it also wraps it in a comment, which makes use of Thymeleaf's JavaScript ntural templating. This ensures there are no syntax errors when processing the template.

Then somewhere in your <head>...</head> section, add this:

<script th:inline="javascript">
    function showMouseoverText( ts ) {
        console.log(ts + ' UTC');
        return escape(ts + ' UTC');
    }
</script>

The console line is just there to test. For me, I get my static test data printed as follows:

04/06/2020 11:14:50 AM UTC

I don't know if that final line return escape(ts + ' UTC') will work the way you need. I'm not sure what it does.

What you get in your HTML page will be the following:

The div:

<div style="cursor: pointer; cursor: hand"
     onmouseover="showMouseoverText( &quot;04\/06\/2020 11:14:50 AM&quot;);">John Doe
</div>

You will see the escaped / characters - and single quotes represented as &quot;. But the JavaScript function should handle these (as shown in the console output above). If not, then at least you can manipulate the data in your function, as needed.

Upvotes: 0

Related Questions