TIL

JavaScript 다중 검색 기능 만들기

빈코 2023. 9. 26. 14:47

 

안녕하세요 오늘은 JavaScript를 이용하여 다중 검색 기능을 만들어 볼 예정입니다. 겉으로는 쉬워 보이지만 코드 내용이 생각보다 많아서 잘 따라오셔야 할 것 같아요. 다중 검색 기능은 어디서든 사용이 가능하게 최대한 모듈화 방식으로 js 파일을 구성했습니다. 글 내용을 천천히 따라가시다 보면 해당 파일을 어떻게 적용하는지 아실 수 있어요😁 또한, 독자분들이 원하는 방향성과 다를 수 있기 때문에 개요에 있는 gif를 보시고 판단하시고, 비슷하다면 직접 원하시는 방향으로 커스텀해서 사용하시면 될 것 같습니다. 시작해 볼까요?

 

JavaScript 다중 검색

개요

위의 gif 파일과 같이 특정 페이지에서는 다중 검색이 가능하게 만들어야 하는 경우들이 종종 있습니다. 사실 해당 페이지에서만 동작하게 만든다면 쉽게(!?) 구현할 수 있었겠지만, 제가 원하는 방향은 모듈화 js를 만들고 어디서나 해당 기능을 사용할 수 있게 만들어 보고 싶었습니다.

 

영상에서는 버튼을 클릭하지 않는 것처럼 보이지만 사실 각 카테고리를 선택하고 옆에 있는 플러스 버튼을 이용하여 하단에 붙이고 있습니다. 그리고 이 포스팅은 단순히 UI만 그려주는 것에서 끝나는 것이 아니라, 각 카테고리 별로 어느 전역변수에 담겨있는지, 또 다중 검색이 정말로 동작하기 위해서 선택한 옵션 리스트들을 어떻게 넘겨야 하는지 등 자세하게 포스팅하려고 합니다.

 

독자분이 이 기능이 정말 필요하고, 하시는 프로젝트에 접목하고 싶으시다면, 설명 하나하나 자세히 봐주셨으면 좋겠습니다😃

 

적용 전 알아야 할 것들📙

저는 JS, Jsp, Java를 사용해서 해당 프로젝트를 구성하였습니다. 위의 영상을 보시면 아시다시피, 카테고리를 선택하는 두 개의 select box가 있고, 검색어로 입력하는 옵션이 있습니다. 글로 적는 포스팅 상 설명이 힘들어 앞으로 select box 옵션은 카테고리 옵션, 검색어를 직접 작성하는 옵션은 검색어 옵션이라 칭하겠습니다. 그리고 아래와 같이 제약조건이 있습니다. 

 

1. 카테고리를 선택하지 않고 플러스 버튼을 눌렀을 경우 경고 메시지

 

2. 이미 선택된 카테고리를 다시 한번 선택하고 플러스 버튼을 눌렀을 경우 경고 메시지

 

3. 검색어 옵션은 전체 검색 시에는 UI 추가 안 됨 & 분류를 선택하면 검색어 옵션도 UI 추가 가능

-. 검색어 옵션은 사용자가 분류를 선택하고 검색어 옵션을 추가하고 이후에 전체로 선택하고 검색어 옵션을 또 추가했을 경우 데이터를 조회하는 쿼리 부분에서 골치(?) 아파집니다. 그래서 검색어 옵션은 전체로 선택했을 경우는 바로 조회만 가능하고, 분류를 선택했을 경우에만 추가가 가능하게 동작됩니다.

 

-. 검색어 옵션 추가 후 전체 검색 시 경고 메시지

 

4. 사용자가 검색 옵션리스트들을 아래와 같이 추가하고, 조회버튼을 바로 누르는 것이 아니라 다른 카테고리를 변경한 후에 플러스 버튼을 누르지 않고 조회를 클릭했을 경우입니다. 즉, 현재 선택되어 있는 옵션들도 검색 조건에 추가시켜 줄 것이냐에 대한 고민이 많았는데, 저는 현재 선택된 옵션들도 사용자가 그냥 의미 없이 하지는 않을 것 같아서, 조회 버튼 클릭 시 현재 선택되어 있는 옵션들도 UI에 추가되고 검색 조건으로도 넘겨주는 방식으로 코드를 구성했습니다. 이해가 되지 않으시면 아래 시나리오대로 그림을 보시면 이해하기 편하실 것 같네요!

검색 옵션 리스트 조건들 추가
장치 구분 휴대용 장치로 놓고 조회 클릭
조회 버튼 클릭 후 화면

마지막으로 검색 조건에 대해서 설명드리려고 합니다. 첫 번째로 카테고리 옵션은 OR 조건으로 구성됩니다. 예시로 위 캡처와 같이 장치 구분을 3개 선택했을 때, 3개 중에 한 개라도 만족한다면 해당 데이터가 조회되어야 하기 때문입니다.

 

하지만 반대로 검색어 옵션은 각 옵션끼리 AND 조건으로 구성됩니다. 예시로 이름을 Binco, 활동하는 장소를 Blog로 검색어 옵션을 추가했다면 검색 조건은 이름이 Binco 이면서 활동하는 장소는 Blog인 데이터를 찾아야 합니다. 

 

모듈화 JS 적용하기📘

multiple_basic_search.js
0.01MB

 

JS 파일을 적용하는 방법은 간단합니다. 위의 JS 파일을 프로젝트의 원하시는 곳에 복사한 후에, 사용하고 싶은 Jsp 파일 상단에 아래 코드처럼 선언만 해주면 됩니다

<script src="<c:url value="/resources/js/common/multiple_basic_search.js"/>

그럼 이제 multiple_basic_search.js를 사용하는 방법에 대해 알아볼까요?

 

사용법📒

/**
사용 설명

1. html 상단에 js import 코드 추가
<script src="<c:url value="/resources/js/common/multiple_basic_search.js"/>

2. 아래 전역 변수들이 사용하려는 js파일에 추가되어야 함
 [필수 추가]
 var searchInputValList = new Array(); 		 // 검색어 옵션 리스트
 var drawOptionList = new Array(); 			 // 옵션박스 리스트
 var searchable = false;					 // 검색가능 여부
 var valOptionList = new Array();            // 값만 담는 리스트
 [선택 추가]
 검색 Option List에서 필요한 List들 추가	         // 체크박스 옵션 리스트들을 선언해야 합니다

3. html에 button 코드 추가
 1-1. select box일 경우
 <button id="[select 옵션 id 값]_btn" onclick="addSearchOption([추가 한 옵션 배열 이름],'[추가 한 옵션 배열 이름]', '[select 옵션 id 값]', this)" style="height: 33px;width: 30px; background-color: white; border: 0.2px solid grey;">+</button>
 1-2. input box일 경우
 <button id="search_input_val_btn" onclick="addSearchInputVal('[select 옵션 id 값]', this)" style="height: 33px;width: 30px; background-color: white; border: 0.2px solid grey;">+</button>

4. html에 추가한 옵션 리스트 보여질 UI 코드 추가
 <div id="viewOptionList"></div>

5. 해당 js 파일의 document.ready.function 안에 사용하는 select box 관련 초기화 로직이 없다면 추가해야 함.
 $('#[selectBoxId]').on("change", function (e) {
	const target = document.getElementById("[selectBoxId]_btn");
	target.disabled=false;
 })

6. 기존 js 파일의 조회 버튼 클릭 이벤트에 코드 추가(ex: btnSearch.click 이벤트)
 var optionArrList = [
	{'optionList': [옵션 리스트], 'selectID':'[해당 옵션 selectBoxID]','optionListName': '[옵션 리스트]'},
	{'optionList': [옵션 리스트], 'selectID':'[해당 옵션 selectBoxID]','optionListName': '[옵션 리스트]'}
 	...
 ];
 currentOptionAddList(optionArrList);
 if(searchable) {
	[table 명].draw(); 		// DataTable일 경우
	조회 로직	코드 추가			// 아닐 경우
 }
 
 **/

 

사용법은 JS 파일에도 첨부되어 있지만 좀 더 자세한 설명을 해보려고 합니다. 사용 설명을 보면 1번 JS import 하는 방법은 상단에서 이미 소개하였고, 2번 아래 전역 변수들이 사용하려는 JS파일에 추가되어야 합니다. 사용하려는 JS파일은 제가 첨부해 드린 JS 파일이 아니라 독자분께서 사용하시던 JS파일을 일컫습니다.

 

* 사용 설명서

2. 아래 전역 변수들이 사용하려는 js파일에 추가되어야 함
 [필수 추가]
 var searchInputValList = new Array(); // 검색어 옵션 리스트
 var drawOptionList = new Array(); // 옵션박스 리스트
 var searchable = false; // 검색가능 여부
 var valOptionList = new Array(); // 값만 담는 리스트
 [선택 추가]
 검색 Option List에서 필요한 List들 추가 // 체크박스 옵션 리스트들을 선언해야 합니다

 

필수 추가는 꼭 등록해주어야 하는 값들이고 선택 추가는 카테고리 옵션 리스트들을 선언해 주시면 됩니다. 저는 차단여부 카테고리 옵션인 blockStatusList를 예시로 설명드릴게요. 변수명은 자유이고, JS 파일 맨 상단에 전역변수로 선언해 주세요. 

 

JS 파일에 전역변수 추가

searchInputValList는 검색어 옵션 값들을 담는 리스트입니다. 사용자가 검색어 옵션을 이용하여 옵션 리스트에 추가할 때 해당 변수에 추가한 검색어 옵션 값들이 담깁니다. 

 

drawOptionList는 화면에 그려질 값들을 담는 리스트입니다. 해당 전역변수에는 어떤 카테고리든, 검색어 옵션이든 간에 분별없이 그려지는 모든 옵션들을 담습니다.

 

searchable은 검색이 가능한지 여부를 판단하는 전역변수입니다. 사용자가 이미 추가한 것을 한번 더 추가하려 하거나, 카테고리를 선택하지 않고 추가하려 했을 경우 등 다양한 상황에서 해당 전역변수 값을 이용하여 true/false로 지정하고, false일 경우 검색이 진행되지 않게 막는 역할을 합니다.

 

valOptionList는 검색 옵션 리스트에 있는 모든 카테고리 옵션, 검색어 옵션들의 value 값을 담는 리스트입니다. 해당 전역변수는 중복되는 옵션이 있는지 체크할 때 사용합니다.

 

blockStatusList는 추가적으로 등록한 카테고리 옵션 리스트입니다. 화면에서 봤던 [차단 여부] 카테고리의 옵션 리스트입니다. 독자분께서 카테고리를 여러 개 추가하고 싶으시면 추가적으로 변수명을 자유롭게 생각해서 하단에 추가하시면 됩니다.


 

3번은 html에 추가한 각 카테고리 및 검색어 옵션에 버튼을 추가해 주는 단계입니다. 

** 사용 설명서

3. html에 button 코드 추가
 1-1. select box일 경우
<button id="[select 옵션 id 값]_btn" 
 	onclick="addSearchOption([추가 한 옵션 배열 이름],'[추가 한 옵션 배열 이름]', '[select 옵션 id 값]', this)" 
    style="height: 33px;width: 30px; background-color: white; border: 0.2px solid grey;">
    +
</button>
 1-2. input box일 경우
<button id="search_input_val_btn" 
 	onclick="addSearchInputVal('[select 옵션 id 값]', this)" 
    style="height: 33px;width: 30px; background-color: white; border: 0.2px solid grey;">
    +
</button>

1-1. select box일 경우는 카테고리 옵션을 칭합니다. id 값에 select option에 선언된 id 값을 넣어주면 되고, onclick 이벤트에 addSearchOption 함수의 파라미터만 정의해 주시면 됩니다. 버튼을 커스텀 하고 싶으시면 style 부분만 바꿔주시면 되겠죠?

 

1-1번의 예시 코드는 아래와 같습니다.

<select class="form-control" id="block_type" name="block_type" style="margin-bottom:5px;">
    <option value="">차단 여부</option>
    <option value="0">차단</option>
    <option value="1">허용</option>
</select>
<button id="block_type_btn" 
	onclick="addSearchOption(blockStatusList,'blockStatusList','block_type',this)" 
    style="height: 33px;width: 30px; background-color: white; border: 0.2px solid grey;">
    +
</button>

 

1-2 input box일 경우는 검색어 옵션을 칭합니다. 제가 만든 multiple_basic_search.js는 검색어 옵션을 하나만 지정할 수 있기 때문에 addSearchInputVal 함수의 파라미터는 검색어 옵션의 select 옵션만 넣어주면 됩니다. 

 

1-2번의 예시 코드는 아래와 같습니다.

<select class="form-control" id="search_field" name="search_field">
    <option value="ALL">전체</option>
    <option value="title">제목</option>
    <option value="content">내용</option>
</select>
<input type="text" class="form-control" id="search_value" name="search_value" value="" style="width:200px;margin-bottom:5px;"/>
<button id="search_input_val_btn" 
	onclick="addSearchInputVal('search_field',this)" 
    style="height: 33px;width: 30px; background-color: white; border: 0.2px solid grey;">
    +
</button>

4번째 작업은 html에 추가한 옵션 리스트를 보여줄 UI 코드를 추가하는 작업입니다. 이 작업은 그저 단순히 UI 코드를 원하는 위치에 붙이기만 하면 되기 때문에 자세한 설명은 생략하겠습니다.

** 사용 설명서

4. html에 추가한 옵션 리스트 보여질 UI 코드 추가
 <div id="viewOptionList"></div>

5번째 작업은 multiple_basic_search.js 파일에 직접 코드를 추가시켜주셔야 합니다. 이미 아래 코드가 있을 텐데 여기서 주석으로 처리한 select options와 search input의 id 값들을 독자분들의 각각의 id 값으로 수정해주셔야 합니다.(저랑 똑같이 작성했으면 안 바꾸셔도 됩니다)

 

여기서 각각의 id 값이란 '#search_type'과 '#search_type_btn'은 카테고리 관련 값들입니다. 아까 추가한 html 코드를 보시면서 id 값들이 다른 부분들을 교체해 주시면 됩니다.

 

'#search_field'와 '#search_value' 그리고  플러스 버튼인 "search_input_val_btn"은 검색어 옵션 관련 값들입니다. 이 부분도 독자분이 html에 선언한 id 값들로 바꿔주시면 됩니다.

 

아래 소스는 사용자의 잘못된 동작으로 버튼을 비활성화시켰을 때, 다시 카테고리를 바꾼다거나 검색어 옵션에 값을 넣는 등 조치를 취하면 각 버튼들을 다시 활성화시켜주는 작업들을 합니다. 

 

$(document).ready(function () {
	// select options
	$('#search_type').on("change", function (e) {
		const target = document.getElementById("search_type_btn");
		target.disabled=false;
	})

	// search input
	$('#search_field').on("change", function (e) {
		const target = document.getElementById("search_input_val_btn");
		var optionList = document.getElementById("search_field");
		var selectLabel = optionList.options[optionList.selectedIndex].label;
		var optionTitle = optionList[0].label;
		if(optionTitle === selectLabel) {
			target.disabled=true;
		} else {
			target.disabled=false;
		}
	})
	$('#search_value').on("propertychange change paste input", function() {
		const search_field = $('#search_field').val();
		const target = document.getElementById("search_input_val_btn");
		if(search_field != 'ALL') {
			target.disabled=false;
		}
	});
})

6번째 작업은 조회 버튼 클릭 시 이벤트 처리 작업입니다. 여기서 조회하기 전에 위에서 설명한 바와 같이 현재 옵션들도 검색 조건에 추가시켜 주는 작업도 동시에 이루어집니다.

 

** 사용 설명서

6. 기존 js 파일의 조회 버튼 클릭 이벤트에 코드 추가(ex: btnSearch.click 이벤트)
 var optionArrList = [
	{'optionList': [옵션 리스트], 'selectID':'[해당 옵션 selectBoxID]','optionListName': '[옵션 리스트]'},
	{'optionList': [옵션 리스트], 'selectID':'[해당 옵션 selectBoxID]','optionListName': '[옵션 리스트]'}
 	...
 ];
 currentOptionAddList(optionArrList);
 if(searchable) {
	[table 명].draw(); 		// DataTable일 경우
	조회 로직	코드 추가		 // 아닐 경우
 }

 

해당 로직은 optionArrList에 추가한 카테고리 옵션들을 넣고 currentOptionAddList 함수에 파라미터로 전달합니다. 그러면 currentOptionAddList 함수에서 중복검사를 진행하고 통과한 옵션들을 각 카테고리 옵션에 추가시켜 줍니다. 이후에 searchable이 true라면 데이터 조회가 시작됩니다.

 

예시 코드는 아래와 같습니다.

//검색
$("#btnSearch").click( function () {
    var optionArrList = [
        {'optionList': blockStatusList, 'selectID':'search_type','optionListName': 'blockStatusList'}
    ];
    currentOptionAddList(optionArrList);
    if(searchable) {
        table.draw();
    }
});

 

저는 DataTable.js를 사용해서 [table 명].draw();를 사용했지만, 독자분께서 사용하지 않는다면 ajax 비동기 처리 방식으로 데이터를 조회해 오면 됩니다.

 

추가적으로 저는 chart.js를 import 하여 $.notify() 함수를 사용하여 경고 메시지를 띄웠습니다. 또한, 경고 메시지의 message 에는 spring:message를 사용했기 때문에, $.i18n.prop()을 사용하여 메시지를 가져오게 구성되어 있습니다. 독자분들은 간단하게는 alert로 대체하시거나 원하시는 경고 메시지 띄우는 방법을 찾아서 적용하면 될 것 같아요 :)

 

정리📗

여기까지 따라오셨다면 카테고리 옵션과 검색어 옵션을 추가했을 때, UI에 버튼식으로 추가되고 삭제 기능까지 작동이 될 것입니다. 또한, 미리 선언한 전역변수들에 추가한 옵션 값들이 각각 맞는 리스트에 분배되어 있을 것입니다.

 

추가한 검색어 옵션searchInputValList에 담겨있을 것이고, 카테고리 옵션들은 독자분께서 처음에 추가한 전역변수들에 담겨 있을 것입니다. 각각의 옵션값들이 따로 담겨 있으니 이제는 java 단으로 각각 넘겨서 데이터를 조회하는 쿼리를 짜고 다시 조회된 데이터를 받아와 front에서 사용자에게 보여주면 끝입니다.

 

옵션 리스트들을 java 단으로 넘길 때 controller에서 Debug를 해보시면 ajax로 dataType을 "json"으로 지정해 주었을 경우는 각 옵션들이 분배되어서 넘어오는 것을 확인하실 수 있고, dataType을 지정하지 않은 채 보내면 [Object object]로 넘어오는 경우가 있습니다. 이럴 때는 js에서 JSON.stringify() 함수를 이용해서 데이터를 보내면 되고, controller에서는 JSONParser를 이용해서 값을 받으면 됩니다.

 

java 단과 쿼리문은 만약 이걸 사용하시는 분들이 계신다면 추가적으로 포스팅할 예정입니다. 또한, multiple_basic_search.js에 있는 각각의 함수들을 자세히 설명드릴 예정입니다. 사실, 많이 부족한 코드여서 쓰시는 분들이 계실지 모르겠지만, 혹여나 한분이라도 쓰신다면 다음 포스팅을 이어 나가볼게요! 도움이 필요하시면 댓글 남겨주시고, 잘 안되거나 문제가 있는 코드들을 지적해 주시는 것은 언제나 환영입니다😁

 


👨‍👩‍👦‍👦 오픈채팅방 운영

취업을 준비하는 예비 개발자분들을 위한 질문&답변할 수 있는 공간을 만들었습니다. 취업과 이직을 하기 위해서 어떤 걸 중점적으로 준비해야 하는지부터 포트폴리오&이력서 작성법 등 다양한 질문들을 받고 답변을 드립니다. 참여하셔서 다양한 정보 얻고 가시면 좋을 것 같네요😁

 

참여코드 : 456456

https://open.kakao.com/o/gVHZP8dg

 

비전공 개발자 취업 준비방(질문&답변)

#비전공 #개발자 #취업 #멘토링 #부트캠프 #국비지원 #백엔드 #프론트엔드 #중소기업 #중견기업 #자바 #Java #sql

open.kakao.com

 


👨‍💻 전자책 출간

아울러 제가  🌟비전공자에서 2년만에 보안 전문 중견기업으로 이직 한 방법들을 정리한 전자책을 출간 하게 되었습니다. 어떤 걸 공부해야 하는지, 이직을 위해서 무엇을 준비해야 하는지, 제가 받았던 기술 면접 리스트 등 다양한 목차로 구성되어 있습니다. 또한, 구매 시 1:1 채팅을 이용하여 포트폴리오 첨삭을 도와드리고 있습니다. 🐕전자책으로 얻은 모든 수익은 유기견 센터 '팅*벨 입양센터'에 후원될 예정입니다. 관심 있으신 분들은 아래 링크를 참고해주세요😁

https://kmong.com/gig/480954

 

비전공개발자 2년만에 중견기업 들어간 방법 | 14000원부터 시작 가능한 총 평점 0점의 전자책, 취

0개 총 작업 개수 완료한 총 평점 0점인 Binco의 전자책, 취업·이직 전자책 서비스를 0개의 리뷰와 함께 확인해 보세요. 전자책, 취업·이직 전자책 제공 등 14000원부터 시작 가능한 서비스

kmong.com


반응형