프로젝트를 하면서 회원가입페이지 구현 중 주소입력창 구현을 위해 주소제공해주는 외부 API가 필요했다. 다음 카카오가 가장 편하다고 들어서 다음 API 가이드북을 통해 사용법을 익힌뒤 적용 해보았다.
<script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
<script>
new daum.Postcode({
oncomplete: function(data) {
// 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분
}
}).open();
</script>
1)팝업을 이용하여 도로명 주소와 지번 주소 모두 보여주기
기본적인 팝업을 이용하여 사용자가 선택한 주소의 도로명 주소와 지번 주소를 모두 보여주는 방식
2)iframe을 이용하여 레이어 띄우기
모바일웹에서는 팝업을 띄우는게 부담스러울 수도 있으니, 아래 코드와 같이 특정 element에 크기를 지정하여 iframe으로 끼워넣는 방식을 이용가능
3)iframe을 이용하여 페이지에 끼워 넣기
화면내에 끼워넣는 방식일 경우, 내부 스크롤이 거슬릴수도 있습니다. 이때 onresize 속성을 추가해서 iframe 높이를 조절하면 스크롤이 사라짐
daum.Postcode의 생성자 속성들은 아래와 같습니다.
💻반환되는 데이터 값
| 속성 | 값 | 속성정보 |
|---|---|---|
| zonecode | 13494 | 국가기초구역번호 |
| address | 경기 성남시 판교역로 235 | 기본 주소 |
| addressEnglish | 235 Pangyoyeok-ro, Bundang-gu | 기본 영문 주소 |
| buildingName | 혜강빌딩 | 건물명 |
| bname | 갈산동 | 법정동/법정리 이름 |
| addressType | R/J | 검색된 기본 주소 타입: R(도로명), J(지번) |
검색 결과로 인해 우편번호 서비스의 화면 크기가 변한 경우, 화면 크기 정보를 받아서 처리할 콜백 함수를 정의하는 부분
size 파라미터의 width의 경우 외부 wrapper DOM의 크기에 영향을 받기 때문에, 최초 렌더링 값으로 유지되며, height 값은 수시로 변하기 때문에 이 height 값을 이용하고자 할때 사용하는 것을 추천
new daum.Postcode({
onresize: function(size) {
//size는 우편번호 찾기 화면의 크기 데이터 객체
}
});
우편번호 찾기 화면을 팝업으로 띄운 후, 검색 결과를 선택하거나, 브라우저의 닫기버튼을 통해 닫았을 때 발생하는 콜백 함수를 정의하는 부분.
이 중 검색결과를 선택한 경우에는 onComplete콜백함수가 완료된 후에 실행
이 함수를 정의할때 넣는 인자에는 우편번호 찾기 화면이 어떻게 닫혔는지에 대한 상태 변수가 들어가게 됨
new daum.Postcode({
onclose: function(state) {
//state는 우편번호 찾기 화면이 어떻게 닫혔는지에 대한 상태 변수 이며,
//상세 설명은 아래 목록에서 확인
if(state === 'FORCE_CLOSE'){
//사용자가 브라우저 닫기 버튼을 통해 팝업창을 닫았을 경우,
//실행될 코드를 작성하는 부분
} else if(state === 'COMPLETE_CLOSE'){
//사용자가 검색결과를 선택하여 팝업창이 닫혔을 경우,
//실행될 코드를 작성하는 부분
//oncomplete 콜백 함수가 실행 완료된 후에 실행
}
}
});
주소를 검색할 경우에 실행되는 콜백함수
onresize콜백보다 먼저 실행되며, 검색어와 검색결과에 대한 간단한 정보가 콜백함수의 인자로 넘어가게 된다.
new daum.Postcode({
onsearch: function(data) {
//data는 검색결과에 대한 검색어와 갯수를 가지고 있는 데이터 객체
}
});
daum.Postcode의 함수는 아래와 같다.
//일반적인 팝업 오픈
new daum.Postcode({...}).open();
//특정 검색어를 넘겨 팝업 오픈
new daum.Postcode({...}).open({
q: '판교역로 235'
});
//팝업 위치를 지정(화면의 가운데 정렬)
var width = 500; //팝업의 너비
var height = 600; //팝업의 높이
new daum.Postcode({
width: width, //생성자에 크기 값을 명시적으로 지정
height: height,
...
}).open({
left: (window.screen.width / 2) - (width / 2),
top: (window.screen.height / 2) - (height / 2)
});
//여러개의 팝업창이 뜨는 것을 방지하기 위해 팝업이름을 지정
//지정하지 않을시 기본값은 '_blank'로 설정되어 계속 새창으로 열림
new daum.Postcode({...}).open({
popupName: 'postcodePopup' //팝업 이름을 설정
});
//검색 결과 선택 후, 자동으로 팝업이 닫히는 것을 방지
new daum.Postcode({...}).open({
autoClose: false //기본값 true
});
//일반적인 iframe 삽입
new daum.Postcode({...}).embed(element);
//특정 검색어를 넘겨 iframe 삽입
new daum.Postcode({...})..embed(element, {
q: '판교역로 235'
});
숙지한부분을 바탕으로 프로젝트에 직접 사용해보았다.
import DaumPostcode from 'react-daum-postcode';
1)
class Signup extends Component {
constructor(props) {
super(props);
this.state = {
address: '', //통신을 위한 key값
firstAddress: '', //주소api를 통해받는 주소
secondAddress: '', //직접 작성하는 상세주소
isDaumPost: false, //주소 api불러오기
🙄먼저 state 초기값 설정해주었다.
2)
render() {
// const { isModalOpen, isModalClose } = this.props; 모달창사용x
const { isDaumPost, firstAddress } = this.state;
// 주소창 style
const width = 505;
const height = 420;
const modalStyle = {
position: 'absolute',
zIndex: '100',
border: '1px solid #333333',
};
return (
🙄Component 페이지가 따로 있지않아 스타일속성을 scss가아닌 js에 직접 작성하였다. absolute display속성을 지정하여 레이아웃이 깨지지않게 해주었다.
3)
<div className="addressBox">
<div className="cellFirst">
<input
placeholder="주소"
className="main_Address"
value={firstAddress}
/>
<button
className="btn-serch"
type="button"
onClick={this.handleOpenPost} //버튼이벤트
>
주소 찾기
</button>
/// 버튼이벤트 후 true값으로 Daumpost 컴포넌트 불러오기 , 속성
{isDaumPost && (
<DaumPostCode
onComplete={this.handleAddress}
autoClose
width={width}
height={height}
style={modalStyle}
isDaumPost={isDaumPost}
/>
)}
</div>
<div className="spec_Address">
<input
type="text"
name="secondAddress"
placeholder="상세주소"
className="second_Address"
onChange={this.handleOnChange}
/>
</div>
🙄불러올 컴포넌트 위치를 정해 속성값과 함께 넣어주었다.
autoClose : 주소값 클릭시 자동 닫힘
4)
handleOpenPost = () => {
this.setState({
isDaumPost: true,
});
🙄버튼 클릭이벤트로 DaumPost 불러오기
// daum api 불러오기 함수
handleAddress = data => {
let AllAddress = data.address; //주소 변수
let extraAddress = ''; //()안 참고항목 변수
if (data.addressType === 'R') { // 사용자가 도로명 주소를 선택했을 경우
if (data.bname !== '' && /[동|로|가]$/g.test(data.bname)) {
// 법정동명이 있을 경우 추가한다. (법정리는 제외)
// 법정동의 경우 마지막 문자가 "동/로/가"로 끝난다.
extraAddress += data.bname;
}
if (data.buildingName !== '') { // 건물명이 있고
//공동주택제한일 경우 if안에 && data.apartment === 'Y' 추가
extraAddress +=
extraAddress !== '' ? ', ' + data.buildingName : data.buildingName;
// 아래와 같이 바꿔쓸수있다.
// extraAddress !== '' ? `, ${data.buildingName}` : data.buildingName;
}
AllAddress += extraAddress !== '' ? `(${extraAddress})` : ''; //템플릿 리터럴 표현
} // 표시할 참고항목이 있을 경우, 괄호까지 추가한 최종 문자열을 만든다.
this.setState({
firstAddress: AllAddress,
});
};
data.address : 데이터 속 기본주소
extraAddress : ()속 참고 주소
🙄 위 두개를 변수로 지정하고
기본주소칸에 쓰일 기본주소(data.address)를 불러오고, 조건문과 속성들을 활용하여 ()안에 쓰일 값을 만든다.
bname(동/로/가) 를 빈 문자 extraAddress에 추가시키고, buildingName(건물명) 또한 추가한다.
마지막으로 기본주소에 추가항목(소괄호안 항목)을 더해서 반환 해준다.
🖊(${extraAddress}): 템플릿 리터럴 문법(참고)
✔추가적으로 깔끔한 구현을 위해 팝업창으로 구현 하도록 수정이 필요해보인다.
공동주택 부분을 어떻게 해야할지 몰라서 헤매고 있었는데, 감사합니다 ! :D