일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- auto.create.topics.enable
- 람다식
- 익명 클래스
- yield
- 스파르타코딩클럽
- System.err
- 브릿지 메소드
- 자바스터디
- 정렬
- 로컬 클래스
- throwable
- Switch Expressions
- github api
- Study Halle
- 접근지시자
- 제네릭 타입
- 제네릭 와일드 카드
- 프리미티브 타입
- System.out
- System.in
- 합병 정렬
- docker
- junit 5
- 상속
- 항해99
- annotation processor
- raw 타입
- 바운디드 타입
- 함수형 인터페이스
- 자바할래
Archives
- Today
- Total
코딩하는 털보
11 to 9, Day 14 본문
11 to 9, Day 14
Today, ToDoList
- Toy Project - NGMA
- 일정 리스트 전체 선택
- 일정 리스트 페이징
- 일정 수정시 기본 데이터
- 짝꿍 취소하기
일정 전체 선택
thead의 체크박스
<th scope="col"><input class="form-check-input" type="checkbox" id="checkAllBox" onclick="checkAll();"></th>
checkAll() 함수
function checkAll() {
if ($('input#checkAllBox').is(':checked')==false) {
$('input[name="scheduleId"]').prop('checked',false);
} else {
$('input[name="scheduleId"]').prop('checked',true);
}
}
이상하게 attr()로 하면 개별로 변경된 엘리먼트들은 제어되지 않아서 prop으로 대신했다.
페이징
기존 메소드는 냅두고 Page 처리할 수 있도록 Pageable을 받는 새로운 repository 메소드
public interface ScheduleRepository extends JpaRepository<Schedule, Long> {
@Query("select s from Schedule s where s.owner.id = :accountId")
List<Schedule> findAllByOwner(Long accountId);
@Query("select s from Schedule s where s.owner.id = :accountId")
List<Schedule> findAllByOwner(Long accountId, Pageable pageable);
@Query("select s from Schedule s where s.owner.id = :accountId " +
"or s.owner.id = (select a.lover.id from Account a where a.id = :accountId) order by s.dateTime")
List<Schedule> findAllByCouple(Long accountId);
@Query("select s from Schedule s where s.owner.id = :accountId " +
"or s.owner.id = (select a.lover.id from Account a where a.id = :accountId) order by s.dateTime")
List<Schedule> findAllByCouple(Long accountId, Pageable pageable);
}
기본적으로 한 페이지에서 10개의 데이터 받아옴.
전체 페이지 수 계산을 위해서 컨트롤러를 추가했는데, 좋은 방법은 아닌거 같다.
@GetMapping
@ResponseBody
public List<Schedule> getSchedules(@AuthenticationPrincipal UserAccount userAccount,
@PageableDefault(size = 10) Pageable pageable) {
List<Schedule> schedules = scheduleService.getSchedules(userAccount, pageable);
return schedules;
}
@GetMapping("/page")
@ResponseBody
public int getSchedulePageInfo(@AuthenticationPrincipal UserAccount userAccount) {
List<Schedule> schedules = scheduleService.getSchedules(userAccount);
return schedules.size();
}
HTML 일정 테이블 아래에 부트스트랩에서 제공하는 page navi 추가
<nav aria-label="Page navigation">
<ul id="pageTab" class="pagination justify-content-end"></ul>
</nav>
처음 일정탭을 누르면 printSchedules()를 호출하여 전체 일정 수 와 기본적으로 1페이지의 10개 데이터를 가져온다.
가져온 일정 수로 각 page 버튼을 만든다. 각 page 버튼은 다시 loadSchedules() 함수로 데이터를 가져온다.
function printSchedules(pageNum) {
$.ajax({
url: "http://localhost:8080/schedule/page",
type: "GET",
dataType: "json",
success: function(data) {
printPageTab(data);
currentPage(pageNum);
},
error: function(e) {
alert(e.responseText);
}
});
loadSchedules(pageNum);
}
function printPageTab(size) {
var pageNum = Math.round(size/10);
for (let i = 1; i <= pageNum; i++) {
$('ul#pageTab').append('<li class="page-item"><a class="page-link" onclick="loadSchedules('+i+')">'+i+'</a></li>');
}
}
function loadSchedules(pageNum) {
$.ajax({
url: "http://localhost:8080/schedule",
type: "GET",
dataType: "json",
data: { page: pageNum-1 },
success: function(data) {
addScheduleRow(data);
},
error: function(e) {
alert(e.responseText);
}
});
}
현재 페이지 버튼 활성화를 위해 함수 추가/변경
function printPageTab(size) {
$('ul#pageTab').empty();
var pageNum = Math.round(size/10);
for (let i = 1; i <= pageNum; i++) {
$('ul#pageTab').append('<li class="page-item" value="'+i+'">' +
'<a class="page-link" onclick="loadSchedules('+i+');currentPage('+i+');">'+i+'</a></li>');
}
}
function currentPage(num) {
$('li.page-item').removeClass("active");
$('li.page-item[value='+num+']').addClass("active");
}
일정 추가/변경/제거 할때 처음 페이지로 돌아오는 버그 수정
loadSchedules() -> printSchedules(현재 페이지);
function modifyScheduleForm(){
$.ajax({
type: "POST",
url: "http://localhost:8080/schedule/modify",
contentType: "application/json",
cache:false,
data: JSON.stringify($("form#modifyScheduleForm").serializeObject()),
success: function(response){
$("#modifyScheduleModal").modal('hide');
var pageNum = $('li.page-item.active').val();
printSchedules(pageNum);
},
error: function(e){
alert(e.responseText);
}
});
}
function modifyScheduleForm(){
$.ajax({
type: "POST",
url: "http://localhost:8080/schedule/modify",
contentType: "application/json",
cache:false,
data: JSON.stringify($("form#modifyScheduleForm").serializeObject()),
success: function(response){
$("#modifyScheduleModal").modal('hide');
var pageNum = $('li.page-item.active').val();
printSchedules(pageNum);
},
error: function(e){
alert(e.responseText);
}
});
}
function removeScheduleForm(){
$.ajax({
type: "DELETE",
url: "http://localhost:8080/schedule",
contentType: "application/json",
cache:false,
data: JSON.stringify(checkedSchedules()),
success: function(response){
var pageNum = $('li.page-item.active').val();
printSchedules(pageNum);
},
error: function(e){
alert(e.responseText);
}
});
}
일정 변경 기본값
일정 변경 Modal 출력 전에 기본값으로 기존의 데이터가 입력되도록 변경
function showModifyScheduleModal(scheduleId) {
$.ajax({
url: "http://localhost:8080/schedule/"+scheduleId,
type: "GET",
dataType: "json",
success: function(data) {
modifyScheduleModalDefaultValue(data)
},
error: function(request) {
alert(request.responseText);
}
});
$('#modifyScheduleModal').modal('show');
}
function modifyScheduleModalDefaultValue(schedule) {
$('input#m-title').val(schedule.title);
$('input#m-place').val(schedule.place);
$('input#m-dateTime').val(schedule.dateTime.substr(0, 16));
$('input#m-personal').prop('checked',schedule.personal);
$('#modifyScheduleForm > .modal-body').append('<input type="hidden" name="id" value="'+schedule.id+'">');
}
짝꿍 취소하기
컨트롤러 테스트
@Test
@WithUserDetails(value = "jilee@example.com", setupBefore = TestExecutionEvent.TEST_EXECUTION)
public void cancelLover() throws Exception {
Account account = accountService.getUserByEmail("jilee@example.com");
Account lover = accountService.getUserByEmail("sjlee@example.com");
account.setLover(lover);
lover.setLover(account);
account.setLoverState(LoverState.COUPLED);
lover.setLoverState(LoverState.COUPLED);
mvc.perform(post("/account/lover/cancel"))
.andDo(print())
.andExpect(status().isOk());
assertThat(lover.getLoverState()).isEqualTo(LoverState.NOTHING);
assertThat(account.getLoverState()).isEqualTo(LoverState.NOTHING);
}
핸들러
@PostMapping("/lover/cancel")
@ResponseBody
public ResponseEntity<?> loverCancel(@AuthenticationPrincipal UserAccount userAccount) {
accountService.cancelLover(userAccount);
return ResponseEntity.ok("{}");
}
서비스
public void cancelLover(UserAccount userAccount) {
Account account = getUserById(userAccount.getAccountId());
Account lover = account.getLover();
account.setLover(null);
account.setLoverState(LoverState.NOTHING);
lover.setLover(null);
lover.setLoverState(LoverState.NOTHING);
}
버튼 추가 및 ajax 기능 추가
function matchedComment(data) {
$("div#loverStateResult").append('<p class="text-sm-start">'+data.name.toString()+'('+data.email.toString()+')님과 짝꿍입니다!</p>');
$("div#loverStateResult").append('<a class="btn btn-outline-secondary btn-sm" type="button" id="cancelLover" onclick="cancelLover();">취소하기</a>');
}
function cancelLover() {
$.ajax({
url: "http://localhost:8080/account/lover/cancel",
type: "POST",
dataType: "json",
success: function(data) {
alert("취소되었습니다.");
loadCoupleState();
},
error: function(request) {
alert(request.responseText);
}
});
}
Comments