Reputation: 138
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
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
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:
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
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";
}
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