1

I am developing a simple Planning Poker MVC app using Java 11, Spring Boot 2.1.2 and Thymeleaf Spring 5.

The attached image shows the main HTML page. After login, the user submits a score. The request goes to a controller method, pasted below, where the score is persisted to a database. Then, the whole set of scores for the group are retrieved from the database as a list. Both the user's individual score and the list of group scores are added to the model and the user is forwarded to the poker.html page

@PostMapping("/score")
public String submitScores(@Valid SimplePoker simplePoker, BindingResult result, Model model) {
    SimplePoker poker = simplePokerRepository.save(simplePoker);
    model.addAttribute("poker_score", poker);

    Iterable<SimplePoker> scores = simplePokerRepository.findAll();
    model.addAttribute("scores", scores);
    return "poker";
}

On the poker.html page, a table is generated using a standard Thymeleaf pattern, as shown below: -

<div class="container" th:if="${not #lists.isEmpty(scores)}">
    <table class="table table-striped table-hover table-bordered table-responsive-md">
        <thead class="thead-dark">
        <tr>
            <th class="text-center, align-middle">Name</th>
            <th class="text-center, align-middle">Planning</th>
            <th class="text-center, align-middle">Business Risk</th>
            <th class="text-center, align-middle">Chance of Failure</th>
            <th class="text-center, align-middle">Total Risk</th>
        </tr>
        </thead>
        <tbody>
        <tr th:each="score: ${scores}">
            <td th:text="${score.name}"></td>
            <td th:text="${score.planningScore}"></td>
            <td th:text="${score.risk1Score}"></td>
            <td th:text="${score.risk2Score}"></td>
            <td th:text="${score.risk3Score}"></td>
        </tr>
        </tbody>
    </table>
</div>

This all works well, but of course the table only represents the results at the time the user made the request. I would like to add an 'Update Table' button just below the table (yellow highlighted area) that the user can click that will fetch a fresh set of data and update the table on the page with the latest results. As I am primarily a back-end developer, I am struggling a bit here and would really appreciate some guidance.

I think I would be able to create a crude solution, where clicking the button simply refreshes the entire page, but it would much more smooth to be able to update just the table. The icing on the cake would be if the table auto-updated every few seconds, omitting the need for the user to click the button. But as a first step, implementing a button to update the table would be brilliant.

Many thanks in advance for reading my post and for any assistance offered. Planning Poker app - the yellow highlight shows where an Update button could go for updating the table

1 Answer 1

3

You might want to look into htmx. It is a JavaScript library that allows to avoid writing JavaScript yourself for doing things like you need here.

You can add a period refresh like this:

<div hx-trigger="every 1s"
     hx-get="/table" >
</div>

You would add this to your Thymeleaf template on the initial render of the full page. After that htmx will do a GET on /table every 1 second.

In your controller, you should return the HTML that is needed to build the table. If the table is a Thymeleaf fragement, then you can re-use that fragment:

@Controller
public class MyController {
  @GetMapping("/table")
  public String getTable(Model model) {
    // first fill up your model using .addAttribute

    // return the fragment
    return "fragments :: table"
  }
}

This example does something similar. See also TodoMVC with Thymeleaf and HTMX for some extra background info on combining Thymeleaf with htmx.

Sign up to request clarification or add additional context in comments.

5 Comments

Many thanks Wim, that looks like a really neat idea. I will try it out and return to comment further!
I've really enjoyed reading the links you sent and your articles Wim, thank you! HTMX looks great. I have it working fine with a button: <button hx-get="/poker/table" hx-swap="outerHTML">Click Me</button>. However, I haven't yet been able to get hx-trigger working. This does nothing so far: <div hx-trigger="delay:2500ms" hx-get="/poker/table" ></div>. I will keep trying!
Can you try with hx-trigger="every 1s" ? See htmx.org/attributes/hx-trigger ("Polling" chapter)
Genius! That worked - big smiles here! Thank you so much Wim. I am so glad that you have introduced me to HTMX - it will revolutionise my approach to UI development!
Glad it solves your problem elegantly :) I updated the answer with the correct trigger statement.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.