Search code examples
javaspringthymeleaf

Display data on HTML using Thymeleaf


I would like to display the data I get from a search, personalized for my taste. At this moment, It is just plain text.

For example, I am searching for "Titanic", and I get the name, a few links, and some information from IMDB.

I have the following code:

search.html

<!DOCTYPE HTML>
<html xmlns:th="https://www.thymeleaf.org">
<head>
    <title>Getting Started: Handling Form Submission</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1>Form</h1>
<form action="#" th:action="@{/search}" th:object="${search}" method="post">
    <p>Message: <input type="text" th:field="*{content}" /></p>
    <p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
</form>
</body>
</html>

result.html

 <!DOCTYPE HTML>
<html xmlns:th="https://www.thymeleaf.org">
<head>
    <title>Getting Started: Handling Form Submission</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1>Result</h1>
<p th:text="'content: ' + ${main.content}"></p>
<a href="/search">Submit another message</a>
</body>
</html>

SearchController.java

    @Controller
public class SearchController {
    @GetMapping("/search")
    public String greetingForm(Model model) {
        model.addAttribute("search", new Main());
        model.addAttribute("main", new Main().getContent());
        return "search";
    }

    @PostMapping("/search")
    public String greetingSubmit(@ModelAttribute Main main) {
        return "result";
    }
}

and Main.java

    private String content;
private List<Result> finalList;
private List<Result> resultList;

public void setContent(String content) throws IOException {
 //code to compute finalList
}

public List<Result> getContent() {
    return this.finalList;
}

The main problem is that I have no ideea where to being with. finalList is a list of objects of type "Result", which have fields such as

private List<String> link = new ArrayList<>();
private String name;
private TitleProp titleProp;

and TitleProp has

private String trailer;
private String rating;
private String description;
private String genre;

I would like to manipulate each field to show it on a different way, such as a table with more rows, etc. Any link or sample of code would help me a lot to understand Thymeleaf and Spring Boot more.


Solution

  • I am coming with an answer to my question. I managed to get the result I wanted using Ajax, as SnakeDoc suggested. It was a long road, mostly because even if I had a working code, I spent a few hours searching for the Forbidden 403 error on ajax post request.

    So, for the js part:

        function ajaxPost() {
            // Here we prepare data for the JSON
            var formData = {
                moviename: $("#moviename").val()
            }
            $.ajax({
                type: "POST",
                contentType: "application/json",
                url: "MYURL",
                data: JSON.stringify(formData),
                dataType: 'json',
                success: function (result) {
                    {
                        $.each(result,
                            function (i, title) {
                                // do whatever you want with what you got from the server
                            });
                        console.log("Success: ", result);
                    }
                    console.log(result);
                },
                error: function (e) {
                    console.log("ERROR: ", e);
                }
    
            });
        }
    

    If this seems confusing, I access the fields you can see in my question by title.name, title.link, title.titleProp.description, etc, inside function (i, title)'s body. For the HTML,

            <label for="moviename" style="margin-right:5px">Title:</label>
            <input type="text" class="form-control" id="moviename" placeholder="Enter a title"/>
    

    Where moviename is the variable name you get from the input.

    Now, on the backend, we have to configure our path

        @PostMapping("/MYURL")
    public ResponseEntity<Object> addSearch(@RequestBody SearchCriteria searchCriteria)
            throws IOException {
         // do whatever you want to get a result. I used a custom class "SearchCriteria"
         // which has a getter and a setter for the field
         // **private String moviename;**
        return ResponseEntity.ok(THIS GETS SENT TO AJAX);
    }
    

    The main problem was that I have web.security, and you have two choices. First one, you disabling csrf. You have to add this line to your security config.

        http.csrf().disable();
    

    in protected void configure(HttpSecurity http) method.

    Or, you add csrf to the ajax request. More info on this topic was discussed here