티스토리 뷰

반응형

아래의 형태의 셔터의 가이드레일 이미지를 관리하는 로직을 개발중이다.

단순 파일선택을 통해 불러오는 구조가 아닌, 윈도우 화면 캡쳐기능을 추가한 편리한 이미지 저장로직을 만들고자 한다.

중간단계에서 개발한 화면

 

 

chatGPT 4.0 기준으로 다시금 코드를 재생산 해본다.

아래의 코드는 guiderail을 json, 형태로 조건값과 이미지를 저장하는 코드이다.
기존의 이미지를 단순하게 파일찾기 기능으로 추가하던 코드를 drop 및 윈도우 화면캡쳐 기능을 추가하는 코드를 삽입했다.

기존의 단순 이미지를 불러와서 저장하는 방식에서 좀더 UI를 개선하는 코드를 넣었다.

이제 기존의 이미지를 저장하는 로직에서 drop Area 및 화면 캡쳐 기능이 작동하게 코드를 일부 수정해줘.

기존의 이미지처리부분의 로직을 수정해주길 바랍니다.

<?php
// guideraillist.php
require_once($_SERVER['DOCUMENT_ROOT'] . "/session.php");  
if (!isset($_SESSION["level"]) || $_SESSION["level"] > 5) {
    sleep(1);
    header("Location: /login/login_form.php");
    exit;
}

$title_message = '가이드레일 이미지 관리';
include $_SERVER['DOCUMENT_ROOT'] . '/load_header.php';

$jsonFile = $_SERVER['DOCUMENT_ROOT'] . '/guiderail/guiderail.json';

// JSON 파일이 존재하면 읽어오고, 없으면 빈 배열 생성
$guiderailData = [];
if (file_exists($jsonFile)) {
    $jsonContent = file_get_contents($jsonFile);
    $guiderailData = json_decode($jsonContent, true);
    if (!is_array($guiderailData)) {
        $guiderailData = [];
    }
}

// POST 요청 처리: 추가, 수정, 삭제
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $action = isset($_POST['action']) ? $_POST['action'] : '';
    $index = isset($_POST['index']) ? intval($_POST['index']) : -1;
    $firstitem = isset($_POST['firstitem']) ? trim($_POST['firstitem']) : '';
    $model_name = isset($_POST['model_name']) ? trim($_POST['model_name']) : '';
    $check_type = isset($_POST['check_type']) ? trim($_POST['check_type']) : '';
		
	// 이미지 파일 업로드 처리
	$imagePath = '';
	if (isset($_FILES['image']) && $_FILES['image']['error'] === UPLOAD_ERR_OK) {
		$uploadDir = $_SERVER['DOCUMENT_ROOT'] . '/guiderail/images/';
		if (!file_exists($uploadDir)) {
			mkdir($uploadDir, 0777, true);
		}
		$originalName = $_FILES['image']['name'];
		$tmpName = $_FILES['image']['tmp_name'];

		// 파일명과 확장자 분리 (pathinfo 사용)
		$pathInfo = pathinfo($originalName);
		$fileName = $pathInfo['filename']; // 확장자 제외한 파일명
		$fileExt = isset($pathInfo['extension']) ? $pathInfo['extension'] : '';

		// 파일명에 한글, 특수문자 제거: 영문, 숫자, _ , - 만 허용
		$fileNameSanitized = preg_replace('/[^A-Za-z0-9_\-]/', '_', $fileName);

		// 새 파일명 생성: 현재 날짜와 시간 + "_" + 정제된 파일명 + .확장자
		$newFileName = date("Y_m_d_H_i_s") . "_" . $fileNameSanitized;
		if (!empty($fileExt)) {
			$newFileName .= "." . $fileExt;
		}
		
		$targetFile = $uploadDir . $newFileName;
		if (!move_uploaded_file($tmpName, $targetFile)) {
			echo json_encode(['error' => '파일 업로드 실패']);
			exit;
		}
		// 업로드 성공 시 상대 경로 저장
		$imagePath = '/guiderail/images/' . $newFileName;
	}

    // 만약 새 이미지가 업로드되지 않았으면 기존 이미지(hidden input)을 사용
    if (empty($imagePath) && isset($_POST['existing_image'])) {
        $imagePath = trim($_POST['existing_image']);
    }
    
    if ($action === 'insert' && !empty($model_name)) {
        // 신규 추가
        $guiderailData[] = array(
            "firstitem"   => $firstitem,
            "model_name"  => $model_name,
            "check_type"  => $check_type,
            "image"       => $imagePath
        );
    } elseif ($action === 'update' && !empty($model_name) && $index >= 0 && $index < count($guiderailData)) {
        // 수정: 해당 인덱스의 데이터를 업데이트
        $guiderailData[$index]["firstitem"] = $firstitem;
        $guiderailData[$index]["model_name"] = $model_name;
        $guiderailData[$index]["check_type"] = $check_type;
        if (!empty($imagePath)) {
            $guiderailData[$index]["image"] = $imagePath;
        }
    } elseif ($action === 'delete' && $index >= 0 && $index < count($guiderailData)) {
        // 삭제: 해당 요소 제거
        array_splice($guiderailData, $index, 1);
    }
    
    // JSON 파일에 저장
    file_put_contents($jsonFile, json_encode($guiderailData, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));    
}
?>
</head>
<body>
<div class="container mt-3">
    <div class="card">
        <div class="card-header d-flex justify-content-center align-items-center text-center">
            <h3><?= $title_message ?></h3>            
            <button type="button" class="btn btn-dark btn-sm mx-5" onclick="window.close();">
                <i class="bi bi-x-square"></i> 닫기
            </button>
        </div>
        <div class="card-body">
            <!-- 신규/수정 폼 -->
            <form id="guiderailForm" method="post" action="guideraillist.php" enctype="multipart/form-data" class="row g-3">
                <input type="hidden" name="action" id="action" value="insert">
                <input type="hidden" name="index" id="index" value="-1">
                <input type="hidden" name="existing_image" id="existing_image" value="">
                <div class="col-auto">
                    <!-- 대분류 선택 -->
					<select id="firstitem" name="firstitem"  class="form-select mx-1 d-block w-auto" style="font-size: 0.8rem; height: 32px;">
						<option value="">(대분류)</option>
						<option value="스크린" <?= ($firstitem == '스크린') ? 'selected' : '' ?>>스크린</option>
						<option value="철재" <?= ($firstitem == '철재') ? 'selected' : '' ?>>철재</option>
					</select> &nbsp;	
                </div>
                <div class="col-auto">                  
				<!-- 제품모델(KSS01 등) 선택 -->
				<?php
				  // JSON 파일 경로 (예: /models/models.json)
				  $jsonFile = $_SERVER['DOCUMENT_ROOT'].'/models/models.json';
				  $modelsList = [];
				  if(file_exists($jsonFile)){
					  $jsonContent = file_get_contents($jsonFile);
					  $modelsList = json_decode($jsonContent, true);
					  if(!is_array($modelsList)) {
						  $modelsList = [];
					  }
				  }
				  // 기존 데이터가 있으면 기본 선택할 값
				  $selectedModel = isset($row['model_name']) ? $row['model_name'] : '';
				  // 대분류 선택값
				  $selectedMajor = isset($row['major_category']) ? $row['major_category'] : '';
				?>
				
				<select id="model_name" name="model_name" class="form-select mx-1 d-block w-auto" style="font-size: 0.8rem; height: 32px;">
				  <option value="">(모델 선택)</option>
				  <?php 
				  // 초기 옵션: 대분류가 선택되어 있으면 해당 모델만 표시
				  foreach($modelsList as $model): 
					  if($selectedMajor === '' || $model['slatitem'] === $selectedMajor): 
				  ?>
					<option value="<?= htmlspecialchars($model['model_name'], ENT_QUOTES, 'UTF-8') ?>" <?= ($model_name === $model['model_name']) ? 'selected' : '' ?>>
					  <?= htmlspecialchars($model['model_name'], ENT_QUOTES, 'UTF-8') ?>
					</option>
				  <?php 
					  endif;
				  endforeach; 
				  ?>
				</select>		
                </div>
                <div class="col-auto">
					<!-- 체크타입 선택 -->
					<select name="check_type" id="check_type" class="form-select mx-1 d-block w-auto" style="font-size: 0.8rem; height: 32px;">
						<option value="">(유형)</option>
						<option value="벽면형" <?= ($check_type == '벽면형') ? 'selected' : '' ?>>벽면형</option>
						<option value="측면형" <?= ($check_type == '측면형') ? 'selected' : '' ?>>측면형</option>
					</select>
                </div>
                <div class="col-auto">
                    <!-- 이미지 파일 선택 -->
                    <input type="file" name="image" id="image" class="form-control">
					<div class="card">
                    <div class="card-body">                        
                            <!-- 기존 이미지 표시 영역 -->                            
                                <div class="card mb-3">
                                    <div class="card-body">
										<div id="previewContainer" class="text-center mb-3" 
											ondragover="event.preventDefault();" 
											ondrop="event.preventDefault();">
											<?php if (!empty($imgdata)): ?>
												<img src="<?= $upload_dir . $imgdata ?>" alt="Image" id="currentImage" class="img-fluid">
											<?php else: ?>
												아직 등록된 이미지가 없습니다.
											<?php endif; ?>
										</div>
                                    </div>
                                </div>
								
							<?php if($mode!=='view') : ?>	
									<!-- 파일 선택 -->
									<input type="file" id="upfile" name="upfile[]" multiple style="display:none;">
									<button class="btn btn-dark btn-sm me-4" type="button" onclick="document.getElementById('upfile').click();">
										<i class="bi bi-image"></i>
									</button>
									
									<div class="d-flex justify-content-center">
										<!-- 드롭 영역 -->
										<div id="dropArea" style="border: 1px dashed #ccc; padding: 5px; width:100%; height:80px; text-align: center;">
											여기로 사진을 drop 하세요!
										</div>
									</div>
									<!-- 파일 목록 표시 -->
									<div class="d-flex mt-2 justify-content-center">
										<div id="displayfile"></div>
									</div>
							 <?php endif; ?>
                            </div>

                            <!-- JavaScript for handling drag and drop -->
                            <script>
                            document.getElementById('dropArea').addEventListener('dragover', function(event) {
                                event.preventDefault();
                                event.stopPropagation();
                                this.style.borderColor = '#000'; // 드래그 시 테두리 색상 변경
                            });

                            document.getElementById('dropArea').addEventListener('dragleave', function(event) {
                                event.preventDefault();
                                event.stopPropagation();
                                this.style.borderColor = '#ccc'; // 드래그 영역 벗어날 때 테두리 색상 복원
                            });

                            document.getElementById('dropArea').addEventListener('drop', function(event) {
                                event.preventDefault();
                                event.stopPropagation();

                                const files = event.dataTransfer.files;
                                if (files.length > 0) {
                                    handleFiles(files);
                                }
                            });

                            document.getElementById('upfile').addEventListener('change', function(event) {
                                const files = event.target.files;
                                if (files.length > 0) {
                                    handleFiles(files);
                                }
                            });

							function handleFiles(files) {
								const file = files[0]; // 첫 번째 파일만 처리
								const reader = new FileReader();

								reader.onload = function(event) {
									const img = document.createElement('img');
									img.src = event.target.result;
									img.className = 'img-fluid';

									const previewContainer = document.getElementById('previewContainer');
									previewContainer.innerHTML = ''; // 기존 이미지 제거
									previewContainer.appendChild(img);

									// 실제 파일 데이터를 <input type="file">에 설정
									const fileInput = document.getElementById('upfile');
									const dataTransfer = new DataTransfer();
									dataTransfer.items.add(file);
									fileInput.files = dataTransfer.files;
								};

								reader.readAsDataURL(file);
							}
                            </script>					
					
					
					
					
					
					
					
                </div>
                </div>
                <div class="col-auto">
                    <button type="submit" class="btn btn-primary" id="submitBtn">등록</button>
                </div>
            </form>
            <hr>
            <!-- 저장된 가이드레일 이미지 목록 테이블 -->
            <div class="table-responsive">
                <table class="table table-bordered">
                    <thead class="table-secondary">
                        <tr>
                            <th>순번</th>
                            <th>대분류</th>
                            <th>모델명</th>
                            <th>유형</th>
                            <th>이미지</th>
                            <th>수정/삭제</th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php if (!empty($guiderailData)): ?>
                            <?php foreach ($guiderailData as $i => $item): ?>
                                <tr>
                                    <td><?= $i + 1 ?></td>
                                    <td><?= htmlspecialchars($item["firstitem"], ENT_QUOTES, 'UTF-8') ?></td>
                                    <td><?= htmlspecialchars($item["model_name"], ENT_QUOTES, 'UTF-8') ?></td>
                                    <td><?= htmlspecialchars($item["check_type"], ENT_QUOTES, 'UTF-8') ?></td>
                                    <td>
                                        <?php if (!empty($item["image"])): ?>
                                            <img src="<?= htmlspecialchars($item["image"], ENT_QUOTES, 'UTF-8') ?>" alt="이미지" style="max-width:100px;">
                                        <?php else: ?>
                                            없음
                                        <?php endif; ?>
                                    </td>
                                    <td>
                                        <button type="button" class="btn btn-sm btn-outline-primary editBtn" data-index="<?= $i ?>">수정</button>
                                        <button type="button" class="btn btn-sm btn-outline-danger deleteBtn" data-index="<?= $i ?>">삭제</button>
                                    </td>
                                </tr>
                            <?php endforeach; ?>
                        <?php else: ?>
                            <tr><td colspan="6">등록된 가이드레일 이미지 정보가 없습니다.</td></tr>
                        <?php endif; ?>
                    </tbody>
                </table>
            </div><!-- table-responsive -->
        </div><!-- card-body -->
    </div><!-- card -->
</div><!-- container -->
 
<script>
$(document).ready(function(){    
    var loader = document.getElementById('loadingOverlay');
    if(loader)
        loader.style.display = 'none';
});
$(document).ready(function(){
    // 수정 버튼 클릭 시: 해당 행의 데이터를 폼에 채워 수정 모드로 전환
    $('.editBtn').on('click', function(){
        var index = $(this).data('index');
        var row = $(this).closest('tr');
        var firstitem = row.find('td:eq(1)').text().trim();
        var modelName = row.find('td:eq(2)').text().trim();
        var checkType = row.find('td:eq(3)').text().trim();
        var imageSrc = row.find('td:eq(4) img').attr('src') || '';
        
        $('#firstitem').val(firstitem);
        $('#model_name').val(modelName);
        $('#check_type').val(checkType);
        $('#existing_image').val(imageSrc);
        $('#index').val(index);
        $('#action').val('update');
        $('#submitBtn').text('수정');
    });
    
    // 삭제 버튼 클릭 시: 확인 후 폼 제출하여 삭제 처리
    $('.deleteBtn').on('click', function(){
        var index = $(this).data('index');
        if(confirm("정말 삭제하시겠습니까?")){
            $('#index').val(index);
            $('#action').val('delete');
            $('#guiderailForm').submit();
        }
    });
});
</script>

<script>
// PHP에서 전달받은 모델 리스트를 JavaScript 변수에 저장
var modelsList = <?php echo json_encode($modelsList); ?>;

$(document).ready(function(){
	$('#firstitem').on('change', function(){
		var selectedMajor = $(this).val();
		var $modelSelect = $('#model_name');
		// 기존 옵션 초기화
		$modelSelect.empty();
		// 기본 옵션 추가
		$modelSelect.append('<option value="">(모델 선택)</option>');
		
		// 모델 리스트를 순회하며 대분류(selectedMajor)와 일치하는 경우 옵션 추가
		$.each(modelsList, function(index, model){
			if(selectedMajor === '' || model.slatitem === selectedMajor){
				var option = $('<option>')
					.val(model.model_name)
					.text(model.model_name);
				$modelSelect.append(option);
			}
		});
	});
});

// 	윈도우키 + Shift + S를 사용하여 화면 캡처한 이미지를 바로 붙여넣기하면, 클립보드에 이미지가 저장
document.addEventListener('paste', function (event) {
	let items = (event.clipboardData || event.originalEvent.clipboardData).items;
	for (let index in items) {
		let item = items[index];
		if (item.kind === 'file' && item.type.startsWith('image/')) {
			let blob = item.getAsFile();
			let reader = new FileReader();
			reader.onload = function (event) {
				// 이미지 미리보기 영역 업데이트
				let previewContainer = document.getElementById('previewContainer');
				previewContainer.innerHTML = '';
				let img = document.createElement('img');
				img.src = event.target.result;
				img.className = 'img-fluid';
				previewContainer.appendChild(img);

				// 파일을 input[type=file] 요소에 추가
				let fileInput = document.getElementById('upfile');
				let dataTransfer = new DataTransfer();
				dataTransfer.items.add(blob);
				fileInput.files = dataTransfer.files;
			};
			reader.readAsDataURL(blob);
		}
	}
});

</script>
</body>
</html>

 

위의 프롬프트로 실제 인공지능을 이용해서 결과치를 받아본다.

다음은 기존의 이미지 업로드 처리 로직을 수정하여,

  1. 먼저 drop 영역(파일 input name="upfile[]")에서 업로드된 파일을 우선적으로 처리하고,
  2. 그 다음 기존의 파일 input(name="image")의 파일을 처리하며,
  3. 둘 다 없으면 기존 hidden input("existing_image")의 값을 사용하는 코드입니다.
// 이미지 파일 업로드 처리 (drop 영역 및 일반 파일 input 모두 지원)
$imagePath = '';

// 1. drop 영역에서 업로드된 파일 처리 (파일 input name="upfile[]"가 존재하고, 첫 번째 파일의 크기가 0보다 큰 경우)
if (isset($_FILES['upfile']) && isset($_FILES['upfile']['size'][0]) && $_FILES['upfile']['size'][0] > 0) {
    $uploadDir = $_SERVER['DOCUMENT_ROOT'] . '/guiderail/images/';
    if (!file_exists($uploadDir)) {
        mkdir($uploadDir, 0777, true);
    }
    $originalName = $_FILES['upfile']['name'][0];
    $tmpName = $_FILES['upfile']['tmp_name'][0];

    // 파일명과 확장자 분리 (pathinfo 사용)
    $pathInfo = pathinfo($originalName);
    $fileName = $pathInfo['filename']; // 확장자 제외한 파일명
    $fileExt = isset($pathInfo['extension']) ? $pathInfo['extension'] : '';

    // 파일명에 한글, 특수문자 제거: 영문, 숫자, _ , - 만 허용
    $fileNameSanitized = preg_replace('/[^A-Za-z0-9_\-]/', '_', $fileName);

    // 새 파일명 생성: 현재 날짜와 시간 + "_" + 정제된 파일명 + .확장자
    $newFileName = date("Y_m_d_H_i_s") . "_" . $fileNameSanitized;
    if (!empty($fileExt)) {
        $newFileName .= "." . $fileExt;
    }
    
    $targetFile = $uploadDir . $newFileName;
    if (!move_uploaded_file($tmpName, $targetFile)) {
        echo json_encode(['error' => '파일 업로드 실패']);
        exit;
    }
    // 업로드 성공 시 상대 경로 저장
    $imagePath = '/guiderail/images/' . $newFileName;

// 2. 일반 파일 input (name="image")에서 업로드된 파일 처리
} elseif (isset($_FILES['image']) && $_FILES['image']['error'] === UPLOAD_ERR_OK) {
    $uploadDir = $_SERVER['DOCUMENT_ROOT'] . '/guiderail/images/';
    if (!file_exists($uploadDir)) {
        mkdir($uploadDir, 0777, true);
    }
    $originalName = $_FILES['image']['name'];
    $tmpName = $_FILES['image']['tmp_name'];

    $pathInfo = pathinfo($originalName);
    $fileName = $pathInfo['filename'];
    $fileExt = isset($pathInfo['extension']) ? $pathInfo['extension'] : '';
    $fileNameSanitized = preg_replace('/[^A-Za-z0-9_\-]/', '_', $fileName);
    $newFileName = date("Y_m_d_H_i_s") . "_" . $fileNameSanitized;
    if (!empty($fileExt)) {
        $newFileName .= "." . $fileExt;
    }
    $targetFile = $uploadDir . $newFileName;
    if (!move_uploaded_file($tmpName, $targetFile)) {
        echo json_encode(['error' => '파일 업로드 실패']);
        exit;
    }
    $imagePath = '/guiderail/images/' . $newFileName;
}

// 3. 만약 새 이미지가 업로드되지 않았으면 기존 이미지(hidden input)를 사용
if (empty($imagePath) && isset($_POST['existing_image'])) {
    $imagePath = trim($_POST['existing_image']);
}

클라이언트 측 (HTML + JavaScript)

이미지 업로드와 관련된 UI에는 다음과 같이 드래그 앤 드롭 영역과 화면 캡쳐(클립보드 붙여넣기) 기능을 포함합니다.

<!-- 이미지 파일 선택 및 드롭 영역 -->
<div class="col-auto">
    <!-- 이미지 파일 선택 (숨김 처리, drop 영역에서 사용) -->
    <input type="file" id="upfile" name="upfile[]" multiple style="display:none;">
    <button class="btn btn-dark btn-sm me-4" type="button" onclick="document.getElementById('upfile').click();">
        <i class="bi bi-image"></i>
    </button>
    
    <div class="d-flex justify-content-center">
        <!-- 드롭 영역 -->
        <div id="dropArea" style="border: 1px dashed #ccc; padding: 5px; width:100%; height:80px; text-align: center;">
            여기로 사진을 drop 하세요!
        </div>
    </div>
    <!-- 파일 목록 및 미리보기 영역 -->
    <div class="d-flex mt-2 justify-content-center">
        <div id="previewContainer">
            <?php if (!empty($imgdata)): ?>
                <img src="<?= htmlspecialchars($upload_dir . $imgdata, ENT_QUOTES, 'UTF-8') ?>" alt="Image" id="currentImage" class="img-fluid">
            <?php else: ?>
                아직 등록된 이미지가 없습니다.
            <?php endif; ?>
        </div>
    </div>
</div>

<!-- JavaScript for Drag & Drop, 파일 선택, 그리고 클립보드 붙여넣기 -->
<script>
document.getElementById('dropArea').addEventListener('dragover', function(event) {
    event.preventDefault();
    event.stopPropagation();
    this.style.borderColor = '#000';
});
document.getElementById('dropArea').addEventListener('dragleave', function(event) {
    event.preventDefault();
    event.stopPropagation();
    this.style.borderColor = '#ccc';
});
document.getElementById('dropArea').addEventListener('drop', function(event) {
    event.preventDefault();
    event.stopPropagation();
    const files = event.dataTransfer.files;
    if (files.length > 0) {
        handleFiles(files);
    }
});
document.getElementById('upfile').addEventListener('change', function(event) {
    const files = event.target.files;
    if (files.length > 0) {
        handleFiles(files);
    }
});
// 클립보드 붙여넣기 (윈도우키+Shift+S 등)
document.addEventListener('paste', function(event) {
    let items = (event.clipboardData || event.originalEvent.clipboardData).items;
    for (let index in items) {
        let item = items[index];
        if (item.kind === 'file' && item.type.startsWith('image/')) {
            let blob = item.getAsFile();
            let reader = new FileReader();
            reader.onload = function(event) {
                const previewContainer = document.getElementById('previewContainer');
                previewContainer.innerHTML = '';
                let img = document.createElement('img');
                img.src = event.target.result;
                img.className = 'img-fluid';
                previewContainer.appendChild(img);
                
                // 파일을 upfile input에 추가
                const fileInput = document.getElementById('upfile');
                const dataTransfer = new DataTransfer();
                dataTransfer.items.add(blob);
                fileInput.files = dataTransfer.files;
            };
            reader.readAsDataURL(blob);
        }
    }
});
function handleFiles(files) {
    const file = files[0]; // 첫 번째 파일만 처리 (필요에 따라 확장 가능)
    const reader = new FileReader();
    reader.onload = function(event) {
        const previewContainer = document.getElementById('previewContainer');
        previewContainer.innerHTML = '';
        let img = document.createElement('img');
        img.src = event.target.result;
        img.className = 'img-fluid';
        previewContainer.appendChild(img);
        
        // 파일을 upfile input에 설정
        const fileInput = document.getElementById('upfile');
        const dataTransfer = new DataTransfer();
        dataTransfer.items.add(file);
        fileInput.files = dataTransfer.files;
    };
    reader.readAsDataURL(file);
}
</script>

요약

  • 서버 측에서는 먼저 $_FILES['upfile'] (드롭 영역/붙여넣기 처리된 파일)을 우선적으로 처리하고,
    그 후 $_FILES['image']를 확인하며, 둘 다 없으면 기존 이미지 값을 사용하도록 수정하였습니다.
  • 클라이언트 측에서는 드래그 앤 드롭 영역, 파일 선택 버튼, 그리고 클립보드 붙여넣기 이벤트를 처리하여 이미지 미리보기와 파일 input 업데이트를 수행합니다.

이렇게 하면 UI가 개선되어 드롭 및 화면 캡쳐 기능을 통해 이미지를 등록할 수 있으며, 서버에서는 새 파일명으로 저장되어 JSON 파일에 저장된 이미지 경로가 업데이트됩니다.

실제 화면에 표시된 결과는 아래와 같다.

 

가이드레일의 정보를 수정하는 코드도 일부 수정했다.

수정 버튼을 누르면 기존의 이미지를 불러오는 것이 되지 않아서, 코드를 추가했다.

<script>
$(document).ready(function(){
    // 수정 버튼 클릭 시: 해당 행의 데이터를 폼에 채워 수정 모드로 전환
	$('.editBtn').on('click', function(){
		var index = $(this).data('index');
		var row = $(this).closest('tr');
		var firstitem = row.find('td:eq(1)').text().trim();
		var modelName = row.find('td:eq(2)').text().trim();
		var checkType = row.find('td:eq(3)').text().trim();
		var imageSrc = row.find('td:eq(4) img').attr('src') || '';
		
		$('#firstitem').val(firstitem);
		$('#model_name').val(modelName);
		$('#check_type').val(checkType);
		$('#existing_image').val(imageSrc);
		$('#index').val(index);
		$('#action').val('update');
		$('#submitBtn').text('수정');

		// 추가: 기존 이미지가 있으면 previewContainer에 표시
		if(imageSrc) {
			$('#previewContainer').html('<img src="' + imageSrc + '" alt="이미지" class="img-fluid">');
		} else {
			$('#previewContainer').html('아직 등록된 이미지가 없습니다.');
		}
	});

    // 삭제 버튼 클릭 시: 확인 후 폼 제출하여 삭제 처리
    $('.deleteBtn').on('click', function(){
        var index = $(this).data('index');
        if(confirm("정말 삭제하시겠습니까?")){
            $('#index').val(index);
            $('#action').val('delete');
            $('#guiderailForm').submit();
        }
    });
});
</script>
반응형
댓글