148 lines
6.4 KiB
PHP
148 lines
6.4 KiB
PHP
<?= $this->extend(LAYOUTS[$viewDatas['layout']]['path']) ?>
|
|
<?php
|
|
// 레이아웃 및 템플릿 경로 설정
|
|
$layouts = LAYOUTS[$viewDatas['layout']]['path'];
|
|
$template = "templates" . DIRECTORY_SEPARATOR . "{$viewDatas['layout']}";
|
|
|
|
// 데이터 API 엔드포인트 설정 (웹 뷰가 데이터를 요청할 주소)
|
|
// RequestTemplate=api 파라미터를 사용하여 해당 컨트롤러가 JSON을 반환하도록 유도합니다.
|
|
$dataApiEndpoint = current_url() . '?RequestTemplate=api';
|
|
$columnCount = count($viewDatas['formFields']) + 2; // 번호와 작업 컬럼 포함
|
|
?>
|
|
<?= $this->section('content') ?>
|
|
<?= session('message') ? $viewDatas['helper']->alertTrait(session('message')) : ""; ?>
|
|
|
|
<div class="layout_top"><?= $this->include("{$layouts}/top"); ?></div>
|
|
<table class="layout_middle">
|
|
<tr>
|
|
<td class="layout_left"><?= $this->include("{$layouts}/left_menu"); ?></td>
|
|
<td class="layout_right">
|
|
<div class="layout_header"><?= $this->include("{$template}/index_header"); ?></div>
|
|
<div id="container" class="layout_content">
|
|
|
|
<link href="/css/<?= $viewDatas['layout'] ?>/index.css" media="screen" rel="stylesheet" type="text/css" />
|
|
<div class="index_body">
|
|
<!-- 필터 영역은 유지 -->
|
|
<?= $this->include("{$template}/index_content_filter"); ?>
|
|
<?= form_open(current_url(), ['id' => 'batchjob_form', 'method' => "post"]) ?>
|
|
<table class="index_table data table table-bordered table-hover table-striped" data-rtc-resizable-table="reisze_table">
|
|
<thead>
|
|
<tr>
|
|
<th class="text-center bg-light">번호</th>
|
|
<?php foreach ($viewDatas['formFields'] as $field => $label): ?>
|
|
<th class="text-center bg-light"><?= $viewDatas['helper']->getListLabel($field, $label, $viewDatas) ?></th>
|
|
<?php endforeach ?>
|
|
<th class="text-center bg-light">작업</th>
|
|
</tr>
|
|
</thead>
|
|
<!-- API 호출로 데이터를 채울 영역 -->
|
|
<tbody id="data_list_tbody">
|
|
<tr>
|
|
<td colspan="<?= $columnCount ?>" class="text-center text-secondary p-5">목록 데이터를 로드 중입니다...</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<!-- 페이지네이션 영역 (데이터 로드 후 JS로 업데이트) -->
|
|
<div id="pagination_area">
|
|
<?= $this->include("{$template}/index_content_bottom"); ?>
|
|
</div>
|
|
|
|
<?= form_close() ?>
|
|
</div>
|
|
|
|
</div>
|
|
<div class="layout_footer"><?= $this->include("{$template}/index_footer"); ?></div>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<div class="layout_bottom"><?= $this->include("{$layouts}/bottom"); ?></div>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const tbody = document.getElementById('data_list_tbody');
|
|
const apiEndpoint = '<?= $dataApiEndpoint ?>';
|
|
const columnCount = <?= $columnCount ?>;
|
|
const formFields = <?= json_encode(array_keys($viewDatas['formFields'])) ?>;
|
|
const actionButtons = <?= json_encode($viewDatas['index_actionButtons']) ?>;
|
|
|
|
// 페이지 로드 시 또는 필터링/페이지네이션 시 호출될 메인 함수
|
|
window.fetchData = async function(page = 1, filters = {}) {
|
|
// 로딩 상태 표시
|
|
tbody.innerHTML = `<tr><td colspan="${columnCount}" class="text-center text-info p-5">데이터 로드 중...</td></tr>`;
|
|
|
|
// 쿼리 파라미터 구성 (페이지, 필터 등을 포함)
|
|
const url = new URL(apiEndpoint);
|
|
url.searchParams.set('page', page);
|
|
Object.keys(filters).forEach(key => url.searchParams.set(key, filters[key]));
|
|
try {
|
|
const response = await fetch(url);
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`API 호출 실패: ${response.statusText}`);
|
|
}
|
|
const result = await response.json();
|
|
if (result.status === 'success' && Array.isArray(result.data)) {
|
|
renderTable(result.data, result.pagination);
|
|
} else {
|
|
throw new Error(result.message || '데이터 구조 오류');
|
|
}
|
|
} catch (error) {
|
|
console.error("데이터 로드 오류:", error);
|
|
tbody.innerHTML = `<tr><td colspan="${columnCount}" class="text-center text-danger p-5">목록을 불러오는 데 실패했습니다. (${error.message})</td></tr>`;
|
|
}
|
|
}
|
|
// 테이블 렌더링 함수
|
|
function renderTable(entities, pagination) {
|
|
if (entities.length === 0) {
|
|
tbody.innerHTML = `<tr><td colspan="${columnCount}" class="text-center text-muted p-5">조회된 데이터가 없습니다.</td></tr>`;
|
|
return;
|
|
}
|
|
|
|
let html = '';
|
|
// 총 건수와 현재 페이지 정보로 시작 번호를 계산해야 하지만, 여기서는 단순화합니다.
|
|
let totalCount = pagination ? parseInt(pagination.totalCount) : entities.length;
|
|
let perPage = pagination ? parseInt(pagination.perPage) : 10;
|
|
let page = pagination ? parseInt(pagination.page) : 1;
|
|
|
|
let startNum = totalCount - ((page - 1) * perPage);
|
|
|
|
entities.forEach((entity, index) => {
|
|
html += '<tr>';
|
|
|
|
// 1. 번호
|
|
let currentNum = startNum - index;
|
|
// $viewDatas['helper']->getListButton('modify', $num, $viewDatas) 역할을 하는 단순 링크
|
|
const modifyLink = `/modify/${entity.id || ''}`;
|
|
html += `<td nowrap><a href="${modifyLink}">${currentNum}</a></td>`;
|
|
|
|
// 2. 데이터 필드
|
|
formFields.forEach(field => {
|
|
const fieldValue = entity[field] !== undefined ? entity[field] : '';
|
|
// 이 부분에서 기존 PHP 헬퍼($viewDatas['helper']->getFieldView)의 복잡한 로직을 JS로 재구현해야 함
|
|
html += `<td>${fieldValue}</td>`;
|
|
});
|
|
|
|
// 3. 작업 버튼
|
|
html += '<td nowrap>';
|
|
Object.keys(actionButtons).forEach(action => {
|
|
const label = actionButtons[action];
|
|
// 작업 버튼 링크 생성
|
|
const actionLink = `/${action}/${entity.id || ''}`;
|
|
html += `<a href="${actionLink}" class="btn btn-sm btn-outline-secondary me-1">${label}</a>`;
|
|
});
|
|
html += '</td>';
|
|
|
|
html += '</tr>';
|
|
});
|
|
|
|
tbody.innerHTML = html;
|
|
// pagination 영역 업데이트 로직 추가 필요
|
|
// document.getElementById('pagination_area').innerHTML = generatePaginationHtml(pagination);
|
|
}
|
|
|
|
// 초기 데이터 로드
|
|
fetchData();
|
|
});
|
|
</script>
|
|
<?= $this->endSection() ?>
|