#1. 날짜 선택 구현하기
웹에서 사용자가 날짜를 선택 해야하는 일이 종종 있다.
예를들어 예약시스템의 경우가 대표적일 것이다.
구현 방법은 매우 간단하다.
<input type="date" />
<input> 태그의 타입을 date로 지정해주기만 하면 된다.
하지만 이렇게만 구현해 놓으면 문제가 하나 있는데, 그것은 사용자가 지난 날짜를 선택해서 예약할 수 있다는 것이다.
물론 지난 날짜를 선택하면 예약이 안되게 따로 구현하는 것도 방법이지만,
아예 선택할 때 부터 지난 날짜는 선택하지 못하게 막아버리면 더 괜찮지 않을까 하는 생각으로 구현해보았다.
그럼 어떻게 구현해야할까?
1. 최소날짜 지정
<input type="date" min={"yyyy-mm-dd"} />
- date 타입에 사용 가능한 속성중에 min이라는 속성이 있는데, 이 속성에 문자열로 날짜를 지정하면 그 날짜를 기준으로 지난 날짜들은 disabled 처리가 되어 선택할 수 없다. (ex "2022-09-25")
- 값은 반드시 "yyyy-mm-dd" 형식이여야 적용된다. (2022-9-25로 값을 넣으면 적용안됨)
2. 날짜 구하는 함수 생성
/**
* @discription 내일 날짜 구하는 함수
* @return yyyy-mm-dd
*/
const tomorrow = () => {
// date 객체 생성
const date = new Date();
// date 객체에서 현재 년도를 구한다
const year = date.getFullYear();
// date 객체에서 현재 월을 구한다 (getMonth는 0부터 시작하기 때문에 +1을 해준다)
let month = date.getMonth() + 1;
// date 객체에서 오늘 날짜를 구한다
const today = date.getDate();
// 오늘 날짜에 +1을 하여 내일 날짜를 구한다
let tomorrow = today + 1;
// "yyyy-mm-dd" 형식으로 값을 전달 해야하기 때문에 삼항연산자를 활용해 10보다 작을 경우 앞에 0을 붙인다
return `${year}-` + (month > 9 ? `${month}-` : `0${month}-`) + (tomorrow > 9 ? tomorrow : `0${tomorrow}`);
};
export { tomorrow };
- 보통 당일 예약을 허용하는 시스템이 아니고서는 내일부터 예약 가능하게 구현한다. (당일 예약을 허용하려면 return문에 tomorrow 대신에 today 변수를 대입하면 된다.)
- 위에서 언급했듯이 min속성에 값을 넣을 때는 "yyyy-mm-dd" 형식으로 넣어야 한다.
- Date 객체에서 얻은 날짜는 10 이하일 경우 한자리 수로 나타낸다.(예를들어 22년 9월 2일이면 2022-9-2 이런식으로 나온다)
- 그렇기 때문에 "yyyy-mm-dd"형식을 맞추기 위해 삼항연산자를 활용해 10보다 작을 경우 앞에 0을 붙여준다.
3. 마지막 날에 대한 대비
위 방법대로 하면 이론상으로는 문제가 없었다. (내 머리의 한계인듯)
하지만 문제가 하나 있었는데, 해당 월의 마지막 날 인데도 다음달로 넘기지 않고 없는 날짜가 지정 되어버린 것이다.
예를들어 오늘 날짜가 2022-08-31이면 2022-09-01로 넘어가지 않고 2022-08-32가 되어버린 것이다..(32일은 없어요...)
해결 방법을 고민하다가 해당 월의 마지막 날을 구해 오늘 날짜와 같다면 month와 tomorrow를 직접 변경하는 방식으로 해결해보았다. (month 와 tomorrow만 let으로 선언한 이유)
/** 해당 월의 마지막 날이면? */
// Date객체에서 마지막 날을 구해 오늘 날짜와 같은지 비교한다
if(new Date(year, month, 0).getDate() === today) {
// 다음달로 넘기기 위해 +2를 한다 (month는 0부터 시작하기 때문에 이번달을 구할 땐 +1, 다음달은 +2)
month = date.getMonth() + 2;
// 오늘날짜 - (오늘날짜 -1)을 한 날짜로 변경 (31일 이면 30을 빼 1이 남도록 한다, 월의 1일)
tomorrow = date.getDate() - (date.getDate() - 1);
}
// return문 위에 작성된 코드를 따로 발췌
- new Date(년, 월, 0)을 통해 해당 월의 마지막 날을 구할 수 있다. (마지막에 0을 생략하면 1일이 출력)
// 2100년 2월의 마지막 날 구하기
console.log(new Date(2100, 2, 0));
- 여기서 getDate()를 사용해 마지막 날짜만 추출해 오늘 날짜와 같다면 if문을 실행해 month와 tomorrow 값을 바꿔준다.
4. 함수적용
import { tomorrow } from '../경로';
<input type="date" min={tomorrow() || ''} />
- min 속성에 위에 작성한 내일 날짜를 구하는 함수를 적용한다.
- 함수에서 값을 제대로 전달받지 못할 때를 대비해서 오류가 나지 않도록 함수 또는 빈문자열을 받게 지정
구현결과
작성일 25일을 기준으로 지난 날짜와 해당 날짜는 선택이 안되고 내일 날짜부터 선택할 수 있는 것을 볼 수 있다.
'Extend > React' 카테고리의 다른 글
[React] axios interceptor 사용하기 (0) | 2022.10.13 |
---|---|
[React] React에서 .env 사용하기 (0) | 2022.09.29 |
[React] SPA 페이지 이동 시 스크롤 맨 위 유지하기 (1) | 2022.09.26 |
[React] Toggle List 구현하기 (0) | 2022.09.23 |
[React] option 태그 여러개 만들기 (0) | 2022.05.22 |