26. 앵커 - 점프 투 스프링부트(게시판 만들기)Spring2023. 1. 7. 09:48
Table of Contents
728x90
728x90
해당 게시글은 점프 투 스프링부트 교재를 통한 개인 학습 용도이며 기초 세팅은 생략하였습니다.
자바 8, 스프링부트 2.7.7버전 입니다.
[ 앵커 ]
답글을 작성하거나 수정한 후 또는 추천 시 항상 페이지 최상단으로 스크롤이 이동되고 있다.
앵커(anchor) 태그를 이용해 해당 앵커 클릭 시 앵커로 스크롤이 이동되게 만들어 보자.
question_detail.html
(...생략...)
<!-- 답변 반복 시작 -->
<div class="card my-3" th:each="answer : ${question.answerList}">
<a th:id="|answer_${answer.id}|"></a>
<div class="card-body">
<div class="card-text" style="white-space: pre-line;" th:text="${answer.content}"></div>
(...생략...)
답변이 표시되는 구역에 답변 고유의 id값을 가진 앵커를 추가했다.
AnswerController
컨트롤러가 answer의 id를 리다이렉트하도록 하자.
(... 생략 ...)
public class AnswerController {
(... 생략 ...)
@PreAuthorize("isAuthenticated()")
@PostMapping("/create/{id}")
public String createAnswer(Model model, @PathVariable("id") Integer id,
@Valid AnswerForm answerForm, BindingResult bindingResult, Principal principal) {
Question question = this.questionService.getQuestion(id);
SiteUser siteUser = this.userService.getUser(principal.getName());
if (bindingResult.hasErrors()) {
model.addAttribute("question", question);
return "/question/question_detail";
}
Answer answer = this.answerService.create(question,
answerForm.getContent(), siteUser);
return String.format("redirect:/question/detail/%s#answer_%s",
answer.getQuestion().getId(), answer.getId());
}
(... 생략 ...)
@PreAuthorize("isAuthenticated()")
@PostMapping("/modify/{id}")
public String answerModify(@Valid AnswerForm answerForm, @PathVariable("id") Integer id,
BindingResult bindingResult, Principal principal) {
if (bindingResult.hasErrors()) {
return "/answer/answer_form";
}
Answer answer = this.answerService.getAnswer(id);
if (!answer.getAuthor().getUsername().equals(principal.getName())) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "수정권한이 없습니다.");
}
this.answerService.modify(answer, answerForm.getContent());
return String.format("redirect:/question/detail/%s#answer_%s",
answer.getQuestion().getId(), answer.getId());
}
(... 생략 ...)
@PreAuthorize("isAuthenticated()")
@GetMapping("/vote/{id}")
public String answerVote(Principal principal, @PathVariable("id") Integer id) {
Answer answer = this.answerService.getAnswer(id);
SiteUser siteUser = this.userService.getUser(principal.getName());
this.answerService.vote(answer, siteUser);
return String.format("redirect:/question/detail/%s#answer_%s",
answer.getQuestion().getId(), answer.getId());
}
}
AnswerService
컨트롤러에서 답변 객체가 필요하기 때문에 답변 생성의 타입을 Answer 엔티티로 변경한다.
(... 생략 ...)
public class AnswerService {
(... 생략 ...)
public Answer create(Question question, String content, SiteUser author) {
Answer answer = new Answer();
answer.setContent(content);
answer.setCreateDate(LocalDateTime.now());
answer.setQuestion(question);
answer.setAuthor(author);
this.answerRepository.save(answer);
return answer;
}
(... 생략 ...)
}
여기까지 잘 진행됐다면 완료된 것이다.
해당 화면에서 URL에 #answer_id가 추가되었고, 스크롤이 자동으로 해당 위치로 이동했다.
728x90
300x250
@mag1c :: 꾸준히 재밌게
2023.04 ~ 백엔드 개발자의 기록
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!