728x90
요구사항 정리
- 좌측 상단의 탭별 필터링 기능을 포함하여 검색 기능을 동작시켜야한다.
- 검색 기능은 사용자가 제목, 작성자의 부서, 팀명, 이름 별로 드롭다운 버튼을 활용해서 필터링하여 지정할 수 있어야한다.
구현한 코드 - 초안
// @function 검색 함수
function executeSearch() {
console.log('검색함수 호출');
let keyword = $(".search-input").val().toLowerCase();
let selectedCategory = $(".search-category").val().toLowerCase();
// NOTE - 탭을 통해 필터링된 결과를 가지고 검색을 시도
// let tempTabFilteredData;
// activeCategory = $(".tab-item.active").data("category");
// if (activeCategory === "all") {
// tempTabFilteredData = [...arr_data_list];
// } else {
// tempTabFilteredData = arr_data_list.filter(function(row) {
// let rowElement = $(row);
// // console.log('rowElement',rowElement);
// let category = rowElement.find(".category").text().toLowerCase();
// switch(true){
// case category.includes("지도"):
// return activeCategory === "mark";
// case category.includes("그래프"):
// return activeCategory === "graph";
// case category.includes("표"):
// return activeCategory === "etc";
// default:
// return activeCategory === "etc";
// }
// });
// }
console.log('탭 필터링된 데이터', filteredData);
// 검색기준 class명과 매핑
const mappingFilteringStandard = {
"전체": "all",
"제목": "title",
"부서명": "division_name",
"팀명": "team_name",
"담당자": "manager"
};
const filterStandard = mappingFilteringStandard[selectedCategory];
console.log('찾아낸 검색 기준 ',filterStandard);
// @pin 검색어가 포함된 데이터 필터링 구역
const tempFilteredData = filteredData.filter(function(row) {
const rowElement = $(row);
// "전체" 조건일 때는 모든 대상 필드에서 검색어를 포함하는지 확인
if (filterStandard === "all") {
const classList = ["title", "division_name", "team_name", "manager"];
// 하나라도 포함하면 true 반환
for (let cls of classList) {
const target = rowElement.find("." + cls);
const text = target.text().toLowerCase();
// console.log("전체시 검색된 타겟 정보:", text);
if (text.includes(keyword.toLowerCase())) {
return true;
}
}
// 전부 불일치하면 false
return false;
}
// 빈 문자열을 검색했을 경우 전체 데이터 조회
if(keyword === ""){
return true;
}
const target = rowElement.find("." + filterStandard);
if (target.length === 0) {
console.warn("찾을 수 없는 클래스: ", "." + filterStandard, "row:", row);
return false;
}
const text = target.text().toLowerCase();
console.log("검색된 타겟 정보:", text);
const isMatch = text.includes(keyword.toLowerCase());
return isMatch;
});
console.log('검색된 데이터', tempFilteredData);
filteredData = tempFilteredData; // 최신 검색 기준으로 갱신
currentPage = 1;
renderTable();
}
이슈 → 검색 필터링 누적
두 번째 검색 시 이전에 검색했던 결과를 가지고 다시 검색에 들어가는 현상 발견…
필터링을 입히기 위해 필터링된 결과를 재활용하여 구현하도록 했는데, 이때 이전에 검색한 결과를 재활용하는 형식이 돼버려서 검색 결과가 중첩되는 현상이 발생했다.
이슈 해결 → 상위에서 필터링된 결과를 활용해 다시 필터링
- 상위 블록에서 사용중인 filteredData를 그대로 사용한다.
//@function 총 건수 표시하는 함수
function updateTableInfo() {
let totalItems = filteredData.length;
let startItem = (currentPage - 1) * itemsPerPage + 1;
let endItem = Math.min(startItem + itemsPerPage - 1, totalItems);
$(".table-info").text(`총 ${totalItems}건 (${startItem} ~ ${endItem})`);
}
//@function 검색 함수
function executeSearch() {
console.log('검색함수 호출');
let keyword = $(".search-input").val().toLowerCase();
let selectedCategory = $(".search-category").val().toLowerCase();
let activeCategory = $(".tab-item.active").data("category");
// console.log('사용자가 입력한 검색어', keyword);
// console.log('선택된 검색 필터링', selectedCategory);
// console.log('선택된 탭 카테고리', activeCategory);
// STEP 1: 탭 기준으로 먼저 필터링
let tabFilteredData = [];
if (activeCategory === "all") {
tabFilteredData = [...arr_data_list]; // 원본 전체 복사
} else {
tabFilteredData = arr_data_list.filter(function(row) {
let rowElement = $(row);
let category = rowElement.find(".category").text().toLowerCase();
switch (true) {
case category.includes("지도"):
return activeCategory === "mark";
case category.includes("그래프"):
return activeCategory === "graph";
case category.includes("표"):
return activeCategory === "etc";
default:
return activeCategory === "etc";
}
});
}
console.log('탭 필터링된 데이터', tabFilteredData);
// STEP 2: 검색 기준 class 매핑
const mappingFilteringStandard = {
"전체": "all",
"제목": "title",
"부서명": "division_name",
"팀명": "team_name",
"담당자": "manager"
};
const filterStandard = mappingFilteringStandard[selectedCategory];
console.log('찾아낸 검색 기준 ', filterStandard);
// STEP 3: 키워드 기반 검색 필터링
const tempFilteredData = tabFilteredData.filter(function(row) {
const rowElement = $(row);
// 빈 문자열 검색은 탭 필터링 상태 유지
if (keyword === "") {
return true;
}
// 전체 검색일 때
if (filterStandard === "all") {
const classList = ["title", "division_name", "team_name", "manager"];
return classList.some(cls => {
const text = rowElement.find("." + cls).text().toLowerCase();
return text.includes(keyword);
});
}
const target = rowElement.find("." + filterStandard);
if (target.length === 0) {
console.warn("찾을 수 없는 클래스: ", "." + filterStandard, "row:", row);
return false;
}
const text = target.text().toLowerCase();
// console.log("검색된 타겟 정보:", text);
return text.includes(keyword);
});
// console.log('검색된 데이터', tempFilteredData);
filteredData = tempFilteredData; // 최신 필터링 결과 저장
currentPage = 1;
renderTable(); // 테이블 다시 그리기
}
'트러블 슈팅 > 트러블 슈팅' 카테고리의 다른 글
canvas에서 echart의 pie 차트가 흐리게 보이는 현상 해결 (0) | 2025.06.17 |
---|---|
formData 전송시 유효성 검사 로직 구현 (1) | 2025.06.17 |
브라우저에서 페이지 로드 시 받아온 대용량 데이터를 특정 이벤트에서 사용하는 로직 (0) | 2025.06.17 |
Flash of Unstyled Content(FOUC) 현상 해결 (0) | 2025.06.17 |
Next.js에서 유니티 빌드 파일 접근 수정 (2) | 2024.12.09 |