0

I use a normal html table for iterating through a list of objects in thymeleaf.

I want to change the class of the <tr> tag changing by the value of the providerResponse.status. But this value is first known after the start of the iteration. So I think its not usable in the same <tr> row definition.

I also used a local variable for switching the <td> class. But the local variable is just usable in the context of the used html attribute. So I needed to write the code several times.

Is it possible to use the local variable in the full context of the table?

Is there a way to reduce the duplication of the same code?

<tr th:each="providerResponse : ${providerResponses}">

  <th:block th:switch="${providerResponse.status}"
    th:with="temp='active'">
    <th:block th:case="'AVAILABLE'">
      <th:block th:with="temp='success'">
        <td th:class="${temp}" th:text="${providerResponse.executeDate}"></td>
        <td th:class="${temp}" th:text="${providerResponse.provider}"></td>
        <td th:class="${temp}" th:text="${providerResponse.status}"></td>
      </th:block>
    </th:block>
    <th:block th:case="'UNKNOWN'">
      <th:block th:with="temp='danger'">
        <td th:class="${temp}" th:text="${providerResponse.executeDate}"></td>
        <td th:class="${temp}" th:text="${providerResponse.provider}"></td>
        <td th:class="${temp}" th:text="${providerResponse.status}"></td>
      </th:block>
    </th:block>
  </th:block>
</tr>
Mr Lister
  • 45,515
  • 15
  • 108
  • 150
Patrick
  • 12,336
  • 15
  • 73
  • 115

3 Answers3

1

As long as there are only two classes (statuses) you need to consider, a simple if check would be enough. Here's an example:

<tr th:each="providerResponse : ${providerResponses}">
    <th:block
        th:with="temp = ${providerResponse.status == 'AVAILABLE'} ? success : danger">
        <td th:class="${temp}" th:text="${providerResponse.executeDate}"></td>
        <td th:class="${temp}" th:text="${providerResponse.provider}"></td>
        <td th:class="${temp}" th:text="${providerResponse.status}"></td>
    </th:block>
</tr>

This code only checks if the status is set to 'AVAILABLE'. If there are more than two possible outcomes and you want to avoid the duplicate code, I'd say you should write a simple jquery function that appends the proper class to your code.

Edit: Here's a simple jQuery example for your needs:

<script>
    function setClassByStatus(status, id) {
        console.log(status);
        if(status == "AVAILABLE"){
            $('td[name=' +id +']').addClass("success");
        }else if(status == "UNKNOWN"){
            $('td[name=' +id +']').addClass("danger");
        }else if(status == "TEST"){
            $('td[name=' +id +']').addClass("test");
        }
    }
</script>

<tr th:each="providerResponse : ${providerResponses}">
    <script th:inline="javascript">
            /*<![CDATA[*/
            $(function() {
                setClassByStatus([[${providerResponse.status}]], [[${providerResponse.yourId}]]);
            });
            /*]]>*/
        </script>
    <td th:name="${providerResponse.yourId}" th:text="${providerResponse.executeDate}"></td>
    <td th:name="${providerResponse.yourId}" th:text="${providerResponse.provider}"></td>
    <td th:name="${providerResponse.yourId}"
        th:text="${providerResponse.status}"></td>
</tr>
Lukehey
  • 1,284
  • 1
  • 11
  • 20
  • Thanks for your answer. For two possibilites its a good solution, but like you said, I need it for more than two. And I think its difficult to use the variable in the `` tag instead of `` tag right? – Patrick Feb 23 '16 at 13:20
  • Posted a jQuery example that can handle more than two statuses – Lukehey Feb 23 '16 at 13:58
0

If you want to add some class param to basic class You can use

<tr th:each="providerResponse : ${providerResponses}">
    <th:block
        th:with="temp = ${providerResponse.status == 'AVAILABLE'} ? success : danger">
        <td class="baseClass" th:classappend="${temp}" th:text="${providerResponse.executeDate}"></td>
        <td class="baseClass" th:classappend="${temp}"  th:text="${providerResponse.provider}"></td>
        <td class="baseClass" th:classappend="${temp}"  th:text="${providerResponse.status}"></td>
    </th:block>
</tr> 

see answer

makson
  • 1,975
  • 3
  • 23
  • 31
0

It's not very nice, but it is possible to nest ternary operators to create your own if-else-if block. I'd prefer this over using JQuery:

<tr th:each="providerResponse : ${providerResponses}">
    <th:block th:with="temp= ${providerResponse.status == 'AVAILABLE'} ? success 
                    : (${providerResponse.status == 'FOO'} ? otherClass1 
                    : (${providerResponse.status == 'BAR'} ? otherClass2 
                    : (${providerResponse.status == 'UNKNOWN'} ? danger
                    : defaultClass)))">
        <td class="baseClass" th:classappend="${temp}" th:text="${providerResponse.executeDate}"></td>
        <td class="baseClass" th:classappend="${temp}"  th:text="${providerResponse.provider}"></td>
        <td class="baseClass" th:classappend="${temp}"  th:text="${providerResponse.status}"></td>
    </th:block>
</tr>
Raj
  • 125
  • 1
  • 11