Search code examples
springspring-bootthymeleaf

How to send thymeleaf value to spring controller


I am new with Spring and Thymeleaf. I am building a simple app to rate films and series. I have a html table with some information about serie including current rating. To display a current rate I need to send a serie id to my spring controller, but don't know how to do that. I was trying with th:with="serie_Id=${tempSerie.id}" but it doesn't work as I wish. The theId variable is always null. Here is my controller:

  @GetMapping("/list")
public String listSeries(@Param("serie_Id") Integer theId, Model theModel, @Param("keyword") String keyword){


    String username;


    Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    if(principal instanceof UserDetails){
        username = ((UserDetails)principal).getUsername();
    }
    else {
        username = principal.toString();
    }
    System.out.println(theId);
    User theUser = userService.findByUsername(username);
    Serie theSerie = serieService.findById(theId);

    int theRating;

    try{
        theRating = serieRatingService.findByUserAndSerie(theUser, theSerie).getSerieRating();
    }
    catch (NullPointerException e){
        theRating = 0;
    }

    List<Serie> theSeries = serieService.findAll(keyword);
    theModel.addAttribute("serie_Id", theId);
    theModel.addAttribute("series", theSeries);
    theModel.addAttribute("ratings", theSeries);
    theModel.addAttribute("keyword", keyword);
    theModel.addAttribute("theRating", theRating);

    return "series/list-series";
}

Here is snippet of my view:

 <table class="table table-bordered table-striped">
    <thead class="thead-dark">
    <tr>
        <th>Title</th>
        <th>Release Year</th>
        <th>Current Rate</th>
        <th>Action</th>

    </tr>
    </thead>

    <tbody>
    <tr th:each="tempSerie : ${series}">

        <td th:text="${tempSerie.title}" />
        <td th:text="${tempSerie.release_year}" />
        <td>

            <p><svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-star-fill" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
                <path d="M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.283.95l-3.523 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z"/>
            </svg><span th:with="serie_Id=${tempSerie.id}" th:text="${theRating}"></span></p>


        </td>
        <td>
            <div sec:authorize="hasRole('ROLE_ADMIN')">


                <a th:href="@{/series/showFormForUpdate(serieId=${tempSerie.id})}"
                   class="btn btn-info btn-sm">
                    Update
                </a>

                <a th:href="@{/series/delete(serieId=${tempSerie.id})}"
                   class="btn btn-danger btn-sm"
                   onclick="if (!(confirm('Are you sure?'))) return false">
                    Delete
                </a>
            </div>
            <div sec:authorize="hasRole('ROLE_USER')">

                <a th:href="@{/serieRatings/showFormForSerieRate(serieId=${tempSerie.id})}"
                   class="btn btn-warning">
                    Rate
                </a>

            </div>
        </td>
    </tr>

    </tbody>

</table>

I want my table to be like this. The serie id is just hard-coded. https://i.sstatic.net/3w7yQ.png


Solution

  • I added user and my services to model and used them in the view. Maybe this approach is not the best but it works a desired. My controller:

     @GetMapping("/list")
    public String listSeries(Model theModel, @Param("keyword") String keyword){
    
        String username;
    
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if(principal instanceof UserDetails){
            username = ((UserDetails)principal).getUsername();
        }
        else {
            username = principal.toString();
        }
    
        User theUser = userService.findByUsername(username);
    
        List<Serie> theSeries = serieService.findAll(keyword);
    
        theModel.addAttribute("series", theSeries);
        theModel.addAttribute("keyword", keyword);
        theModel.addAttribute("theService", serieService);
        theModel.addAttribute("theRatingService", serieRatingService);
        theModel.addAttribute("user", theUser);
    
        return "series/list-series";
    }
    

    Snippet of my view:

            <td th:text="${tempSerie.title}" />
            <td th:text="${tempSerie.release_year}" />
            <td>
    
                <p><svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-star-fill" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
                    <path d="M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.283.95l-3.523 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z"/>
                </svg><span th:text="${theRatingService.findByUserAndSerie(user, theService.findById(tempSerie.id))?.getSerieRating()}"></span></p>
    
    
            </td>