programing/jQuery&HTML5

005. jQuery [시도/시군구/읍면동]을 이용한 selectbox 제어 submit 사용에도 option 유지

ZelKun 2023. 9. 17. 15:02
반응형

005. jQuery [시도/시군구/읍면동]을 이용한 selectbox 제어 submit 사용에도 option 유지

 

예전에 올린 selectbox 예제는 jquery로 동적으로 selectbox를 컨트롤 하는데

submit을 하게 되면, option이 유지가 안되는 단점을 가졌습니다.

parameter를 유지하려면 서버를 이용해야하는데...

https://jsfiddle.net 에 샘플을올리는거라 paramter 유지가 안되는 단점이 있었죠

 

코드가 다소 많이 복잡해지긴 했지만...

GET을 이용한 호출은 location.search 에 쿼리스트링을 받아올수 있으니

예제를 좀 수정해봤습니다

 

이전글 참고:

[programing/jQuery&HTML5] - 004. jQuery [시도/시군구/읍면동]을 이용한 selectbox 제어 with 기상청 동네예보

[programing/jQuery&HTML5] - 002. jQuery 셀렉트박스 제어 예제 select box control example

 

이전에 만든 소스에서 selectbox의 선택값을 변경할 때마다 submit이 발생하고

마지막 동을 변경했을때 동네예보 페이지를 iframe으로 호출하는 방식으로 변경

 

아쉽지만 jsfiddle.net 에서 submit을 발생하면 404가 나와 submit이 불가능합니다.

실행가능한 예제는 PC에서 직접 해봐야 합니다

 

<!--  https://zelkun.tistory.com/entry/005-jQuery-시도시군구읍면동을-이용한-selectbox-제어-submit-사용에도-option-유지 -->
<!DOCTYPE html>
<html lang="ko">

<head>
	<meta charset="utf-8" />
	<title>jQuery Select Example</title>
	<style type="text/css">
		div.contents {
			text-align: center;
			padding-bottom: 10px;
		}
	</style>
	<script src="https://code.jquery.com/jquery-latest.min.js" type="application/javascript"></script>
	<script type="application/javascript" src="https://zelkun.tistory.com/attachment/cfile8.uf@99BB7A3D5D45C065343307.js"></script>
	<script type="application/javascript">
		let searchParam = {
			sido: ''
			, sigugun: ''
			, dong: ''
		}
		function fn_search(){
			// console.log('-', $('#searchForm').serialize()) // request Param data check
			// document.searchForm.action = window.location.pathname;
			document.searchForm.submit();
		}
		jQuery(document).ready(function () {
			//검색결과 세팅
			fn_getParams();

			//sido option 추가
			jQuery.each(hangjungdong.sido, function (idx, code) {
				//append를 이용하여 option 하위에 붙여넣음
				if(searchParam.sido == code.sido) jQuery('#sido').append(fn_option(code.sido, code.codeNm, true));
				else jQuery('#sido').append(fn_option(code.sido, code.codeNm, false));
			});

			//sido 변경시 시군구 option 추가
			jQuery('#sido').change(() => {
				jQuery('#sigugun option:selected').attr('selected', false);
				jQuery('#dong option:selected').attr('selected', false);
				fn_search();
			});

			//시군구 변경시 행정동 옵션추가
			jQuery('#sigugun').change(() => {
				jQuery('#dong option:selected').attr('selected', false);
				fn_search();
			});

			jQuery('#dong').change(() => {
				fn_search();
			});

			console.log('1', searchParam.sido)
			if(searchParam.sido != '') fn_setSigugunCd();
			if(searchParam.sigugun != '') fn_setDongCd();
			if(searchParam.dong != '') fn_searchWeather();

			var sido = jQuery('#sido option:selected');
			var sigugun = jQuery('#sigugun option:selected');
			var dong = jQuery('#dong option:selected');
			var dongName = sido.text() + '/' + sigugun.text() + '/' + dong.text(); // 시도/시군구/읍면동 이름
			jQuery('#dongName').text(dongName);
		});

		function fn_setSigugunCd() {
			jQuery('#sigugun').show();
			jQuery('#sigugun').empty();
			jQuery('#sigugun').append(fn_option('', '선택')); //
			jQuery.each(hangjungdong.sigugun, function (idx, code) {
				if (jQuery('#sido > option:selected').val() == code.sido)
					if(searchParam.sigugun == code.sigugun) jQuery('#sigugun').append(fn_option(code.sigugun, code.codeNm, true));
					else jQuery('#sigugun').append(fn_option(code.sigugun, code.codeNm, false));
			});

			//세종특별자치시 예외처리
			//옵션값을 읽어 비교
			if (jQuery('#sido option:selected').val() == '36') {
				jQuery('#sigugun').hide();
				//index를 이용해서 selected 속성(attr)추가
				//기본 선택 옵션이 최상위로 index 0을 가짐
				jQuery('#sigugun option:eq(1)').prop('selected', true); // 세종은 시구군이 1개
				//trigger를 이용해 change 실행
				// jQuery('#sigugun').trigger('change');
				fn_setDongCd();
			}
		}
		function fn_setDongCd() {
			console.log(jQuery('#sido > option:selected').val(), jQuery('#sigugun > option:selected').val())
			//option 제거
			jQuery('#dong').empty();
			jQuery.each(hangjungdong.dong, function (idx, code) {
				if (jQuery('#sido > option:selected').val() == code.sido && jQuery('#sigugun > option:selected').val() == code.sigugun)
					if(searchParam.dong == code.dong) jQuery('#dong').append(fn_option(code.dong, code.codeNm, true));
					else jQuery('#dong').append(fn_option(code.dong, code.codeNm, false));
			});
			//option의 맨앞에 추가
			jQuery('#dong').prepend(fn_option('', '선택'));
			//option중 선택을 기본으로 선택
			jQuery('#dong option:eq(0)').attr('selected', true);
		}
		function fn_searchWeather(){
			var sido = jQuery('#sido option:selected');
			var sigugun = jQuery('#sigugun option:selected');
			var dong = jQuery('#dong option:selected');

			// var dongName = sido.text() + '/' + sigugun.text() + '/' + dong.text(); // 시도/시군구/읍면동 이름
			// jQuery('#dongName').text(dongName);
			var dongCode = sido.val() + sigugun.val() + dong.val() + '00'; // 읍면동코드
			jQuery('#dongCode').text(dongCode);

			//동네예보 URL
			var url = 'https://www.weather.go.kr/weather/process/timeseries-dfs-body-ajax.jsp?myPointCode=' + dongCode + '&unit=K';
			//iframe으로 결과 보기
			fn_iframe(url);
		}

		function fn_getParams(){
			console.log(window.location.search)
			var params = window.location.search.split('&');
			for(idx in params){
				const param = params[idx].split('='); //param settion
				if(param[0].includes('sido')) searchParam.sido = param[1];
				else if(param[0].includes('sigugun')) searchParam.sigugun = param[1];
				else if(param[0].includes('dong')) searchParam.dong = param[1];
			}
			// console.log('param:', searchParam) check Param
			return searchParam;
		}
		function fn_option(code, name, selected) {
			if(selected) return '<option value="' + code + '" selected="selected">' + name + '</option>';
			else return '<option value="' + code + '">' + name + '</option>';
		}
		function fn_iframe(url) {
			jQuery('#iframe').attr('src', url);
		}
	</script>
</head>

<body>
	<div class="contents">
		<form name="searchForm" id="searchForm">
			<select id="sido" name="sido"><option value="">선택</option></select>
			<select id="sigugun" name="sigugun"><option value="">선택</option></select>
			<select id="dong" name="dong"><option value="">선택</option></select>
		</form>
		<div>
			텍스트: <span id="dongName"></span><br/>
			코드: <span id="dongCode"></span>
		</div>
	</div>
	<div class="main">
		<iframe id="iframe" style="width:100%; height:500px;"></iframe>
	</div>
</body>

</html>

 

이전과 달라진 점은 위에도 언급했지만

검색을 위해 이전에 onchange에서 처리하던걸 대부분 function 을 분리, 절차순으로 변경했습니다

 

Form을 추가해서 parameter를 전달하며

selectbox option을 유지하기 위해 window.location.search 의 값을 받아 split 를 이용해 param을 분리하고

파싱된 데이터를 selectbox option을 추가할때 이용됩니다

전체적인 구조가 이전에 올린 샘플과 상이하니 다소 난해할 수 있지만 결과적으로는

option을 추가할때 받아온 값과 같을때 selected를 해주도록 변경 된부분 이 있습니다

 

jsp를 이용하면 JSTL 을 써서 <c:out value="${param.sido}"> 이렇게 parameter를 개별로 분리하면 되는데

html로 구현하니 javascript에서 안되는부분을 다른기능으로 커버할 수 밖에 없네요

 

option 을 유지하는건 option 태그에 selected="selected" 이거만 추가하면 되는 일인데요

 

 

본적인 코드긴한데, 작성한 성의를 봐서라도

퍼가실때는 정확한 출처 표시해주시기 바랍니다

반응형