简体   繁体   中英

How can I input HTML from JS function into Thymeleaf th:text?

I want to show rating based on the returned value of an object method. JS function - returns an html that contains amount of stars based on a parameter. Parameter - digit up to 5. I get it from calling employee.getUser().getAvgGrade().

Here is a table I have

            <table>
            <thead>
            <tr>
                <th>Name</th>
                <th>Rating</th>
                <th>Schedule</th>
            </tr>
            </thead>
<tbody>
    <tr th:each="employee:${employees}">

        <td th:text="${employee.getUser().getFullName()}"></td>
        <td th:text="${employee.getUser().getAvgGrade()}"></td>
        <td th:text="${employee.getTimeBegin() + ' - ' + employee.getTimeEnd()}"></td>

    </tr>
    </tbody>
        </table>

Here is a JS function that returns HTML

    function star(rate) {
    var starHTML = '';
    var rate = parseInt(rate);
    var increment = 0;
    var max = 5;

    while(increment < rate) {
        starHTML += '<i class="material-icons orange">grade</i>';
        increment++;
    }

    while(max > rate) {
        starHTML += '<i class="material-icons gray">grade</i>';
        max--;
    }
    return starHTML;
};

CSS for stars

<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet">

I want to call this function with the integer from getAvgGrade() ( second th:text ) and place the html it returns as th:text ( so the cell holds the stars ).

You can simplify this by using Thymeleaf to manage generating the stars, instead of using JavaScript.

Here is that approach:

First, some Java test data (a simplified version of your data, just for this demo):

List<UserRating> userRatings = new ArrayList<>();
userRatings.add(new UserRating("Abel", 2));
userRatings.add(new UserRating("Baker", 3));
userRatings.add(new UserRating("Charlie", 4));

So, we have 3 users with grades of 2, 3, and 4.

The Thymeleaf template is as follows:

<table>
    <thead>
        <tr>
            <th>Name</th>
            <th>Avg Grade</th>
            <th>Stars</th>
        </tr>
    </thead>
    <tbody>
        <tr th:each="user : ${users}">
            <td th:text="${user.name}"></td>
            <td th:text="${user.grade}"></td>
            <td>
                <th:block th:each="star,iterStat : ${#numbers.sequence(1,5)}">
                    <span th:if="${user.grade} >= ${iterStat.count}" 
                          class="material-icons" 
                          style="color: orange;">grade</span>
                    <span th:if="${user.grade} < ${iterStat.count}" 
                          class="material-icons" 
                          style="color: grey;">grade</span>
                </th:block>
            </td>
        </tr>
    </tbody>
</table>

The result of applying the test data to the template is this:

在此处输入图片说明

Notes

This approach does not require any JavaScript.

I assumed the average grades are integers, but this also works for decimal values.

To build 5 stars I use a predefined sequence counting from 1 to 5:

${#numbers.sequence(1,5)}

I use an iteration status variable called iterStat to track progress through this sequence of 5 integers.

I compare this iterStat.count value (the current position in the iteration) with the average grade value. I use this to determine if the star should be orange or grey.

The th:block element is a special Thymeleaf element. It can be convenient to use in certain iteration situations. More details here .


You can certainly implement this in other ways - for example, by calling a JavaScript function after the table has been drawn - but that would involve more JavaScript code - your function, plus extra code to iterate the table values in JavaScript.

I would recommend the above approach instead. But I understand, if that may not be what you want, or if it may not fit into your overall approach for some reason.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM