https://www.daterangepicker.com/
기술스택
- 자바 17
- 스프링부트
- JPA + QueryDSL
프로세스
- HTML에 Date Range Picker 라는 CDN API를 Import 해준다.
- HTML에 기간을 입력/설정할 수 있는 input 태그를 하나 만들어준다.
- 호출해온 위 API를 사용해서 JavaScript에서 날짜/달력에 관한 설정을 해준다.
- 해당 설정을 html의 input 태그에 적용하여 사용자가 input 태그를 클릭 했을 때 달력이 팝업되도록 한다.
- 팝업된 달력에서 사용자가 날짜/시간 값을 설정한 뒤 apply 버튼을 클릭 하면 trigger 되는 코드를 작성한다.
- 여기서 시작날짜/시간과 종료날짜/시간을 구분하여 두개의 인자로 컨트롤러에 쏴주고 백엔드 소스를 거친다.
- DB 조회를 할 때 입력받아온 값과 DB의 값과 대조한다.
- *시작날짜/시간보다는 같거나 크며, 종료날짜/시간보다는 작거나 같은 값을 조회한다.
- 선택적으로 뽑아온 데이터를 뿌려줌으로써 기간 조회가 완성되는 프로세스 이다.
1. HTML에 Date Range Picker 라는 CDN API를 Import 해준다.
<script type="text/javascript" src="https://cdn.jsdelivr.net/jquery/latest/jquery.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/momentjs/latest/moment.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.css" />
2. HTML에 기간을 입력/설정할 수 있는 input 태그를 하나 만들어준다.
<input type="text" name="datetimes" />
3. 호출해온 위 API를 사용해서 JavaScript에서 날짜/달력에 관한 설정을 해준다.
//외부 Javascript 파일을 사용할 경우
$(function() {
$('input[name="datetimes"]').daterangepicker({
timePicker: true,
startDate: moment().startOf('hour'),
endDate: moment().startOf('hour').add(32, 'hour'),
locale: {
format: 'M/DD hh:mm A'
}
});
});
//HTML내 Inline Script tag를 사용할 경우
<script>
$(function() {
$('input[name="datetimes"]').daterangepicker({
timePicker: true,
startDate: moment().startOf('hour'),
endDate: moment().startOf('hour').add(32, 'hour'),
locale: {
format: 'M/DD hh:mm A'
}
});
});
</script>
4. 해당 설정을 html의 input 태그에 적용하여 사용자가 input 태그를 클릭 했을 때 달력이 팝업되도록 한다.
제이쿼리 selector가 올바른 input 태그를 select 했는지 확인하면 되는데
이 예시의 경우 input 태그의 ID나 CLASS를 설정하지 않고 name으로만 설정했기 때문에
위 소스코드처럼 $('input[name="datetimes"]') 이런식으로 선택해주면 된다.
*ID를 설정해주는 것도 방법이다.
5. 팝업된 달력에서 사용자가 날짜/시간 값을 설정한 뒤 apply 버튼을 클릭 하면 trigger 되는/발동되는 코드를 작성한다.
아래는 API 공식 문서에서 어떻게 시작날짜/시간과 종료날짜/시간을 사용할 수 있는지 나와있는 예시이다.
$('#daterange').on('apply.daterangepicker', function(ev, picker) {
console.log(picker.startDate.format('YYYY-MM-DD'));
console.log(picker.endDate.format('YYYY-MM-DD'));
});
이 예시 코드를 사용해서 우리는 apply 버튼을 클릭했을 때 trigger되는/ 발동되는 코드안에서 시작/종료 날짜를 받아오는 방법을 알 수 있다.
제이쿼리 selector는 input 태그의 이름으로 받아왔기 때문에 selector를 일단 $('input[name="datetimes"]')로 바꾸고
저 시작/종료 날짜를 console.log에 찍는 것이 아니라 택배에 보낼 물건 포장해서 보내듯 변수에 담아 컨트롤러에 인자로 담아서 보내야 할 것이다.
심플하게 아래처럼 바꾸면 가능하다.
$('input[name="datetimes"]').on('apply.daterangepicker', function(ev, picker) {
let startDate = picker.startDate.format('YYYY-MM-DD');
let endDate = picker.endDate.format('YYYY-MM-DD');
});
6. 여기서 시작날짜/시간과 종료날짜/시간을 구분하여 두개의 인자로 컨트롤러에 쏴주고 백엔드 소스를 거친다.
위에서 이미 여기서 시작날짜/시간과 종료날짜/시간을 구분하여 두개의 변수에 각각 담아두었기에 이제 보낼일만 남았다.
$('input[name="datetimes"]').on('apply.daterangepicker', function (ev, picker) {
let startDate = picker.startDate.format('YYYY-MM-DD');
let endDate = picker.endDate.format('YYYY-MM-DD');
$.ajax({
type: 'GET',
url: '/경로',
data: {startDate: startDate, endDate: endDate},
success: function (data) {
if (data) {
//성공 시 하고싶은 작업
}
}
})
})
ajax를 이용하여 컨트롤러에 data를 담아 보내주는 작업은 위와 같은 샘플코드로 가능하며, 데이터 전송이 성공했을 때
발동하고 싶은 동작을 if(data){ 이곳에 적어주면 된다 }
* 필자 같은 경우 비동기로 화면 깜빡임 없이 기간 조회하여 선택된 데이터를 VIEW 테이블안에 알맹이만 갱신해주고 싶기 때문에 아래와 같은 코드를 사용했다.
if (data) {
$('#테이블을 감싸는 DIV ID').replaceWith(data);
}
컨트롤러
@GetMapping("/경로")
public String 함수명(Model model, Pageable pageable, @RequestParam(value = "startDate", required = false) String startDate, @RequestParam(value = "endDate", required = false) String endDate) {
Page<DTO 명> p;
p = 서비스 참조변수 명.서비스 내의 함수명(pageable, startDate,endDate);
model.addAttribute("뽑아온 데이터를 담을 변수", p);
// 페이징 관련하여 다른 함수에도 사용되어 전역 추출한 함수로 오늘의 주제와 상관 없기에 패스
// 페이징은 블로그의 페이징관련 글을 보고 구현해보기!
paging(model, p);
return "HTML 이름 :: #테이블을 감싸고 있는 DIV ID";
서비스
public Page<DTO 명> 함수명(Pageable pageable, String startDate, String endDate) {
return QueryDSL 인터페이스 참조변수명.함수명(startDate,endDate, pageable);
}
QueryDSL 인터페이스
Page<DTO 명> 함수명(String startDate, String endDate, Pageable pageable);
7. DB 조회를 할 때 입력받아온 값과 DB의 값과 대조한다.
*시작날짜/시간보다는 같거나 크며, 종료날짜/시간보다는 작거나 같은 값을 조회한다.
QueryDSL 구현체
@Override
public Page<DTO 명> 함수명(String startDate, String endDate, Pageable pageable) {
// 아래는 조건에 부합하는 데이터를 뽑아와서 List에 담아주기 위해 필요한 코드
List<DTO 명> content = jpaQueryFactory // (1) 조회한 결과 리스트에 담기
.selectFrom(static으로 import 해와야 하는 QueryDSL 전용 DTO의 참조변수 a.k.a QueryDSL참조변수)
.where(
QueryDSL참조변수.날짜가 있는 칼럼.goe(startDate).and(QueryDSL참조변수.날짜가 있는 칼럼.loe(endDate)))
.offset(pageable.getOffset()) // (2) 페이지 번호
.limit(pageable.getPageSize()) // (3) 페이지 사이즈
.fetch();
// 아래는 뽑아온 데이터를 페이징할 때 필요한 코드
JPAQuery<Long> count = jpaQueryFactory // (4) 검색 결과 값의 개수
.select(QueryDSL참조변수.count())
.from(QueryDSL참조변수)
.where(
QueryDSL참조변수.날짜가 있는 칼럼.goe(startDate).and(QueryDSL참조변수.날짜가 있는 칼럼.loe(endDate)));
return PageableExecutionUtils.getPage(content, pageable, count::fetchOne); // (6) PageImpl 반환
}
* 여기서 눈여겨볼점은 goe와 loe인데 예측했을 수도 있지만 greater or equal to, less or equal to라는 뜻으로
크거나 같다와 작거나 같다를 QueryDSL 라이브러리에서 쉽게 사용할 수 있도록 함수화 해놓은 것이다.
기본 문법에 관심이 많다면 이전 글을 참조하면 된다.
8. 다시 컨트롤러로 돌아와서 선택적으로 뽑아온 데이터를 HTML에 특정 DIV에만 뿌려줌으로써
비동기적인 기간 조회가 완성되는 프로세스 이다.
@GetMapping("/경로")
public String 함수명(Model model, Pageable pageable, @RequestParam(value = "startDate", required = false) String startDate, @RequestParam(value = "endDate", required = false) String endDate) {
Page<DTO 명> p;
p = 서비스 참조변수 명.서비스 내의 함수명(pageable, startDate,endDate);
model.addAttribute("뽑아온 데이터를 담을 변수", p);
// 페이징 관련하여 다른 함수에도 사용되어 전역 추출한 함수로 오늘의 주제와 상관 없기에 패스
// 페이징은 블로그의 페이징관련 글을 보고 구현해보기!
paging(model, p);
return "HTML 이름 :: #테이블을 감싸고 있는 DIV ID";
'개발자 전향 프로젝트' 카테고리의 다른 글
최신 Spring Security 사용법 - SecurityFilterChain (0) | 2023.02.09 |
---|---|
QueryDSL에서 Date 타입들의 Parsing and Comparing (StringTemplate, DateTemplate, & Expressions) (0) | 2023.02.03 |
Querydsl + Spring 3.0 + Java17 업데이트 내용! [Maven+Gradle] (10) | 2022.12.20 |
[JAVA] JPA 활용법 -2 (QueryDSL 활용해보기) (0) | 2022.12.06 |
자주 쓰이는 Ajax 활용법 - 부분 갱신 feat.@ResponseBody (0) | 2022.11.21 |