
한 줄 요약: 지역을 고르면 그 지역 항목만 남는 메뉴를 블로그스팟 테마에 직접 넣었습니다. 핵심은 전국 단위와 지자체 단위가 섞인 지원금 정보를 먼저 갈라내는 일이었고, 그 구조를 정리합니다.
지역 정보가 한 곳에 있지 않았습니다
처음에 막힌 지점입니다. 받아온 데이터에 지역을 적는 칸이 따로 없는 경우가 많았습니다. 대신 제목이나 담당 기관 이름 안에 지역명이 들어 있었습니다. 예를 들면 서울시 청년 월세 지원 같은 제목입니다.
지원금 정보는 전국 누구나 대상인 것과 특정 지자체 주민만 대상인 것이 한 목록에 섞여 있습니다. 그래서 지역 필터를 만들 때 가장 먼저 풀어야 할 문제는 이 항목이 어느 지역 것인지를 어디서 알아내느냐였습니다.
이 글의 코드는 블로그스팟 테마에 직접 넣은 자바스크립트를 기준으로 합니다. 아래에서 설명하는 판정 규칙, 시도와 시군구 두 단계 메뉴, 선택 개수 표시 세 가지가 이 글의 중심입니다.

지역 필터를 만들기 전에 아래 세 가지를 먼저 정해야 합니다.
- 데이터에 지역을 적는 칸이 있는지, 없다면 어느 칸에서 지역명을 찾을지
- 지역명이 없는 항목을 어떻게 다룰지
- 시도와 시군구 중 어느 단위까지 나눌지
지원금을 찾는 사람은 대개 내가 사는 곳에서 받을 수 있는 것만 보고 싶어 합니다. 그래서 지역 필터는 편의 기능이 아니라 목록을 쓸 수 있게 만드는 기본 장치에 가깝습니다.
제목, 지역, 기관을 이어 붙여 판정합니다
한 칸만 보면 놓치는 항목이 생겨서, 제목과 지역과 기관을 한 문자열로 이어 붙인 뒤 그 안에 지역명이 있는지 봅니다. 실제 코드는 다음과 같습니다.
function isRegionalItem(item){
var text = String((item.title||'') + ' '
+ (item.region||'') + ' '
+ (item.agency||'')).toLowerCase();
return hasAny(text, situationTerms['지역 혜택']);
}
세 칸을 합치는 방식이 지저분해 보이지만 실제로는 이 방식이 가장 잘 맞았습니다. 지역명이 어느 칸에 들어 있을지 데이터마다 다르기 때문입니다. 칸이 비어 있어도 오류가 나지 않도록 각 값에 빈 문자열을 기본으로 둔 점도 중요합니다.
문자열 안에 특정 단어가 있는지는 자바스크립트의 includes로 확인합니다. MDN 문서에 따르면 이 함수는 대소문자를 구분하고, 찾으면 참을 아니면 거짓을 돌려줍니다. 영문이 섞인 기관명을 비교할 때는 양쪽을 소문자로 맞춘 뒤 비교하라고 문서가 예시까지 보여 줍니다. 위 코드에서 toLowerCase()를 붙인 이유가 이것입니다.
MDN 문서에는 주의할 점도 하나 더 있습니다. 빈 문자열을 찾으면 includes는 언제나 참을 돌려줍니다. 지역명 목록에 빈 값이 섞여 들어가면 모든 항목이 지역 항목으로 판정될 수 있다는 뜻입니다. 목록을 만들 때 빈 문자열이 없는지 한 번 살펴보세요. 또 정규식을 넘기면 오류가 나므로 지역명은 글자 그대로 넣어야 합니다.
시도를 고르면 시군구가 다시 그려집니다
메뉴는 두 단계입니다. 시도를 고르면 그 아래 시군구 목록이 새로 만들어집니다. 전국 시군구를 처음부터 모두 보여주면 목록이 200개가 넘어서 쓸 수 없습니다.
그래서 시도를 고르는 순간에만 해당 시군구를 그리고, 고르기 전에는 시군구 칸을 비워 둡니다. 화면이 간단해지고 선택 지점이 한 번에 하나로 줄어듭니다.
이 방식은 사용자가 해야 할 판단을 줄여 줍니다. 처음 보는 사람은 자기 시도만 찾으면 되고, 그 다음에 시군구를 고르면 됩니다. 시도를 바꾸면 이전에 고른 시군구는 의미가 없어지므로 목록도 함께 새로 그립니다.
| 사용자 상태 | 시군구 칸 | 이유 |
|---|---|---|
| 아직 시도를 고르지 않음 | 비어 있음 | 전국 시군구는 200개가 넘어 한꺼번에 보여 줄 수 없음 |
| 시도를 고름 | 그 시도의 시군구만 그림 | 사용자가 볼 선택지를 해당 시도 안으로 좁힘 |
| 다른 시도로 바꿈 | 새 시도 기준으로 다시 그림 | 이전 시도의 시군구는 더 이상 맞지 않음 |
이 표의 첫 줄이 가장 중요합니다. 선택지가 200개가 넘으면 스크롤하다가 지쳐서 필터를 포기하게 됩니다. 단계를 두 개로 나누면 한 번에 마주하는 선택지는 시도 목록 하나나 그 시도의 시군구 목록 하나로 줄어듭니다.
어디에도 걸리지 않는 항목은 전국으로 취급합니다
지역명이 아예 나오지 않는 항목이 있습니다. 이런 항목은 전국으로 취급해서 어느 지역을 고르든 같이 보이게 했습니다.
반대로 해 보기도 했습니다. 지역을 알 수 없는 항목을 아무 곳에도 보이지 않게 했더니, 서울을 골랐을 때 정작 전국 대상 지원금이 사라졌습니다. 그쪽이 훨씬 나쁜 결과였습니다. 놓친 혜택은 사용자가 알 수 없지만, 대상이 아닌 항목이 하나 더 보이는 것은 사용자가 직접 걸러 낼 수 있기 때문입니다.
아래 표는 이 규칙이 어떻게 동작하는지 보여 주는 가상의 예시입니다. 실제 목록이 아니라 설명을 위해 만든 예시입니다.
| 예시 항목(가상) | 판정 | 서울 선택 시 | 부산 선택 시 |
|---|---|---|---|
| 서울시 청년 월세 지원 | 제목에 서울 포함 | 보임 | 안 보임 |
| 지역명이 없는 지원금 | 지역 미상, 전국으로 취급 | 보임 | 보임 |
| 서울에 있는 기관이 하는 전국 사업 | 기관명에 서울이 있어 서울 항목으로 판정 | 보임 | 안 보임 |
세 번째 줄은 아래 한계 항목에서 다시 다루는 문제로, 기관 이름만으로는 사업 범위를 알 수 없어서 생깁니다. 예시는 규칙을 설명하려는 것일 뿐 실제 데이터에서 나온 수치가 아닙니다.

이 규칙은 정확도보다 누락 방지를 우선한 것입니다. 지역이 불확실한 항목을 숨기는 쪽은 오류를 사용자가 발견할 수 없지만, 보여 주는 쪽은 사용자가 내용을 읽고 스스로 판단할 수 있습니다.
선택한 개수를 버튼에 붙이는 한 줄
필터를 여러 개 고르면 지금 몇 개를 골랐는지 헷갈립니다. 그래서 메뉴 버튼에 선택한 개수를 붙였습니다. 코드는 짧습니다.
function updateCount(id, count){
document.getElementById(id).textContent = count + '개 선택';
}
짧지만 있고 없고의 차이가 컸습니다. 메뉴를 접어 둔 상태에서도 뭔가 걸려 있다는 걸 알 수 있기 때문입니다. 필터가 걸린 채 목록이 줄어든 이유를 모르는 상황이 가장 불편한데, 이 한 줄이 그 상황을 막아 줍니다.
여기에 쓴 두 가지 함수는 MDN 문서에서 동작을 확인할 수 있습니다. getElementById는 일치하는 요소가 없으면 null을 돌려주고, 아이디는 대소문자를 구분합니다. 그래서 아이디 철자가 다르면 이 줄에서 오류가 납니다. 또 textContent는 값을 HTML로 해석하지 않고 글자 그대로 넣습니다. 문서는 HTML로 넣는 innerHTML이 보안 문제에 취약할 수 있어 단순 글자에는 쓰지 말라고 권합니다.
설계 선택 정리
지금까지의 선택을 한 표로 모았습니다. 각 규칙이 무엇을 막는지 같이 적었습니다.
| 선택 | 이유 | 반대로 하면 |
|---|---|---|
| 제목, 지역, 기관을 합쳐서 판정 | 지역명이 어느 칸에 있을지 데이터마다 다름 | 한 칸만 보면 절반쯤 놓침 |
| 시도 선택 때만 시군구를 그림 | 전체 시군구가 200개가 넘어 쓸 수 없음 | 목록이 너무 길어짐 |
| 지역 미상은 전국으로 취급 | 어느 지역에서든 볼 수 있어야 함 | 서울을 골랐을 때 전국 대상 지원금이 사라짐 |
| 선택 개수를 버튼에 표시 | 접어 둔 상태에서도 필터가 걸린 걸 알 수 있음 | 왜 목록이 줄었는지 알기 어려움 |
기준은 하나입니다. 애매할 때는 보여 주는 쪽을 고른다는 것입니다. 놓치는 것보다 한 건 더 보이는 편이 사용자에게 덜 해롭다고 판단했습니다.
나중에 이 필터를 다시 손볼 때는 아래 세 가지를 점검하면 됩니다. 규칙이 의도대로 남아 있는지 확인하는 간단한 목록입니다.
- 서울을 골랐을 때 전국 대상 항목이 사라지지 않는지
- 지역명이 없는 항목이 어느 지역에서든 보이는지
- 메뉴를 접은 상태에서도 선택한 개수가 버튼에 보이는지
네 가지 선택은 서로 이어져 있습니다. 세 칸을 합쳐 판정하면 놓치는 항목이 줄고, 판정하지 못한 항목을 전국으로 돌리면 남은 항목이 사라지지 않습니다. 시도 단계에서만 시군구를 그리면 화면이 가벼워지고, 개수 표시는 이 모든 조건이 걸려 있다는 사실을 사용자에게 알려 줍니다. 하나라도 빠지면 필터는 쓰기 불편하거나 틀린 결과를 보여 줍니다.
이 방식의 한계
지역명이 겹치면 잘못 걸립니다. 예를 들어 광주는 광주광역시와 경기도 광주시가 둘 다 있습니다. 지금은 이 둘을 구분하지 못합니다.
또 기관 이름에 지역이 들어 있다고 그 지역 사업이라는 보장은 없습니다. 서울에 있는 기관이 전국 사업을 하기도 합니다. 이건 데이터만으로는 알 수 없어서 그대로 두었습니다.
이 글의 방식은 지역 칸이 없는 데이터를 글자 기준으로 나누는 방법이라 정확도에 한계가 있습니다. 데이터에 지역 코드 같은 칸이 있다면 그쪽을 먼저 쓰는 편이 더 정확합니다. 문자열 판정은 그런 칸이 없을 때를 위한 대안입니다.
| 한계 | 원인 | 현재 처리 |
|---|---|---|
| 지역명이 겹치면 잘못 걸림 | 글자만 보고 판정해서 같은 이름의 지역을 구분하지 못함 | 구분하지 못함 |
| 기관명의 지역이 사업 지역과 다를 수 있음 | 서울에 있는 기관이 전국 사업을 하기도 함 | 데이터만으로 알 수 없어 그대로 둠 |
이용하는 입장에서는 지역 필터의 결과를 참고용으로 보고, 실제 신청 대상은 공고 원문에서 다시 확인하는 것이 안전합니다. 필터는 목록을 줄여 주는 도구이지 신청 자격을 판정하는 도구가 아니기 때문입니다.