- URL 하드코딩 → .env APP_URL 기반 동적 URL로 변경 - DB 연결 하드코딩 → .env 기반으로 변경 - MySQL strict mode DATE 오류 수정
788 lines
31 KiB
PHP
788 lines
31 KiB
PHP
<?php
|
|
require_once($_SERVER['DOCUMENT_ROOT'] . "/session.php");
|
|
|
|
if (!isset($_SESSION["level"]) || $_SESSION["level"] > 5) {
|
|
sleep(1);
|
|
header("Location:" . $WebSite . "login/login_form.php");
|
|
exit;
|
|
}
|
|
|
|
include $_SERVER['DOCUMENT_ROOT'] . '/load_header.php';
|
|
$title_message = '현설 참여 관리';
|
|
?>
|
|
|
|
<link href="css/style.css" rel="stylesheet">
|
|
<title> <?=$title_message?> </title>
|
|
</head>
|
|
|
|
<body>
|
|
<?php
|
|
$header = isset($_REQUEST['header']) ? $_REQUEST['header'] : '';
|
|
require_once($_SERVER['DOCUMENT_ROOT'] . '/myheader1.php');
|
|
|
|
$search = isset($_REQUEST['search']) ? $_REQUEST['search'] : '';
|
|
$mode = isset($_REQUEST["mode"]) ? $_REQUEST["mode"] : '';
|
|
$fromdate = $_REQUEST["fromdate"] ?? '' ;
|
|
$todate = $_REQUEST["todate"] ?? '' ;
|
|
|
|
$tablename = 'bid';
|
|
|
|
// 현재 날짜
|
|
$currentDate = date("Y-m-d");
|
|
|
|
// fromdate 또는 todate가 빈 문자열이거나 null인 경우
|
|
if ($fromdate === "" || $fromdate === null || $todate === "" || $todate === null) {
|
|
$fromdate = date("Y-01-01"); // 현재 년도의 1월 1일
|
|
$todate = $currentDate; // 현재 날짜
|
|
}
|
|
|
|
require_once($_SERVER['DOCUMENT_ROOT'] . "/lib/mydb.php");
|
|
$pdo = db_connect();
|
|
|
|
$order = " ORDER BY registedate DESC ";
|
|
|
|
// SQL 기본 구조 (날짜 범위 필터링 추가)
|
|
$sql = "SELECT * FROM ".$DB.".".$tablename."
|
|
WHERE is_deleted IS NULL
|
|
AND registedate BETWEEN :fromdate AND :todate";
|
|
|
|
// 검색어가 있을 경우 추가
|
|
if (!empty($search)) {
|
|
$sql .= " AND searchtag LIKE :search ";
|
|
}
|
|
|
|
$sql .= $order;
|
|
|
|
try {
|
|
$stmh = $pdo->prepare($sql);
|
|
|
|
// 바인딩
|
|
$stmh->bindValue(":fromdate", $fromdate, PDO::PARAM_STR);
|
|
$stmh->bindValue(":todate", $todate, PDO::PARAM_STR);
|
|
|
|
if (!empty($search)) {
|
|
$stmh->bindValue(":search", "%{$search}%", PDO::PARAM_STR);
|
|
}
|
|
|
|
$stmh->execute();
|
|
$total_row = $stmh->rowCount();
|
|
?>
|
|
|
|
<form id="board_form" name="board_form" method="post" enctype="multipart/form-data">
|
|
<input type="hidden" id="mode" name="mode" value="<?=$mode?>">
|
|
<input type="hidden" id="num" name="num">
|
|
<input type="hidden" id="tablename" name="tablename" value="<?=$tablename?>">
|
|
<input type="hidden" id="header" name="header" value="<?=$header?>">
|
|
|
|
<div class="container-fluid">
|
|
<!-- Bootstrap Modal -->
|
|
<div class="modal fade" id="myModal" tabindex="-1" aria-labelledby="myModalLabel" aria-hidden="true" data-bs-backdrop="static" data-bs-keyboard="false">
|
|
<div class="modal-dialog modal-fullscreen modal-dialog-centered modal-dialog-scrollable">
|
|
<div class="modal-content border-0 shadow-lg">
|
|
<div class="modal-header bg-primary text-white" style="padding: 0.5rem 1rem;">
|
|
<h5 class="modal-title fw-bold" id="myModalLabel">
|
|
<i class="bi bi-gear-fill me-2"></i>현설정보 등록/수정
|
|
</h5>
|
|
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="custom-card">
|
|
<!-- 여기에 폼 내용이 들어갑니다 ajax로 불러옴-->
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer bg-white border-top">
|
|
<div class="d-flex justify-content-between w-100">
|
|
<div class="d-flex">
|
|
<button type="button" id="saveBtn" class="btn btn-success btn-sm me-2 shadow-sm">
|
|
<i class="bi bi-check-circle me-1"></i>저장
|
|
</button>
|
|
<button type="button" id="deleteBtn" class="btn btn-danger btn-sm me-2 shadow-sm">
|
|
<i class="bi bi-trash me-1"></i>삭제
|
|
</button>
|
|
</div>
|
|
<div class="d-flex">
|
|
<!-- <button type="button" id="resetBtn" class="btn btn-warning btn-sm me-2 shadow-sm">
|
|
<i class="bi bi-arrow-clockwise me-1"></i>초기화
|
|
</button> -->
|
|
<button type="button" id="closeBtn" class="btn btn-secondary btn-sm shadow-sm" data-bs-dismiss="modal">
|
|
<i class="bi bi-x-circle me-1"></i>닫기
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="container">
|
|
<div class="d-flex mt-4 mb-2 align-items-center justify-content-center">
|
|
<span class="text-center fs-5"> <?=$title_message?> </span>
|
|
<button type="button" class="btn btn-dark btn-sm mx-2" onclick='location.reload();' > <i class="bi bi-arrow-clockwise"></i> </button>
|
|
</div>
|
|
<div class="d-flex mt-2 mb-3 align-items-center justify-content-center">
|
|
<i class="bi bi-caret-right"></i> <?= $total_row ?> 건
|
|
|
|
<!-- 기간부터 검색까지 연결 묶음 start -->
|
|
<span id="showdate" class="btn btn-dark btn-sm mx-1" > 기간 </span>
|
|
|
|
<div id="showframe" class="card" style="width:500px;">
|
|
<div class="card-header " style="padding:2px;">
|
|
<div class="d-flex justify-content-center align-items-center">
|
|
기간 설정
|
|
</div>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="d-flex justify-content-center align-items-center">
|
|
<button type="button" class="btn btn-outline-success btn-sm me-1 change_dateRange" onclick='alldatesearch()' > 전체 </button>
|
|
<button type="button" id="preyear" class="btn btn-outline-primary btn-sm me-1 change_dateRange" onclick='pre_year()' > 전년도 </button>
|
|
<button type="button" id="three_month" class="btn btn-dark btn-sm me-1 change_dateRange" onclick='three_month_ago()' > M-3월 </button>
|
|
<button type="button" id="prepremonth" class="btn btn-dark btn-sm me-1 change_dateRange" onclick='prepre_month()' > 전전월 </button>
|
|
<button type="button" id="premonth" class="btn btn-dark btn-sm me-1 change_dateRange" onclick='pre_month()' > 전월 </button>
|
|
<button type="button" class="btn btn-outline-danger btn-sm me-1 change_dateRange" onclick='this_today()' > 오늘 </button>
|
|
<button type="button" id="thismonth" class="btn btn-dark btn-sm me-1 change_dateRange" onclick='this_month()' > 당월 </button>
|
|
<button type="button" id="thisyear" class="btn btn-dark btn-sm me-1 change_dateRange" onclick='this_year()' > 당해년도 </button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<input type="date" id="fromdate" name="fromdate" size="12" class="form-control" style="width:100px;" value="<?=$fromdate?>" > ~
|
|
<input type="date" id="todate" name="todate" size="12" class="form-control" style="width:100px;" value="<?=$todate?>" > </span>
|
|
|
|
|
|
|
|
<div class="inputWrap30">
|
|
<input type="text" id="search" class="form-control" style="width:150px;" name="search" autocomplete="off" value="<?=$search?>" onKeyPress="if (event.keyCode==13){ enter(); }">
|
|
<button class="btnClear"></button>
|
|
</div>
|
|
<button class="btn btn-dark btn-sm mx-1" type="button" id="searchBtn"> <i class="bi bi-search"></i> </button>
|
|
<button id="newBtn" type="button" class="btn btn-dark btn-sm mx-1"> <i class="bi bi-pencil-square"></i> 신규 </button>
|
|
</div>
|
|
</div>
|
|
<div class="container-fluid">
|
|
<!-- <div class="d-flex mt-1 mb-1 align-items-center justify-content-center">
|
|
<button type="button" class="btn btn-success btn-sm downloadExcel mx-2">📥 선택행 엑셀 다운로드</button>
|
|
<button type="button" class="btn btn-secondary btn-sm downloadPDF mx-2">📥 선택행 PDF 다운로드</button>
|
|
</div> -->
|
|
<div class="d-flex mt-1 mb-1 align-items-center justify-content-center">
|
|
<table class="table table-hover" id="myTable">
|
|
<thead class="table-primary">
|
|
<th class="text-center" style="width:30px;">번호</th>
|
|
<th class="text-center" style="width:100px;">등록일</th>
|
|
<th class="text-center" style="width:120px;">시공사</th>
|
|
<th class="text-center" style="width:200px;">현장명</th>
|
|
<th class="text-center" style="width:100px;">주소</th>
|
|
<th class="text-center" style="width:80px;">산출</th>
|
|
<th class="text-center" style="width:80px;">현설일</th>
|
|
<th class="text-center" style="width:80px;">현설참여자</th>
|
|
<th class="text-center" style="width:80px;">진행상태</th>
|
|
<th class="text-center" style="width:60px;">총개소</th>
|
|
<th class="text-center" style="width:250px;">아이템 내역</th>
|
|
<th class="text-center" style="width:100px;">입찰금액</th>
|
|
<th class="text-center" style="width:80px;">입찰일</th>
|
|
<th class="text-center" style="width:80px;">입찰결과</th>
|
|
<th class="text-center" style="width:250px;">비고</th>
|
|
</thead>
|
|
<tbody>
|
|
<?php
|
|
$start_num = $total_row;
|
|
while($row = $stmh->fetch(PDO::FETCH_ASSOC)) {
|
|
include '_row.php';
|
|
$quantityData = json_decode($quantityJson, true);
|
|
// '0'이 아닌 품목만 필터링하여 'item : quantity' 형태로 출력
|
|
$surang = "";
|
|
if (is_array($quantityData)) {
|
|
$filteredItems = array_filter($quantityData, function ($item) {
|
|
return isset($item['quantity']) && $item['quantity'] !== "0";
|
|
});
|
|
// 'item : quantity' 형식으로 변환
|
|
$surang = implode("<br>", array_map(function ($item) {
|
|
return htmlspecialchars($item['item'], ENT_QUOTES, 'UTF-8') . ":" . htmlspecialchars($item['quantity'], ENT_QUOTES, 'UTF-8');
|
|
}, $filteredItems));
|
|
}
|
|
?>
|
|
<tr onclick="loadForm('modify', <?= $num ?>)">
|
|
<td class="text-center"><?= $start_num ?></td>
|
|
<td class="text-center"><?= $registedate ?></td>
|
|
<td class="text-start text-primary"><?= $secondord ?></td>
|
|
<td class="text-start fw-bold"><?= $workplacename ?></td>
|
|
<td class="text-start"><?= $address ?></td>
|
|
<td class="text-center text-success"><?= $estimatedbyPerson ?></td>
|
|
<td class="text-start"><?= ($siteDate == '0000-00-00') ? '' : $siteDate ?></td>
|
|
<td class="text-start"><?= $siteAttendance ?></td>
|
|
<td class="text-center fw-bold"><?= $siteStatus ?></td>
|
|
<td class="text-end text-danger fw-bold"><?= $totalitem ?></td>
|
|
<td class="text-start"><?= $surang ?></td>
|
|
<td class="text-end fw-bold"><?= is_numeric($fee) ? number_format($fee) : htmlspecialchars($fee) ?></td>
|
|
<td class="text-center"><?= ($bidDate == '0000-00-00') ? '' : $bidDate ?></td>
|
|
<td class="text-center
|
|
<?php
|
|
if ($siteresult === '낙찰') {
|
|
echo 'text-primary';
|
|
} elseif ($siteresult === '탈락') {
|
|
echo 'text-danger';
|
|
} elseif ($siteresult === '유찰') {
|
|
echo 'text-success';
|
|
}
|
|
?>">
|
|
<?= htmlspecialchars($siteresult, ENT_QUOTES, 'UTF-8') ?>
|
|
</td>
|
|
|
|
<td class="text-start"><?= $memo ?></td>
|
|
</tr>
|
|
<?php
|
|
$start_num--;
|
|
}
|
|
} catch (PDOException $Exception) {
|
|
print "오류: ".$Exception->getMessage();
|
|
}
|
|
?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
</form>
|
|
|
|
<script>
|
|
var ajaxRequest = null;
|
|
var ajaxRequest_write = null;
|
|
var dataTable; // DataTables 인스턴스 전역 변수
|
|
var material_regpageNumber; // 현재 페이지 번호 저장을 위한 전역 변수
|
|
var bootstrapModal = null; // Bootstrap 모달 인스턴스 전역 변수
|
|
|
|
// 날짜 필드 초기화 함수
|
|
function initializeDateFields() {
|
|
$('input[type="date"]').each(function() {
|
|
if ($(this).val() === "0000-00-00" || $(this).val() === "") {
|
|
$(this).val("");
|
|
}
|
|
});
|
|
}
|
|
|
|
// 아이템수 합계 내기
|
|
function sumItem(){
|
|
// 아이템 합계 내기
|
|
// 테이블 바디 요소 찾기
|
|
const tableBody = document.querySelector('#itemTable tbody');
|
|
if (!tableBody) {
|
|
console.error('테이블 바디 요소를 찾을 수 없습니다.');
|
|
return; // 요소가 없으면 이후 코드를 실행하지 않음
|
|
}
|
|
|
|
// 합계를 계산하여 업데이트하는 함수
|
|
function updateTotal() {
|
|
let total = 0;
|
|
const inputs = document.querySelectorAll('input[name="quantity[]"]');
|
|
inputs.forEach(function(input) {
|
|
let value = parseFloat(input.value) || 0;
|
|
total += value;
|
|
});
|
|
$("#totalitem").val(total);
|
|
// 합계를 표시할 셀 업데이트
|
|
const totalQuantityCell = document.getElementById('totalQuantity');
|
|
if (totalQuantityCell) {
|
|
totalQuantityCell.textContent = total;
|
|
}
|
|
}
|
|
|
|
// 마지막 행 생성 및 배경색 음영 적용
|
|
const totalRow = document.createElement('tr');
|
|
totalRow.style.backgroundColor = '#f9f9f9';
|
|
|
|
// // 번호 컬럼 (빈 셀)
|
|
const tdEmpty = document.createElement('td');
|
|
tdEmpty.textContent = '';
|
|
|
|
// 아이템 종류 컬럼에 '합계' 라벨
|
|
const tdLabel = document.createElement('td');
|
|
tdLabel.textContent = '합계';
|
|
tdLabel.style.textAlign = 'center';
|
|
|
|
// 수량 컬럼에 총합을 표시할 셀 (초기값 0)
|
|
const tdTotal = document.createElement('td');
|
|
tdTotal.id = 'totalQuantity';
|
|
tdTotal.textContent = '0';
|
|
tdTotal.style.textAlign = 'center';
|
|
|
|
// 셀들을 행에 추가
|
|
totalRow.appendChild(tdLabel);
|
|
totalRow.appendChild(tdTotal);
|
|
totalRow.appendChild(tdEmpty);
|
|
|
|
// 마지막 행을 테이블 바디에 추가
|
|
tableBody.appendChild(totalRow);
|
|
|
|
// 모든 수량 입력 필드에 이벤트 리스너 추가 (입력 시 합계 업데이트)
|
|
const inputs = document.querySelectorAll('input[name="quantity[]"]');
|
|
inputs.forEach(function(input) {
|
|
input.addEventListener('input', updateTotal);
|
|
});
|
|
|
|
// 초기 합계 계산
|
|
updateTotal();
|
|
|
|
}
|
|
|
|
function loadForm(mode, num = null) {
|
|
if (mode === 'copy' && num) {
|
|
$("#mode").val('copy');
|
|
$("#num").val(num); // 기존 데이터 복사할 num 유지
|
|
} else if (num == null) {
|
|
$("#mode").val('insert');
|
|
} else {
|
|
$("#mode").val('modify');
|
|
$("#num").val(num);
|
|
}
|
|
|
|
$.ajax({
|
|
type: "POST",
|
|
url: "fetch_modal.php",
|
|
data: { mode: mode, num: num },
|
|
dataType: "html",
|
|
success: function(response) {
|
|
document.querySelector(".modal-body .custom-card").innerHTML = response;
|
|
|
|
// Bootstrap 모달 표시 (전역 변수 사용)
|
|
if (bootstrapModal) {
|
|
bootstrapModal.show();
|
|
}
|
|
|
|
// 아이템 합계내기
|
|
sumItem();
|
|
|
|
// 기존 participant 데이터 처리
|
|
let participantData = [];
|
|
try {
|
|
// fetch_modal.php에서 전달된 participantJson 데이터 추출
|
|
const tempDiv = document.createElement('div');
|
|
tempDiv.innerHTML = response;
|
|
const participantJsonElement = tempDiv.querySelector('input[name="participantJson"]');
|
|
if (participantJsonElement && participantJsonElement.value) {
|
|
participantData = JSON.parse(participantJsonElement.value);
|
|
}
|
|
} catch (e) {
|
|
console.log('participantData 파싱 오류:', e);
|
|
participantData = [];
|
|
}
|
|
|
|
// mode가 insert가 아닐때는 deleteBtn 버튼 보이게 하기
|
|
if(mode !== 'insert')
|
|
$("#deleteBtn").show();
|
|
else
|
|
$("#deleteBtn").hide();
|
|
|
|
// 닫기 버튼 이벤트 (Bootstrap 모달의 기본 닫기 기능 사용)
|
|
$("#closeBtn").off("click").on("click", function() {
|
|
if (bootstrapModal) {
|
|
bootstrapModal.hide();
|
|
}
|
|
});
|
|
|
|
// 기존 이벤트 제거 후 재등록
|
|
$(document).off('click', '.specialbtnClear').on('click', '.specialbtnClear', function(e) {
|
|
e.preventDefault(); // 기본 동작을 방지합니다.
|
|
$('#siteAttendance').val('');
|
|
});
|
|
|
|
// 날짜 필드 초기화
|
|
initializeDateFields();
|
|
|
|
// Log 파일보기
|
|
$("#showlogBtn").click( function() {
|
|
var num = $(this).data("num"); // 'data-num' 속성 값 가져오기
|
|
// table 이름을 넣어야 함
|
|
var tablename = $("#tablename").val() ;
|
|
// 버튼 비활성화
|
|
var btn = $(this);
|
|
popupCenter("../Showlog.php?num=" + num + "&workitem=" + tablename , '로그기록 보기', 500, 500);
|
|
btn.prop('disabled', false);
|
|
});
|
|
|
|
let isSaving = false;
|
|
|
|
$("#saveBtn").off("click").on("click", function() {
|
|
if (isSaving) return;
|
|
isSaving = true;
|
|
|
|
var formData = new FormData($("#board_form")[0]);
|
|
|
|
// 날짜 필드 유효성 검사
|
|
initializeDateFields();
|
|
|
|
// 수량 데이터를 JSON으로 변환
|
|
let quantityData = [];
|
|
$("#itemTable tbody tr").each(function() {
|
|
let rowData = {
|
|
// item: $(this).find("td.quantityArray").text().trim(), // 아이템명
|
|
item: ( $(this).find("input[name='item[]']").val() || "" ).trim() || "",
|
|
quantity: ( $(this).find("input[name='quantity[]']").val() || "" ).trim() || "0",
|
|
note: ( $(this).find("input[name='note[]']").val() || "" ).trim() || ""
|
|
};
|
|
quantityData.push(rowData);
|
|
});
|
|
|
|
formData.set("quantityJson", JSON.stringify(quantityData));
|
|
|
|
// 현설 참여업체 데이터를 JSON으로 변환
|
|
let participantDataArray = [];
|
|
$("input[name='participant[]']").each(function() {
|
|
let value = $(this).val().trim();
|
|
if (value) {
|
|
participantDataArray.push(value);
|
|
}
|
|
});
|
|
|
|
// 참여업체 JSON 데이터 추가
|
|
formData.set("participantJson", JSON.stringify(participantDataArray));
|
|
|
|
$.ajax({
|
|
url: "process.php",
|
|
type: "post",
|
|
data: formData,
|
|
processData: false,
|
|
contentType: false,
|
|
success: function(response) {
|
|
Toastify({
|
|
text: "저장완료",
|
|
duration: 3000,
|
|
close: true,
|
|
gravity: "top",
|
|
position: "center",
|
|
backgroundColor: "#4fbe87",
|
|
}).showToast();
|
|
|
|
setTimeout(function() {
|
|
if (bootstrapModal) {
|
|
bootstrapModal.hide();
|
|
}
|
|
location.reload();
|
|
}, 1000);
|
|
},
|
|
error: function(jqxhr, status, error) {
|
|
console.log(jqxhr, status, error);
|
|
isSaving = false;
|
|
}
|
|
});
|
|
});
|
|
|
|
|
|
// 삭제 버튼
|
|
$("#deleteBtn").off("click").on("click", function() {
|
|
// var level = '<?= $_SESSION["level"] ?>';
|
|
|
|
// if (level !== '1') {
|
|
// Swal.fire({
|
|
// title: '삭제불가',
|
|
// text: "관리자만 삭제 가능합니다.",
|
|
// icon: 'error',
|
|
// confirmButtonText: '확인'
|
|
// });
|
|
// return;
|
|
// }
|
|
|
|
Swal.fire({
|
|
title: '자료 삭제',
|
|
text: "삭제는 신중! 정말 삭제하시겠습니까?",
|
|
icon: 'warning',
|
|
showCancelButton: true,
|
|
confirmButtonColor: '#3085d6',
|
|
cancelButtonColor: '#d33',
|
|
confirmButtonText: '삭제',
|
|
cancelButtonText: '취소'
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
$("#mode").val('delete');
|
|
var formData = $("#board_form").serialize();
|
|
|
|
$.ajax({
|
|
url: "process.php",
|
|
type: "post",
|
|
data: formData,
|
|
success: function(response) {
|
|
Toastify({
|
|
text: "파일 삭제완료",
|
|
duration: 2000,
|
|
close: true,
|
|
gravity: "top",
|
|
position: "center",
|
|
style: {
|
|
background: "linear-gradient(to right, #00b09b, #96c93d)"
|
|
},
|
|
}).showToast();
|
|
|
|
if (bootstrapModal) {
|
|
bootstrapModal.hide();
|
|
}
|
|
location.reload();
|
|
},
|
|
error: function(jqxhr, status, error) {
|
|
console.log(jqxhr, status, error);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
});
|
|
|
|
// textarea 자동 행 조절 (개선된 버전)
|
|
function autoResizeTextarea(textarea) {
|
|
// 텍스트가 없으면 최소 높이로 설정
|
|
if (!textarea.value.trim()) {
|
|
textarea.style.height = 'auto';
|
|
textarea.style.minHeight = '38px'; // 최소 높이 설정
|
|
return;
|
|
}
|
|
|
|
// 원본 스타일 저장
|
|
const originalHeight = textarea.style.height;
|
|
const originalOverflow = textarea.style.overflow;
|
|
|
|
// 임시로 높이를 auto로 설정하여 정확한 계산을 위해
|
|
textarea.style.height = 'auto';
|
|
textarea.style.overflow = 'hidden';
|
|
|
|
// 정확한 높이 계산 (여유 공간 최소화)
|
|
const newHeight = Math.max(textarea.scrollHeight + 2, 38);
|
|
|
|
// 높이 설정
|
|
textarea.style.height = newHeight + 'px';
|
|
textarea.style.overflow = 'hidden';
|
|
textarea.style.minHeight = '38px';
|
|
}
|
|
|
|
// 페이지 로드 시 모든 textareaClass에 대해 자동 조절 적용
|
|
document.querySelectorAll('.textareaClass').forEach(function(textarea) {
|
|
// 약간의 지연을 두고 초기 높이 설정 (DOM이 완전히 렌더링된 후)
|
|
setTimeout(function() {
|
|
autoResizeTextarea(textarea);
|
|
}, 10);
|
|
|
|
// focus 이벤트에서도 재조정
|
|
textarea.addEventListener('focus', function() {
|
|
autoResizeTextarea(this);
|
|
});
|
|
});
|
|
|
|
// 입력 시 자동 행 조절 (debounce 적용)
|
|
let resizeTimeout;
|
|
document.addEventListener('input', function(e) {
|
|
if (e.target && e.target.classList.contains('textareaClass')) {
|
|
clearTimeout(resizeTimeout);
|
|
resizeTimeout = setTimeout(function() {
|
|
autoResizeTextarea(e.target);
|
|
}, 10);
|
|
}
|
|
});
|
|
|
|
// 창 크기 변경 시에도 재조정
|
|
window.addEventListener('resize', function() {
|
|
document.querySelectorAll('.textareaClass').forEach(function(textarea) {
|
|
autoResizeTextarea(textarea);
|
|
});
|
|
});
|
|
|
|
// 현설 참여업체 및 메모 테이블 동적 행 추가/삭제 기능
|
|
function initializeParticipantTable() {
|
|
const table = document.getElementById('participantTable');
|
|
if (!table) return;
|
|
|
|
const tbody = table.querySelector('tbody');
|
|
|
|
// 행 추가 버튼 이벤트
|
|
$(document).off('click', '.addRowBtn').on('click', '.addRowBtn', function() {
|
|
const clickedRow = $(this).closest('tr');
|
|
const newRow = document.createElement('tr');
|
|
newRow.innerHTML = `
|
|
<td class="text-center">
|
|
<button type="button" class="btn btn-outline-dark btn-sm addRowBtn"> + </button>
|
|
<button type="button" class="btn btn-outline-dark btn-sm deleteRowBtn"> - </button>
|
|
</td>
|
|
<td>
|
|
<input type="text" class="form-control text-start" name="participant[]" placeholder="현설 참여업체 및 메모" autocomplete="off">
|
|
</td>
|
|
`;
|
|
// 클릭한 행 바로 아래에 새 행 삽입
|
|
clickedRow.after(newRow);
|
|
});
|
|
|
|
// 행 삭제 버튼 이벤트
|
|
$(document).off('click', '.deleteRowBtn').on('click', '.deleteRowBtn', function() {
|
|
const row = $(this).closest('tr');
|
|
if (tbody.children.length > 1) {
|
|
row.remove();
|
|
} else {
|
|
// 마지막 행이면 내용만 지우기
|
|
row.find('input[name="participant[]"]').val('');
|
|
}
|
|
});
|
|
}
|
|
|
|
// 현설 참여업체 테이블 초기화
|
|
initializeParticipantTable();
|
|
|
|
// 기존 participant 데이터가 있으면 로드
|
|
if (participantData && participantData.length > 0) {
|
|
const table = document.getElementById('participantTable');
|
|
if (table) {
|
|
const tbody = table.querySelector('tbody');
|
|
|
|
// 기존 행들 제거 (첫 번째 행 제외)
|
|
while (tbody.children.length > 1) {
|
|
tbody.removeChild(tbody.lastChild);
|
|
}
|
|
|
|
// 첫 번째 행에 첫 번째 데이터 설정
|
|
if (tbody.children.length > 0) {
|
|
const firstInput = tbody.children[0].querySelector('input[name="participant[]"]');
|
|
if (firstInput) {
|
|
firstInput.value = participantData[0] || '';
|
|
}
|
|
}
|
|
|
|
// 나머지 데이터로 새 행 추가
|
|
for (let i = 1; i < participantData.length; i++) {
|
|
const newRow = document.createElement('tr');
|
|
newRow.innerHTML = `
|
|
<td class="text-center">
|
|
<button type="button" class="btn btn-outline-dark btn-sm addRowBtn"> + </button>
|
|
<button type="button" class="btn btn-outline-dark btn-sm deleteRowBtn"> - </button>
|
|
</td>
|
|
<td>
|
|
<input type="text" class="form-control text-start" name="participant[]" placeholder="현설 참여업체 및 메모" autocomplete="off" value="${participantData[i] || ''}">
|
|
</td>
|
|
`;
|
|
tbody.appendChild(newRow);
|
|
}
|
|
}
|
|
}
|
|
|
|
},
|
|
error: function(jqxhr, status, error) {
|
|
console.log("AJAX Error: ", status, error);
|
|
}
|
|
});
|
|
}
|
|
|
|
</script>
|
|
<!-- 데이터 테이블 및 기타 기능을 위한 스크립트 -->
|
|
<script>
|
|
$(document).ready(function() {
|
|
// DataTables 초기 설정
|
|
dataTable = $('#myTable').DataTable({
|
|
"paging": true,
|
|
"ordering": true,
|
|
"searching": true,
|
|
"pageLength": 200,
|
|
"lengthMenu": [ 100, 200, 500, 1000],
|
|
"language": {
|
|
"lengthMenu": "Show _MENU_ entries",
|
|
"search": "Live Search:"
|
|
},
|
|
"order": [[1, 'desc']],
|
|
"dom": 't<"bottom"ip>' // search 창과 lengthMenu 숨기기
|
|
});
|
|
|
|
// 페이지 번호 복원 (초기 로드 시)
|
|
var savedPageNumber = getCookie('material_regpageNumber');
|
|
if (savedPageNumber) {
|
|
dataTable.page(parseInt(savedPageNumber) - 1).draw(false);
|
|
}
|
|
|
|
// 페이지 변경 이벤트 리스너
|
|
dataTable.on('page.dt', function() {
|
|
var material_regpageNumber = dataTable.page.info().page + 1;
|
|
setCookie('material_regpageNumber', material_regpageNumber, 10); // 쿠키에 페이지 번호 저장
|
|
});
|
|
|
|
// 페이지 길이 셀렉트 박스 변경 이벤트 처리
|
|
$('#myTable_length select').on('change', function() {
|
|
var selectedValue = $(this).val();
|
|
dataTable.page.len(selectedValue).draw(); // 페이지 길이 변경 (DataTable 파괴 및 재초기화 없이)
|
|
|
|
// 변경 후 현재 페이지 번호 복원
|
|
savedPageNumber = getCookie('material_regpageNumber');
|
|
if (savedPageNumber) {
|
|
dataTable.page(parseInt(savedPageNumber) - 1).draw(false);
|
|
}
|
|
});
|
|
|
|
$(document).on('click', '.specialbtnClear', function(e) {
|
|
e.preventDefault(); // 기본 동작을 방지합니다.
|
|
$(this).siblings('input').val('').focus();
|
|
});
|
|
|
|
$(document).on('click', '.btnClear_lot', function(e) {
|
|
e.preventDefault(); // 기본 동작을 방지합니다.
|
|
$(this).siblings('input').val('').focus();
|
|
});
|
|
});
|
|
|
|
</script>
|
|
|
|
<!-- 페이지로딩 및 Modal Script -->
|
|
<script>
|
|
$(document).ready(function(){
|
|
var loader = document.getElementById('loadingOverlay');
|
|
if(loader)
|
|
loader.style.display = 'none';
|
|
|
|
// Bootstrap 모달 인스턴스 초기화 (전역 변수)
|
|
var modalElement = document.getElementById("myModal");
|
|
if (modalElement) {
|
|
bootstrapModal = new bootstrap.Modal(modalElement);
|
|
}
|
|
|
|
$("#newBtn").on("click", function() {
|
|
loadForm('insert');
|
|
});
|
|
|
|
$("#searchBtn").on("click", function() {
|
|
$("#board_form").submit();
|
|
});
|
|
});
|
|
|
|
function phonebookBtn(searchfield)
|
|
{
|
|
var search = $("#" + searchfield).val();
|
|
href = '../pb_juil/list.php?search=' + search ;
|
|
popupCenter(href, '전화번호 검색', 1600, 800);
|
|
}
|
|
|
|
function enter() {
|
|
$("#board_form").submit();
|
|
}
|
|
|
|
function inputNumberFormat(obj) {
|
|
// 숫자 이외의 문자는 제거
|
|
obj.value = obj.value.replace(/[^0-9]/g, '');
|
|
|
|
// 콤마를 제거하고 숫자를 포맷팅
|
|
let value = obj.value.replace(/,/g, '');
|
|
obj.value = value.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
|
}
|
|
|
|
// Prevent form submission on Enter key
|
|
$(document).on("keypress", "input", function(event) {
|
|
return event.keyCode != 13;
|
|
});
|
|
|
|
$(document).ready(function(){
|
|
// 방문기록 남김
|
|
var title_message = '<?php echo $title_message ; ?>';
|
|
saveMenuLog(title_message);
|
|
});
|
|
|
|
$(document).ready(function(){
|
|
// 전체 선택 체크박스 클릭 이벤트
|
|
$('#selectAll').on('click', function() {
|
|
$('.rowCheckbox').prop('checked', this.checked);
|
|
});
|
|
|
|
// 개별 체크박스 클릭 시 전체 선택 체크박스 상태 업데이트
|
|
$('.rowCheckbox').on('click', function() {
|
|
$('#selectAll').prop('checked', $('.rowCheckbox:checked').length === $('.rowCheckbox').length);
|
|
});
|
|
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|