$(function () {
boardCaptionToggle();
checkboxAllToggle();
accordionToggle();
/* ==================================================
Sub Visual SNB Navigation
- 파일명 기준 자동 활성
- 대메뉴 클릭 시 첫 하위 페이지 이동
- 모바일/PC 공통 구조
================================================== */
const BREAK_POINT = 1280;
const $snbWrap = $(".snb_wrap");
const currentSection = $("h2.sub_title").data("section");
const currentFile = location.pathname.split("/").pop();
const MENU_MAP = {
company: {
base: "/web/content.do?proFn=",
pages: [{
text: "설립배경",
file: "999110000"
},
{
text: "연혁",
file: "history.html"
},
{
text: "조직도",
file: "999130000"
},
{
text: "오시는길",
file: "999140000"
}
]
},
platform_tech: {
base: "/publish/usr/platform_tech/",
pages: [{
text: "연구배경",
file: "background.html"
},
{
text: "Organelle Selective Autophagy",
file: "autophagy.html"
}
]
},
major_result: {
base: "/publish/usr/major_result/",
pages: [{
text: "Mitophagy",
file: "mitophagy.html"
},
{
text: "Pexophagy",
file: "pexophagy.html"
},
{
text: "Melanophagy",
file: "melanophagy.html"
},
{
text: "Ciliogenesis",
file: "ciliogenesis.html"
},
{
text: "Anti Cancer",
file: "anticancer.html"
},
{
text: "Pipeline Summary",
file: "pipeline.html"
},
{
text: "R&D",
file: "rd.html"
}
]
}
};
/* =========================
SNB 렌더링
========================= */
function renderSNB() {
$snbWrap.each(function (index) {
const $wrap = $(this);
const $title = $wrap.find(".snb_title");
const $list = $wrap.find(".snb_select");
function toTitleCase(str) {
return str
.replace("_", " ")
.replace(/\b\w/g, char => char.toUpperCase());
}
// 첫 번째 snb = 대메뉴
if (index === 0) {
$title.text(toTitleCase(currentSection));
return;
}
// 두 번째 snb = 하위메뉴
const data = MENU_MAP[currentSection];
if (!data) return;
$list.empty();
let matched = false;
data.pages.forEach(page => {
const isActive = page.file === currentFile;
if (isActive) {
matched = true;
$title.text(page.text);
}
$list.append(
`
${page.text}
`
);
});
// 현재 파일과 매칭 안 되면 첫 번째로 세팅
if (!matched && data.pages.length) {
$title.text(data.pages[0].text);
}
});
}
/* =========================
Toggle 동작
========================= */
$(".snb_title").on("click", function () {
const $wrap = $(this).closest(".snb_wrap");
const $currentList = $wrap.find(".snb_select");
// 다른 메뉴 닫기
$(".snb_wrap").not($wrap).removeClass("active")
.find(".snb_select").stop(true, true).slideUp(200);
// 현재 메뉴 토글
if ($wrap.hasClass("active")) {
$wrap.removeClass("active");
$currentList.stop(true, true).slideUp(200);
} else {
$wrap.addClass("active");
$currentList.stop(true, true).slideDown(250);
}
});
/* =========================
대메뉴 클릭 시 첫 페이지 이동
========================= */
$(".snb_wrap").eq(0).find(".snb_select").on("click", "a", function (e) {
e.preventDefault();
const section = $(this).text().toLowerCase().replace(/\s/g, "_");
const data = MENU_MAP[section];
if (!data) return;
location.href = data.base + data.pages[0].file;
});
/* =========================
외부 클릭 시 닫기
========================= */
$(document).on("click", function (e) {
if (!$(e.target).closest(".snb_wrap").length) {
$(".snb_wrap").removeClass("active")
.find(".snb_select").stop(true, true).slideUp(200);
}
});
/* =========================
초기 실행
========================= */
renderSNB();
/* const title = $("h2.sub_title").text().trim().toUpperCase();
let sectionClass = "";
if (title === "COMPANY") {
sectionClass = "company";
} else if (title === "MAJOR RESULT") {
sectionClass = "major_result";
} else if (title === "PLATFORM TECH") {
sectionClass = "platform_tech";
}
if (sectionClass) {
$(".container.sub").addClass(sectionClass);
}*/
if (currentSection) {
$(".container.sub").addClass(currentSection);
}
})
function boardCaptionToggle() {
/**
* ✅ boardCaptionToggle()
*
* - 접근성 준수를 위한 테이블 캡션 자동 생성 함수
* - 각 .table 요소 내 의 | 텍스트를 기반으로 caption 생성
* - 상단 제목(.tb_tit01 또는 .content_title)을 함께 조합
* - 입력형(폼요소 포함) 테이블은 "정보입력" 문구, 일반형은 "정보제공" 문구 사용
*
*/
$(".table").each(function (idx, itm) {
const $table = $(itm).find("table");
let subTit = "";
// 1️⃣ 테이블 제목 찾기
if ($(itm).prev(".tb_tit01").length === 1) {
subTit = $(itm).prev(".tb_tit01").find(".tb_tit01_left p").text();
} else {
subTit = $(itm).closest(".content_title").find("h3").text();
}
// 2️⃣ th 텍스트 모두 가져오기
let thText = "";
const thList = $table.find("th");
thList.each(function (index) {
thText += $(this).text();
if (index < thList.length - 1) thText += ", ";
});
// 3️⃣ 기존 caption 제거 (중복 방지)
$table.find("caption").remove();
// 4️⃣ 입력형 여부 판단
const hasInputElements = $table.find("input, select, textarea, button").length > 0;
const isInputType = $(itm).hasClass("form_wrap") || hasInputElements;
// 5️⃣ caption 내용 구성
const captionText = isInputType ?
`${subTit} : ${thText} 등의 정보입력` :
`${subTit} : ${thText} 등의 정보제공`;
// 6️⃣ caption 추가
$table.prepend(`${captionText}`);
});
}
function checkboxAllToggle() {
/**
* ✅ checkboxAllToggle()
*
* [기능 설명]
* - id가 "_all"로 끝나는 체크박스를 클릭하면
* 같은 name을 가진 모든 체크박스를 선택/해제함.
* - 개별 체크박스 상태가 변경되면
* 전체 선택 체크박스의 상태도 자동으로 갱신됨.
*
*/
// 1️⃣ id가 '_all'로 끝나는 전체 선택용 체크박스 찾기
const $allCheckboxes = $("input[type='checkbox'][id$='_all']");
// 2️⃣ 전체 선택 체크박스 클릭 시 → 같은 name 그룹 모두 체크/해제
$allCheckboxes.on("change", function () {
const name = $(this).attr("name"); // 그룹 구분용 name 속성
const isChecked = $(this).is(":checked"); // 현재 전체 체크박스의 상태(true/false)
// 같은 name을 가진 모든 체크박스 상태 변경
$(`input[type='checkbox'][name='${name}']`).prop("checked", isChecked);
});
// 3️⃣ 개별 체크박스 클릭 시 → 전체 선택 체크박스 상태 갱신
$("input[type='checkbox']").not($allCheckboxes).on("change", function () {
const name = $(this).attr("name"); // 현재 클릭된 체크박스의 name
const $group = $(`input[type='checkbox'][name='${name}']`).not(`[id$='_all']`); // 전체선택 제외한 같은 그룹
const total = $group.length; // 그룹 내 전체 체크박스 수
const checked = $group.filter(":checked").length; // 체크된 개수
// 모든 체크박스가 선택되어 있으면 전체선택 체크박스도 체크, 아니면 해제
$(`input[type='checkbox'][id$='_all'][name='${name}']`).prop("checked", total === checked);
});
}
function accordionToggle(selector = ".accordion_header", duration = 400) {
const $headers = $(selector);
// 초기 상태 닫기
$(".accordion_body").hide();
$headers.off("click.accordion").on("click.accordion", function () {
const $this = $(this);
const $body = $this.next(".accordion_body");
const isOpen = $this.hasClass("active");
// 전체 닫기
$(".accordion_header").removeClass("active");
$(".accordion_body").slideUp(duration);
// 클릭한 것만 열기
if (!isOpen) {
$this.addClass("active");
$body.slideDown(duration);
}
});
} |