Thymeleaf, Javascript Inlining and Iteration

Chris Spiking

Using Spring MVC and Thymeleaf, I am constructing an html view with some javascript inside.

Within the page, th:each is used with iteration values to give a set of buttons a unique HTML id.

<td th:each="optionValue,iterStat : ${someObject.optionValues}">
  <button class="btn btn-default" th:id="${'optionBtn_' + (iterStat.count - 1)}" th:text="${optionValue.toString()}" />
</td>

My problem comes when trying to generate javascript that will use a jQuery reference to each button id.

In 'another' view resolution language, I would use the code:

<% for(var i = 0; i < someObject.optionValues.length; i++) { %>
    $('#optionBtn_<%- i %>').on("click", function() {
        doSomething('<%= someObject.optionValues[i] %>');
    });
<% } %>

(the above may not be 100% syntactically correct, but I hope you get the idea - what I'm trying to do is possible using the above style)

but in Thymeleaf, whilst I understand that I can use

th:inline="javascript"

to reference individual model items, I can't see how I can use a look to generate multiple jQuery function call definitions within a script block.

Any ideas? (I may be approaching the problem completely wrong, so am open to new ideas on that front too)

grid

I'll accept your invitation for new ideas and put on the table my methodology of approaching similar cases.
Clearly the problem is mostly about the communication between back-end and javascript data. The data that the javascript function needs as an argument in this case. Since html5's introduction of data attributes and the improved jQuery's efficiency with them in late versions, you may expose whatever back end data you want as attributes starting with "data-". This is valid according to html5. In jQuery you can access them as if they were jQuery data by translating the html naming convention to camelCase after reducing the initial "data-" pefix. (e.g. data-my-attribute = myAttribute). You can either access them in the original html convention (e.g. my-attribute). Its a matter of preference.

Then your html can be much cleaner:

<td th:each="optionValue,iterStat : ${someObject.optionValues}">
  <button class="btn btn-default" th:id="${'optionBtn_' + (iterStat.count - 1)}" th:text="${optionValue.toString()}" th:attr="data-my-func-attr=${optionValue}"/>
</td>

You can bind your event handlers then as:

$("button.btn").on("click", function() {
      buttonPressed($(this).data("my-func-attr"))
}

or similar.

This way you also keep your code cleaner and separate from the markup which is one principle of Unobtrusive JS

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related