<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>관리자 화면</title>
</head>
<body>
<h1>카테고리 관리</h1>
<div th:replace="/fragments/layout.html :: fragment-admin-body-menu"></div>
<div>
<a href="/admin/main.do">관리자 메인</a>
|
<a href="/admin/member/list.do">회원 관리</a>
|
<a href="/admin/category/list.do">카테고리 관리</a>
|
<a href="#">강의 관리</a>
|
<a href="/member/logout">로그아웃</a>
<br/>
<hr/>
</div>
<div class="list">
<table>
<thead>
<tr>
<th> ID </th>
<th>
카테고리명
</th>
<th>
순서
</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</body>
</html>
<div>
<a href="/admin/main.do">관리자 메인</a>
|
<a href="/admin/member/list.do">회원 관리</a>
|
<a href="#">카테고리 관리</a>
|
<a href="#">강의 관리</a>
|
<a href="/member/logout">로그아웃</a>
<br/>
<hr/>
</div>
이 부분들을 다 아래와 같이 수정
<div th:replace="/fragments/layout.html :: fragment-admin-body-menu"></div>
<a href="/admin/category/list.do">카테고리 관리</a>
반영이 잘 안될때는 target
폴더를 지우면 되는건가?
바로 추가할 수 있도록 list.html 수정
<div>
<form method="post" action="/admin/category/add.do">
<input type="text" name="categoryName" required placeholder="카테고리명 입력">
<button type="submit">추가</button>
</form>
</div>
@PostMapping("/admin/category/add.do")
public String add(Model model, CategoryInput parameter) {
return null;
}
add를 수행할 수 있는 CategoryInput 생성
@Data
public class CategoryInput {
String categoryName;
long id;
int sortValue;
boolean usingYn;
}
카테고리를 저장하기 위한 entity 생성
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Data
@Entity
public class Category {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
String categoryName;
int sortValue; // 카테고리 순서
boolean usingYn; // 사용 가능 여부 설정
}
카테고리 내용 저장을 위한 CategoryRepository 생성
public interface CategoryRepository extends JpaRepository<Category, Long> {
}
카테고리 컬럼 자동 생성!
UI에서 데이터를 저장하는 서버쪽 crud를 서비스 이용해서 생성!
public interface CategoryService {
List<CategoryDto> list();
/**
* 카테고리 신규 추가
*/
boolean add(String categoryName);
/**
* 카테고리 수정
*/
boolean update(CategoryDto parameter);
/**
* 카테고리 삭제
*/
boolean del(Long id);
}
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
public class CategoryDto {
Long id;
String categoryName;
int sortValue; // 카테고리 순서
boolean usingYn; // 사용 가능 여부 설정
}
인터페이스 구현
@RequiredArgsConstructor
@Service
public class CategoryServiceImpl implements CategoryService {
private final CategoryRepository categoryRepository;
@Override
public List<CategoryDto> list() {
List<Category> categories = categoryRepository.findAll(); // 리스트 가져오기
return CategoryDto.of(categories);
}
@Override
public boolean add(String categoryName) {
// 카테고리명이 중복인 경우 체크해야 함!
Category category = Category.builder()
.categoryName(categoryName)
.usingYn(true)
.sortValue(0)
.build();
categoryRepository.save(category);
return true;
}
@Override
public boolean update(CategoryDto parameter) {
return false;
}
@Override
public boolean del(Long id) {
return false;
}
}
if (categories != null) {
List<CategoryDto> categoryList = new ArrayList<>();
for(Category x : categories) {
categoryList.add(of(x));
}
return categoryList;
}
return null;
}
public static CategoryDto of(Category category) {
return CategoryDto.builder()
.id(category.getId())
.categoryName(category.getCategoryName())
.sortValue(category.getSortValue())
.usingYn(category.isUsingYn())
.build();
}
private final CategoryService categoryService;
@GetMapping("/admin/category/list.do")
public String list(Model model, MemberParam parameter) {
List<CategoryDto> list = categoryService.list();
model.addAttribute("list", list);
return "admin/category/list";
}
@PostMapping("/admin/category/add.do")
public String add(Model model, CategoryInput parameter) {
boolean result = categoryService.add(parameter.getCategoryName());
return "redirect:/admin/category/list.do";
}
<th>
사용여부
</th>
추가하고
<tbody>
<tr th:each="x : ${list}">
<td th:text="${x.id}">1</td>
<td th:text="${x.categoryName}">김이슬</td>
<td th:text="${x.sortValue}">010-1111-2222</td>
<td>
<p th:if="${x.usingYn}">Y</p>
</td>
</tr>
</tbody>
추가하고 마지막으로 css 추가!
<style>
.list table {
margin-top: 20px;
width: 100%;
border-collapse: collapse;
}
.list table th, .list table td {
border: solid 1px #000;
}
</style>
<script src="https://code.jquery.com/jquery-3.6.4.min.js" integrity="sha256-oP6HI9z1XaZNBrJURtCoUT5SUnxFr8s3BzRl+cbzUq8=" crossorigin="anonymous"></script>
<td>
<form name="deleteForm" method="post" action="/admin/category/delete.do">
<input type="hidden" name="id" th:value="${x.id}">
<button type="submit">삭제</button>
</form>
</td>
<script>
$(document).ready(function () {
$('form[name=deleteForm]').on('submit', function () {
if (!confirm(' 카테고리를 삭제하시겠습니까? ')) {
return false;
}
});
});
</script>
확인 누르면 페이지 이동!
@PostMapping("admin/category/delete.do")
public String del(Model model, CategoryInput parameter) {
boolean result = categoryService.del(parameter.getId());
return "redirect:/admin/category/list.do";
}
삭제 버튼 확인 누르면 list.do 페이지로 이동!
@Override
public boolean del(Long id) {
categoryRepository.deleteById(id);
return true;
}
삭제 완료
카테고리 목록 내용이 없을경우
<tr th:if="${#lists.size(list) < 1}">
<td colspan="5">
<p class="nothing">내용이 없습니다.</p>
</td>
</tr>
p.nothing {
text-align: center;
padding: 100px;
}
<td>
<div class="inline-div">
<button type="button">수정</button>
</div>
<div class="inline-div">
<form name="deleteForm" method="post" action="/admin/category/delete.do">
<input type="hidden" name="id" th:value="${x.id}">
<button type="submit">삭제</button>
</form>
</div>
</td>
.inline-div {
display: inline-block;
}
<td>
<input th:checked="${x.usingYn}" type="checkbox" th:id="'usingYn_' + ${x.id}" th:name="'usingYn_' + ${x.id}" value="true">
<label th:for="'usingYn_yes_' + ${x.id}">사용</label>
</td>
아이디 값 가져오기
<td th:text="${x.id}">
<input type="hidden" name="id" th:value="${x.id}">
<p th:text="${x.id}"></p>
</td>
삭제와 수정한 값을 폼으로 가져옴
<form name="updateform" method="post" action="/admin/category/update.do">
<input type="hidden" name="id">
<input type="hidden" name="categoryName">
<input type="hidden" name="sortValue">
<input type="hidden" name="usingYn">
</form>
$('button.update-button').on('click', function () {
if (!confirm('카테고리를 수정하시겠습니까?')) {
return false;
}
var $this = $(this);
var $tr = $this.closest('tr');
var id = $tr.find('input[name=id]').val();
var categoryName = $tr.find('input[name=categoryName]').val();
var sortValue = $tr.find('input[name=sortValue]').val();
var usingYn = $tr.find('input[type=checkbox]')[0].checked;
$updateForm = $('form[name=updateForm]');
$updateForm.find('input[name=id]').val(id);
$updateForm.find('input[name=categoryName]').val(categoryName);
$updateForm.find('input[name=sortValue]').val(sortValue);
$updateForm.find('input[name=usingYn]').val(usingYn);
$updateForm.submit();
});
<td>
<input th:value="${x.sortValue}" type="text" name="sortValue">
@PostMapping("admin/category/update.do")
public String update(Model model, CategoryInput parameter) {
boolean result = categoryService.update(parameter);
return "redirect:/admin/category/list.do";
}
boolean update(CategoryInput parameter);
@Override
public boolean update(CategoryInput parameter) {
Optional<Category> optionalCategory = categoryRepository.findById(parameter.getId());
if (optionalCategory.isPresent()) {
Category category = optionalCategory.get();
category.setCategoryName(parameter.getCategoryName());
category.setSortValue(parameter.getSortValue());
category.setUsingYn(parameter.isUsingYn());
categoryRepository.save(category);
}
return true;
}
private Sort getSortBySortValueDesc() {
return Sort.by(Sort.Direction.DESC,"sortValue");
}
@Override
public List<CategoryDto> list() {
List<Category> categories = categoryRepository.findAll(getSortBySortValueDesc()); // 리스트 가져오기
return CategoryDto.of(categories);
}