주문 완료 페이지 스크립트

판매자별 테이블 접기 기능

// 롯데On 주문 페이지 전체 스크립트
document.addEventListener("DOMContentLoaded", function () {

    // 판매자별 테이블 접기
    const table = document.querySelector('.order_content'); // 원본 테이블
    const container = document.getElementById('tables-container');
    const rows = Array.from(table.querySelectorAll('tr')).slice(1); // 헤더 제외

    const vendorGroups = {};

    // 각 행(tr)을 판매자별로 그룹화
    rows.forEach(row => {
        const vendor = row.querySelector('.vendor-name')?.innerText.trim();
        if (!vendor) return;
        if (!vendorGroups[vendor]) vendorGroups[vendor] = [];
        vendorGroups[vendor].push(row);
    });

    container.innerHTML = '';

    // 판매자별로 섹션을 생성하여 붙이기
    Object.entries(vendorGroups).forEach(([vendor, trList]) => {
        const section = document.createElement('div');
        section.className = 'vendor-section';

        const header = document.createElement('div');
        header.className = 'vendor-header';

        const titleSpan = document.createElement('span');
        titleSpan.className = 'vendor-title';
        titleSpan.innerText = vendor;

        const iconSpan = document.createElement('span');
        iconSpan.className = 'vendor-toggle-icon';
        iconSpan.innerText = '▼';

        header.appendChild(titleSpan);
        header.appendChild(iconSpan);

        // 새로운 테이블에 기존 헤더 복제
        const groupTable = document.createElement('table');
        groupTable.className = 'order_content';

        const headerRow = table.querySelector('tr').cloneNode(true);
        groupTable.appendChild(headerRow);

        const clonedTrs = [];

        // 판매자 소속 행들을 복제해 붙이되, 두 번째 이후 행은 숨김
        trList.forEach((tr, i) => {
            const clonedRow = tr.cloneNode(true);
            if (i !== 0) clonedRow.style.display = 'none';
            clonedTrs.push(clonedRow);
            groupTable.appendChild(clonedRow);
        });

        // 헤더 클릭 시 나머지 행들 토글
        let isOpen = false;
        header.addEventListener('click', () => {
            isOpen = !isOpen;
            clonedTrs.forEach((tr, i) => {
                if (i === 0) return; // 첫 번째 행은 항상 보임
                tr.style.display = isOpen ? 'table-row' : 'none';
            });
            iconSpan.innerText = isOpen ? '▲' : '▼';
        });

        section.appendChild(header);
        section.appendChild(groupTable);
        container.appendChild(section);
    });

});

기능 설명

  1. 원본 테이블과 행 모아오기

    • const table = document.querySelector('.order_content')로 원본 테이블 선택
    • const rows = Array.from(table.querySelectorAll('tr')).slice(1)로 헤더(첫 번째 <tr>)를 제외한 모든 행을 배열로 가져옴
  2. 판매자별 그룹화 (vendorGroups)

    rows.forEach(row => {
        const vendor = row.querySelector('.vendor-name')?.innerText.trim();
        if (!vendor) return;
        if (!vendorGroups[vendor]) vendorGroups[vendor] = [];
        vendorGroups[vendor].push(row);
    });
    
    
    • 각 행에서 .vendor-name 텍스트를 추출
    • 해당 판매자를 키로 vendorGroups 객체에 배열로 저장
    • 예: { "롯데백화점": [tr1, tr2, …], "신세계": [trA, trB], … }
  3. 컨테이너 초기화

    container.innerHTML = '';
    
    
    • 기존 #tables-container 내부 내용을 비워서 새로운 섹션을 붙일 준비
  4. 판매자별로 섹션(section) 생성

    Object.entries(vendorGroups).forEach(([vendor, trList]) => {
        const section = document.createElement('div');
        section.className = 'vendor-section';
        // …
    });
    
    
    • Object.entries(vendorGroups)를 순회하며 각 판매자(vendor)와 해당 행 목록(trList)을 얻음
    • <div class="vendor-section">를 생성하여 아래 내용을 추가
  5. 헤더(header) 생성

    const header = document.createElement('div');
    header.className = 'vendor-header';
    
    const titleSpan = document.createElement('span');
    titleSpan.className = 'vendor-title';
    titleSpan.innerText = vendor;
    
    const iconSpan = document.createElement('span');
    iconSpan.className = 'vendor-toggle-icon';
    iconSpan.innerText = '▼';
    
    header.appendChild(titleSpan);
    header.appendChild(iconSpan);
    
    
    • <div class="vendor-header">에
      • <span class="vendor-title">판매자명</span>
      • <span class="vendor-toggle-icon">▼</span>
    • 아이콘은 접기/펼치기 상태를 표시
  6. 새로운 테이블 생성 및 헤더 복제

    const groupTable = document.createElement('table');
    groupTable.className = 'order_content';
    
    const headerRow = table.querySelector('tr').cloneNode(true);
    groupTable.appendChild(headerRow);
    
    
    • 원본 테이블의 첫 번째 <tr>(헤더 행)를 복제하여 새 테이블에 붙임
    • 이렇게 하면 동일한 열 구조가 유지됨
  7. 판매자 소속 행들 복제 & 초기 숨김 처리

    const clonedTrs = [];
    
    trList.forEach((tr, i) => {
        const clonedRow = tr.cloneNode(true);
        if (i !== 0) clonedRow.style.display = 'none';
        clonedTrs.push(clonedRow);
        groupTable.appendChild(clonedRow);
    });
    
    
    • trList 배열(판매자별 원본 행들)을 순회
    • 각 원본 <tr>를 cloneNode(true)로 복제
    • index i !== 0이면(첫 행 제외) style.display = 'none' 처리하여 숨김
    • clonedTrs 배열에 담아둠
    • 새 테이블(groupTable)에 순서대로 붙임
  8. 헤더 클릭 시 접기/펼치기 토글

    let isOpen = false;
    header.addEventListener('click', () => {
        isOpen = !isOpen;
        clonedTrs.forEach((tr, i) => {
            if (i === 0) return; // 첫 번째 행은 항상 보이게
            tr.style.display = isOpen ? 'table-row' : 'none';
        });
        iconSpan.innerText = isOpen ? '▲' : '▼';
    });
    
    
    • isOpen 불리언 변수를 토글
    • clonedTrs 배열의 두 번째 이후 행들(i !== 0)을
      • isOpen === true → tr.style.display = 'table-row' (펼치기)
      • isOpen === false → tr.style.display = 'none' (접기)
    • iconSpan 텍스트를 '▲' ↔ '▼' 로 변경
  9. 컨테이너에 판매자 섹션 추가

    section.appendChild(header);
    section.appendChild(groupTable);
    container.appendChild(section);
    
    
    • <div class="vendor-section">에 헤더와 해당 판매자 테이블을 넣고
    • 최종적으로 #tables-container에 붙임

결과적으로, 페이지 로드 시 다음과 같은 구조가 동적으로 생성됩니다:

<div id="tables-container">
  <div class="vendor-section">
    <div class="vendor-header">
      <span class="vendor-title">롯데백화점</span>
      <span class="vendor-toggle-icon">▼</span>
    </div>
    <table class="order_content">
      <!-- 복제된 헤더 행 -->
      <tr>…</tr>
      <!-- 롯데백화점 소속 첫 번째 상품 행(보임) -->
      <tr>…</tr>
      <!-- 롯데백화점 소속 나머지 상품 행들(기본 숨김) -->
      <tr style="display: none;">…</tr>
      <tr style="display: none;">…</tr>
    </table>
  </div>
  <div class="vendor-section">
    <div class="vendor-header">
      <span class="vendor-title">신세계</span>
      <span class="vendor-toggle-icon">▼</span>
    </div>
    <table class="order_content">
      <!-- 복제된 헤더 행 -->
      <tr>…</tr>
      <!-- 신세계 소속 첫 번째 상품 행(보임) -->
      <tr>…</tr>
      <!-- 신세계 소속 나머지 상품 행들(기본 숨김) -->
      <tr style="display: none;">…</tr>
    </table>
  </div>
  <!-- 타 판매자 섹션들… -->
</div>