본문 바로가기

PHP

PHP/JS 동적으로 바뀌는 행정구역 select 태그 만들기 [도시선택]

반응형

처음 onLoad 될 때의 select 태그

 

첫번째 select 내 경기도 option을 클릭하였을 때 option 요소들이 변경되는 두번째 select 태그

 

웹사이트를 구축하다 보면 사용자에게 정해진 행정구역의 값을 정확하게 입력받기 위해서 select 태그를 사용해야 할 경우가 발생한다. 첫 번째 select 태그에서 특별·광역시/도를 선택하면 두 번째 select 태그가 해당 행정구역에 속한 시/군/구를 선택할 수 있게 동적으로 option 항목들이 변경되는 소스다.

 

전체적인 소스코드는 아래와 같다.

<? 
	function area_info($도="") {
		$area_1 = array("서울특별시","부산광역시","대구광역시","인천광역시","광주광역시","대전광역시","울산광역시","세종특별자치시","경기도","강원도","충청도","전라도","경상도","제주특별자치도");
		$area_2 = array();
		$area_2["서울특별시"]		= array("종로구","중구","용산구","성동구","광진구","동대문구","중랑구","성북구","강북구","도봉구","노원구","은평구","서대문구","마포구","양천구","강서구","구로구","금천구","영등포구","동작구","관악구","서초구","강남구","송파구","강동구");
		$area_2["부산광역시"]		= array("중구","서구","동구","영도구","부산진구","동래구","남구","북구","강서구","해운대구","사하구","금정구","연제구","수영구","사상구");
		$area_2["대구광역시"]		= array("중구","동구","서구","남구","북구","수성구","달서구","달성군");
		$area_2["인천광역시"]		= array("중구","동구","미추홀구","연수구","남동구","부평구","계양구","서구","강화군","옹진군");
		$area_2["광주광역시"]		= array("동구","서구","남구","북구","광산구");
		$area_2["대전광역시"]		= array("동구","중구","서구","유성구","대덕구");
		$area_2["울산광역시"]		= array("중구","남구","동구","북구","울주군");
		$area_2["세종특별자치시"]	= array("세종");
		$area_2["경기도"]		= array("수원","안양","안산","용인","부천","광명","평택","과천","오산","시흥","군포","의왕","하남","이천","안성","김포","화성","광주","여주","양평","고양","의정부","동두천","구리","남양주","파주","양주","포천","연천","가평");
		$area_2["강원도"]		= array("춘천","원주","강릉","동해","태백","속초","삼척","홍천","횡성","영월","평창","정선","철원","화천","양구","인제","고성","양양");
		$area_2["충청도"]		= array("청주","충주","제천","보은","옥천","영동","증평","진천","괴산","음성","단양","천안","공주","보령","아산","서산","논산","계룡","당진","금산","부여","서천","청양","홍성","예산","태안");
		$area_2["전라도"]		= array("전주","군산","익산","정읍","남원","김제","완주","진안","무주","장수","임실","순창","고창","부안","목포","여수","순천","나주","광양","담양","곡성","구례","고흥","보성","화순","장흥","강진","해남","영암","무안","함평","영광","장성","완도","진도","신안");
		$area_2["경상도"]		= array("포항","경주","김천","안동","구미","영주","영천","상주","문경","경산","군위","의성","청송","영양","영덕","청도","고령","성주","칠곡","예천","봉화","울진","울릉","창원","진주","통영","사천","김해","밀양","거제","양산","의령","함안","창녕","고성","남해","하동","산청","함양","거창","합천");
		$area_2["제주특별자치도"]	= array("제주","서귀포");

		if($도 == "")	return $area_1;
		else		return $area_2[$도];
	}
	$area_list		= area_info();
	$area_list2		= area_info($area_list[0]);
?>

<div>
	<!-- 결과물 가독성을 편하게 하기 위하여 multiple 속성을 명시 -->
	<select name="client_area" onchange="setArea2(this.value)" multiple> 
		<? foreach($area_list AS $area) { ?>
		<option value="<?=$area?>"><?=$area?></option>
		<? } ?>
	</select>
	<select name="client_area2" multiple>
		<? foreach($area_list2 AS $area) { ?>
		<option value="<?=$area?>"><?=$area?></option>
		<? } ?>
	</select>
</div>

<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script> 
<script language="javascript">
	function setArea2(area1) {
		var areaArr = new Array();
		
		<? foreach($area_list AS $area) { $areaArr = area_info($area); $areaTxt=""; foreach($areaArr AS $area2) { $areaTxt .= "'$area2',"; } $areaTxt = substr($areaTxt,0,-1); ?>
		areaArr["<?=$area?>"] = [<?=$areaTxt?>];
		<? } ?>
		
		var html = "";
		areaArr[area1].forEach(function(element){ html += "<option value='"+element+"'>"+element+"</option>"; });

		$("select[name='client_area2']").empty();
		$("select[name='client_area2']").append(html);
	}
</script>

 

 

위의 소스코드 작동 방식을 차례대로 복기해보자면, 먼저 area_info() 함수를 선언하여, 해당 함수 내의 첫 번째 배열 변수에는 광역자치단체의 정보를, 두 번째 배열 변수에는 각 광역자치단체 내의 기초자치단체 정보 값을 입력한다. 해당 함수를 호출할 때 매개변수에 값이 없으면 광역자치단체 배열을 리턴하고, 값이 있으면 매개 변숫값에 해당하는 기초자치단체 배열을 리턴한다.

(개별의 storage 또는 DB에 저장하여 행정구역정보 테이블을 관리하는 방식도 있겠지만, 간단하게 작성할 수 있는 소스코드를 예시로 들었다. 그 뭐 우리나라 행정구역이 쉽게 개편되는 것도 아니고, 한 번 하드코딩해놓으면 몇 년은 쓸 수 있...)

 

그리고 $area_list 변수에 광역지방자치단체 정보에 대한 배열을, $area_list2 변수에는 서울특별시의 기초지방자치단체에 대한 정보를 배열로 설정한다.

(물론 따로 $_REQUEST 값 또는 DB에서 꺼내온 값을 가지고 area_info($매개변수)를 실행하여 원하는 광역지방자치단체의 기초지방자치단체 값을 가져와도 된다.)

<?
$area_list	= area_info();
// $area_list	== ["서울특별시","부산광역시","대구광역시","인천광역시","광주광역시","대전광역시","울산광역시","세종특별자치시","경기도","강원도","충청도","전라도","경상도","제주특별자치도"];
$area_list2	= area_info($area_list[0]);
// $area_list2	== ["종로구","중구","용산구","성동구","광진구","동대문구","중랑구","성북구","강북구","도봉구","노원구","은평구","서대문구","마포구","양천구","강서구","구로구","금천구","영등포구","동작구","관악구","서초구","강남구","송파구","강동구"];
?>

 

 

그리고 생성된 배열들로 첫 번째 select 태그에는 $area_list의 값들을 option으로 세팅하고, 두 번째 select 태그에는 $area_list2의 값들을 option으로 각각 foreach 함수를 이용하여 세팅한다. 첫번 째 select 태그에는 두번 째 select 태그를 동적으로 변환시킬 javascript 함수를 선언한다.

<!-- 결과물 가독성을 편하게 하기 위하여 multiple 속성을 명시 -->
<select name="client_area" onchange="setArea2(this.value)" multiple> 
	<? foreach($area_list AS $area) { ?>
	<option value="<?=$area?>"><?=$area?></option>
	<? } ?>
</select>
<select name="client_area2" multiple>
	<? foreach($area_list2 AS $area) { ?>
	<option value="<?=$area?>"><?=$area?></option>
	<? } ?>
</select>

 

 

그리고 마지막으로 위에서 선언한 PHP 변수 $area_list와 $area_list2를 가지고 사용자 화면에서 동적으로 select option 값을 변경할 javascript 함수를 선언한다. 일반 JS문법으로도 처리가 가능하지만, 개인적인 편의상 Jquery를 사용하여 처리하였다.

<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script> 
<script language="javascript">
  function setArea2(area1) {
    var areaArr = new Array();
    <? 
    foreach($area_list AS $area) { 
      $areaArr = area_info($area); $areaTxt=""; 
      foreach($areaArr AS $area2) { $areaTxt .= "'$area2',"; } 
      $areaTxt = substr($areaTxt,0,-1); 
    ?>
      areaArr["<?=$area?>"] = [<?=$areaTxt?>];
    <? } ?>

    var html = "";
    areaArr[area1].forEach(function(element){ html += "<option value='"+element+"'>"+element+"</option>"; });

    $("select[name='client_area2']").empty();
    $("select[name='client_area2']").append(html);
  }
</script>

이 serArea2 함수 필드 부분이 PHP와 javascript 소스코드가 버무려진 스파게티 코드인데, 아래와 같이 순서대로 정의한다.

 

먼저 javascript 필드에 빈 배열을 선언한다. 그리고 PHP 필드에서 1차로 광역자치단체 정보를 가진 $area_list 배열 변수를 loop 시키고, 해당 반복 문내에서 다음과 같은 작업을 처리한다.

1. area_info($반복문요소(이하 $key)) 함수를 이용 $areaArr에 $key 값에 해당하는 기초자치단체 배열 정보를 정의한다.

2. javascript에서 배열 값으로 사용할 문자열 $areaTxt를 초기화시킨다.

3. $areaArr 배열 변수를 loop 시켜, $areaTxt에 $areaArr의 반복 요소들을 콤마를 구분자로 문자열로 붙이고, 끝자리에 붙은 콤마를 substr 함수를 이용하여 제거한다.

(이 글을 작성하는 중간에 깨달은 사실이지만, 굳이 저렇게 반복문을 다시 돌리기보다는 implode(",",$areaArr) 함수를 이용하면 더 짧게 코드 작성이 가능하다.)

4. PHP 반복문 필드 내의 javascript 필드에 areaArr 배열 변수의 키값에는 $key를 선언, 값에는 $areaTxt 값을 정의한다.

 

위의 반복문 작업이 마무리되면 areaArr 배열에는 광역자치단체의 키값에 각각 기초자치단체 값들이 정의된 2차원 배열이 선언된다.

 

 매개변수로 들어온 광역자치단체의 키값에 해당하는 2차 배열을 반복문으로 돌려 html 변수에 option 태그를 설정한 후 select 태그의 option 태그를 html 변수에 정의된 값을 갈아 끼워 넣는 형태로 함수가 작동하게 된다.

 

반응형