Merušić
Merušić

Reputation: 138

How to stay on the same page after form submit thymleaf and Spring boot?

Hello guys i have a question regarding what is mentioned in the title. Is it possible to stay on the same page and submit . I found something with javascript but it is not working for me because i m using thymleaf and spring boot. Or i just don't know how to adapt it to my case.

thymeleaf code:

<form th:action="@{/tweets/tweet}" th:object="${tweet}" method="post">
  <div class="row">
    <div class="col">
  <input type="text" th:field="*{content}" class="form-control"  placeholder="What's happening? Tell us!">
    </div>
    <div class="col">
      <input class="form-control" type="submit" value="Submit" />
    </div>
  </div>
</form>

the controller class:

@Controller
@RequestMapping("tweets")
@Slf4j
public class TweetController {

 private TweetService tweetService;

public TweetController(TweetService tweetService) {
this.tweetService = tweetService;
}


@PostMapping("/tweet")
@ResponseStatus(CREATED)
public Tweet tweet(@Valid @ModelAttribute("tweet")  Tweet tweet, Principal 
principal, BindingResult result) {
if(result.hasErrors()){

   //do somethign
}

if (!tweet.getContent().equals(null) && !tweet.getContent().equals("") && !tweet.getContent().isEmpty()) {
  tweetService.createTweet(tweet.getContent(), principal);
}

 }

 @GetMapping("/")
 public String goToIndex(Model model){
   model.addAttribute("tweet",new Tweet());
return "overview";
}

And i have server.context-path=/api I have one more additional question to this topic. When i wanted to redirect it to another page i was getting a blank page. Not an error not an exception just a blank page. Any help ? I m new to this.

Upvotes: 3

Views: 14064

Answers (3)

Paul Rambags
Paul Rambags

Reputation: 747

If you have a local URI /tweet that should result in a download of file tweet.zip while staying on the same page, do the following:

HTML

  <a th:href="@{|/tweet|}" download>Tweet</a>

Java Controller

@GetMapping("/tweet")
@ResponseBody
public FileSystemResource tweet(
    HttpServletResponse response
) {
    response.setHeader("Content-Disposition", "attachment; filename=tweet.zip");
    response.setContentType("application/zip");
    File zip = ...; // create your own ZIP file here
    return new FileSystemResource(zip);
}

Upvotes: 0

Alain Cruz
Alain Cruz

Reputation: 5097

Yes, this is possible using ajax. I would recommend doing it using jQuery though. So, if you would like to submit your form and stay in the same page, you could do the following.

HTML

<form id="tweet-form" th:action="@{/tweets/tweet}" th:object="${tweet}" method="post">
  <div class="row">
    <div class="col">
  <input type="text" th:field="*{content}" class="form-control"  placeholder="What's happening? Tell us!">
    </div>
    <div class="col">
      <input id="submit-form" class="form-control" type="button" value="Submit" />
    </div>
  </div>
</form>

Changes:

  • Added an id to the form.
  • Added an id to your input.
  • Change submit input's type for button.

jQuery

$('#submit-form').on('click', function() {
   var form = $('#tweet-form');
   $.ajax({
      url: form.attr('action'),
      data: form.serialize(),
      type: post,
      success: function(result) {
          // Do something with the response.
          // Might want to check for errors here.
      }, error: function(error) {
          // Here you can handle exceptions thrown by the server or your controller.
      }
   })
}

Controller

@PostMapping("/tweet")
@ResponseStatus(CREATED)
public Tweet tweet(@Valid @ModelAttribute("tweet")  Tweet tweet, Principal 
principal, BindingResult result) {
    if(result.hasErrors()){
        // Throw an exception or send a null Tweet.
    }
    if (!tweet.getContent().equals(null) && !tweet.getContent().equals("") && !tweet.getContent().isEmpty()) {
        tweetService.createTweet(tweet.getContent(), principal);
    }
    // You are returning a Tweet, so you must return something. 
    return tweet;
}

Your controller pretty much stay the same. Just remember to return something.

Upvotes: 3

dyslexit
dyslexit

Reputation: 773

Your example doesn't show what the tweet() method returns. It should return a Tweet object but doesn't have any return value. What are you attempting to do with that return value? If you're not handling it with Javascript someway, then get rid of @ResponseStatus(CREATED) and return a either a Model or a String pointing to your html file, like so:

@PostMapping("/tweet")
public String tweet(@Valid @ModelAttribute("tweet")  Tweet tweet, Principal 
principal, BindingResult result) {
    if(result.hasErrors()){
       //do somethign
    }

    if (!tweet.getContent().equals(null) && !tweet.getContent().equals("") && !tweet.getContent().isEmpty()) {
        tweetService.createTweet(tweet.getContent(), principal);
    }
    return "redirect:/name-of-html-file";
}

reference

If you want thymeleaf to handle the tweet and the HttpStatus you could instead return something along the lines of

ModelAndView model = new ModelAndView("your-view");
model.addAttribute(tweet);
model.setStatus(HttpStatus.CREATED);
return model;

Upvotes: 0

Related Questions