
1️⃣[myHomeForm.jsp] - 제품검색 버튼을 누르면 모달창 생성
<!-- 모달창 -->
<div id="prodSearchModal" class="modal">
<div class="modal-header">
<strong>🛒 제품 검색</strong>
<button type="button" onclick="closeProdSearch()" class="modal-close">×</button>
</div>
<div class="modal-body">
<input type="text" id="searchKeyword" placeholder="상품명을 입력하세요" class="search-input">
<button type="button" id="modalprodSearchBtn" onclick="searchProduct()"> 검색🔍</button>
<div id="productResults" class="search-results"></div>
</div>
</div>
<div class="prodHeader">
<!-- 상품 검색 버튼 -->
<button type="button" id="prodSearchBtn" onclick="openProdSearch()">제품 검색</button>
<!-- 미리보기 -->
<h3>우리집에 사용된 제품</h3>
</div>
<div id="prodPreview" class="prodPreview"></div>
ajax로 productController로 데이터 요청 (검색창에 입력하는 keyword 보냄)
document.getElementById("searchKeyword").addEventListener("keydown", function(event) {
if (event.key === "Enter") {
event.preventDefault(); // 기본 동작 방지
searchProduct(); // 검색 함수 실행
}
});
function openProdSearch() {
document.getElementById('prodSearchModal').style.display = 'block';
}
function closeProdSearch() {
document.getElementById('prodSearchModal').style.display = 'none';
}
function searchProduct(){
const keyword = document.getElementById('searchKeyword').value;
$.ajax({
type: "GET",
url: "/gami/product/productSearch.do",
data: {keyword: keyword},
dataType: "json",
success: function(response) {
const resultDiv = document.getElementById("productResults");
resultDiv.innerHTML = "";
if (response.products && response.products.length > 0) {
const products = response.products;
for (let i = 0; i < products.length; i++) {
const product = products[i];
const div = document.createElement("div");
div.className = "prodList";
div.style.cursor = "pointer";
const img = document.createElement("img");
img.className = "prodImage";
img.src = "/gami/product/productThumbnail.do?articleNO=" + product.productNO + "&image=" + encodeURIComponent(product.imageFileName);
img.alt = product.productName;
img.width = 60;
const nameP = document.createElement("p");
nameP.className = "prod";
nameP.style.marginTop = "5px";
nameP.innerHTML = "<font size=3>" + product.productName + "</font>";
div.appendChild(img);
div.appendChild(nameP);
div.onclick = function () {
prodPreView(product);
closeProdSearch();
};
resultDiv.appendChild(div);
}
} else {
resultDiv.innerText = "검색 결과가 없습니다.";
}
},
error: function(xhr, status, error) {
console.log("오류 발생:", error);
alert("서버와 통신 중 문제가 생겼습니다.");
}
});
}
[productController]
@RequestMapping(value = "/productSearch.do", method = RequestMethod.GET)
@ResponseBody
public Map<String, Object> productSearch(@RequestParam("keyword") String keyword) throws Exception {
System.out.println("keyword 어서오시옵소서 : " + keyword);
List<ProductDomain> searchedProdList = productService.productSearching(keyword);
System.out.println("리스트 오시옵소서 : "+searchedProdList);
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("products", searchedProdList);
return resultMap;
}
5️⃣[mapper]
<select id="searchingProd" resultType="ProductDomain" parameterType="String">
SELECT
p.productNo,
p.productName,
p.productDescription,
p.productPrice,
i.imageFilename
FROM (
SELECT productNo, productName, productDescription, productPrice,
ROW_NUMBER() OVER (PARTITION BY productName ORDER BY productOptions) AS rn
FROM product
) p
LEFT JOIN (
SELECT articleNo, MIN(imageFilename) AS imageFilename
FROM image
WHERE imageType = '상품'
GROUP BY articleNo
) i ON p.productNo = i.articleNo
WHERE p.rn = 1
AND p.productName LIKE '%' || #{keyword} || '%'
</select>
[Jackson 라이브러리 추가]
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.8.5</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.8.5</version>
</dependency>
9️⃣[myHomeFome.jsp] - 선택한 상품 미리보기 생성
//선택된 상품 미리보기
let selectedProducts = [];
function prodPreView(product) {
const previewArea = document.getElementById("prodPreview");
// 중복선택 방지
for (let i = 0; i < selectedProducts.length; i++) {
if (selectedProducts[i].productNO === product.productNO) {
alert("이미 선택한 상품입니다!");
return;
}
}
selectedProducts.push(product);
// 기존 "선택한 상품이 없습니다." 메시지가 있다면 지움
const existingMsg = document.getElementById("noProdMsg");
if (existingMsg) {
previewArea.removeChild(existingMsg);
}
const container = document.createElement("div");
container.style.display = "flex";
container.style.alignItems = "center";
container.style.gap = "10px";
container.style.marginTop = "10px";
// 썸네일 이미지
const img = document.createElement("img");
img.src = "/gami/product/productThumbnail.do?articleNO=" + product.productNO + "&image=" + encodeURIComponent(product.imageFileName);
img.alt = product.productName;
img.width = 60;
// 상품 이름
const name = document.createElement("span");
name.innerText = product.productName;
// 삭제 버튼
const delBtn = document.createElement("button");
delBtn.innerText = "X";
delBtn.style.marginLeft = "auto";
delBtn.style.background = "none";
delBtn.style.border = "none";
delBtn.style.color = "#4D4D4D";
delBtn.style.cursor = "pointer";
delBtn.onclick = function(){
selectedProducts = selectedProducts.filter(p => p.productNO !== product.productNO);
previewArea.removeChild(container);
// 상품 다 지워졌으면 메시지 다시 보여주기
if (selectedProducts.length === 0) {
const noProd = document.createElement("p");
noProd.id = "noProdMsg"; // 메시지 id 부여!
noProd.innerText = "선택한 상품이 없습니다.";
previewArea.appendChild(noProd);
}
};
container.appendChild(img);
container.appendChild(name);
container.appendChild(delBtn);
previewArea.appendChild(container);
}
document.addEventListener("DOMContentLoaded", function () {
const previewArea = document.getElementById("prodPreview");
const noProd = document.createElement("p");
noProd.id = "noProdMsg";
noProd.innerText = "선택한 상품이 없습니다.";
previewArea.appendChild(noProd);
});
productThumbnail.do그대로 활용