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 >grade</i>';
increment ;
}
while(max > rate) {
starHTML = '<i >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 ).
CodePudding user response:
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.