From 10c5a67b05e4dd17d81576da6975b29bd08499e0 Mon Sep 17 00:00:00 2001 From: hjjeong Date: Wed, 22 Oct 2025 17:08:11 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20Select2=20=EC=9D=B4=EB=B2=A4=ED=8A=B8?= =?UTF-8?q?=EB=A5=BC=20change=EC=97=90=EC=84=9C=20select2:select=EB=A1=9C?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD=ED=95=98=EC=97=AC=20=EA=B0=99=EC=9D=80=20?= =?UTF-8?q?=EA=B0=92=20=EC=9E=AC=EC=84=A0=ED=83=9D=20=EC=8B=9C=EC=97=90?= =?UTF-8?q?=EB=8F=84=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=20=EB=B0=9C=EC=83=9D?= =?UTF-8?q?=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - estimateRegistFormPopup.jsp: 품번/품명 셀렉트박스 이벤트 수정 - estimateTemplate1.jsp: 품명 셀렉트박스 이벤트 수정 및 select2:clear 이벤트 추가 - common.js: initPartSelect2Ajax 함수의 품번/품명 이벤트 핸들러 수정 - ContractMgmtController.java: 견적서 신규 작성 시 품목 데이터 로드 주석처리 --- .../WEB-INF/view/approval/approvalDetail.jsp | 4 +- .../contractMgmt/estimateRegistFormPopup.jsp | 144 +++++++++--------- .../view/contractMgmt/estimateTemplate1.jsp | 84 ++++++---- WebContent/js/common.js | 46 +++--- .../controller/ContractMgmtController.java | 10 +- 5 files changed, 159 insertions(+), 129 deletions(-) diff --git a/WebContent/WEB-INF/view/approval/approvalDetail.jsp b/WebContent/WEB-INF/view/approval/approvalDetail.jsp index 3416036..91be67f 100644 --- a/WebContent/WEB-INF/view/approval/approvalDetail.jsp +++ b/WebContent/WEB-INF/view/approval/approvalDetail.jsp @@ -75,8 +75,8 @@ $(function(){ url = "/supplyChainMgmt/invoiceFormPopUp.do?checkArr="+targetObjId+"&actionType=view"; window.open(url, "", "width=1000,height=880"); }else if(targetType == "CONTRACT_ESTIMATE"){ - url = "/contractMgmt/estimateRegistFormPopup.do?objId="+targetObjId+"&actionType=view"; - window.open(url, "", "width=1000,height=560"); + url = "/contractMgmt/estimateTemplate1.do?templateObjId="+targetObjId+"&actionType=view"; + window.open(url, "", "width=1000,height=1200"); } }); diff --git a/WebContent/WEB-INF/view/contractMgmt/estimateRegistFormPopup.jsp b/WebContent/WEB-INF/view/contractMgmt/estimateRegistFormPopup.jsp index 75ec44d..71a483a 100644 --- a/WebContent/WEB-INF/view/contractMgmt/estimateRegistFormPopup.jsp +++ b/WebContent/WEB-INF/view/contractMgmt/estimateRegistFormPopup.jsp @@ -1406,82 +1406,82 @@ } }); - // 품번 변경 이벤트 - $partNoSelect.off('change').on('change', function() { - var selectedData = $(this).select2('data')[0]; - - if(selectedData && selectedData.id) { - // 무한루프 방지 - $partNameSelect.data('syncing', true); - - // 품명 셀렉트박스에 옵션이 없으면 추가 - if($partNameSelect.find("option[value='" + selectedData.id + "']").length === 0) { - var newOption = new Option(selectedData.partName, selectedData.id, true, true); - $(newOption).data('partNo', selectedData.partNo); - $partNameSelect.append(newOption); - } - - // 품명 셀렉트박스 값 설정 - $partNameSelect.val(selectedData.id).trigger('change.select2'); - - // hidden 필드에 값 설정 - var $row = $("#" + itemId); - $row.find(".item-part-objid").val(selectedData.id); - $row.find(".item-part-no").val(selectedData.partNo); - $row.find(".item-part-name").val(selectedData.partName); - - console.log("품번 선택 후 hidden 필드 설정:", { - itemId: itemId, - partObjId: $row.find(".item-part-objid").val(), - partNo: $row.find(".item-part-no").val(), - partName: $row.find(".item-part-name").val() - }); - - setTimeout(function() { - $partNameSelect.data('syncing', false); - }, 100); - } - }); + // 품번 선택 이벤트 (select2:select는 같은 값 재선택 시에도 발생) + $partNoSelect.off('select2:select').on('select2:select', function(e) { + var selectedData = e.params.data; - // 품명 변경 이벤트 - $partNameSelect.off('change').on('change', function() { + if(selectedData && selectedData.id) { // 무한루프 방지 - if($(this).data('syncing')) return; + $partNameSelect.data('syncing', true); - var selectedData = $(this).select2('data')[0]; - - if(selectedData && selectedData.id) { - // 무한루프 방지 - $partNoSelect.data('syncing', true); - - // 품번 셀렉트박스에 옵션이 없으면 추가 - if($partNoSelect.find("option[value='" + selectedData.id + "']").length === 0) { - var newOption = new Option(selectedData.partNo, selectedData.id, true, true); - $(newOption).data('partName', selectedData.partName); - $partNoSelect.append(newOption); - } - - // 품번 셀렉트박스 값 설정 - $partNoSelect.val(selectedData.id).trigger('change.select2'); - - // hidden 필드에 값 설정 - var $row = $("#" + itemId); - $row.find(".item-part-objid").val(selectedData.id); - $row.find(".item-part-no").val(selectedData.partNo); - $row.find(".item-part-name").val(selectedData.partName); - - console.log("품명 선택 후 hidden 필드 설정:", { - itemId: itemId, - partObjId: $row.find(".item-part-objid").val(), - partNo: $row.find(".item-part-no").val(), - partName: $row.find(".item-part-name").val() - }); - - setTimeout(function() { - $partNoSelect.data('syncing', false); - }, 100); + // 품명 셀렉트박스에 옵션이 없으면 추가 + if($partNameSelect.find("option[value='" + selectedData.id + "']").length === 0) { + var newOption = new Option(selectedData.partName, selectedData.id, true, true); + $(newOption).data('partNo', selectedData.partNo); + $partNameSelect.append(newOption); } - }); + + // 품명 셀렉트박스 값 설정 + $partNameSelect.val(selectedData.id).trigger('change.select2'); + + // hidden 필드에 값 설정 + var $row = $("#" + itemId); + $row.find(".item-part-objid").val(selectedData.id); + $row.find(".item-part-no").val(selectedData.partNo); + $row.find(".item-part-name").val(selectedData.partName); + + console.log("품번 선택 후 hidden 필드 설정:", { + itemId: itemId, + partObjId: $row.find(".item-part-objid").val(), + partNo: $row.find(".item-part-no").val(), + partName: $row.find(".item-part-name").val() + }); + + setTimeout(function() { + $partNameSelect.data('syncing', false); + }, 100); + } + }); + + // 품명 선택 이벤트 (select2:select는 같은 값 재선택 시에도 발생) + $partNameSelect.off('select2:select').on('select2:select', function(e) { + // 무한루프 방지 + if($(this).data('syncing')) return; + + var selectedData = e.params.data; + + if(selectedData && selectedData.id) { + // 무한루프 방지 + $partNoSelect.data('syncing', true); + + // 품번 셀렉트박스에 옵션이 없으면 추가 + if($partNoSelect.find("option[value='" + selectedData.id + "']").length === 0) { + var newOption = new Option(selectedData.partNo, selectedData.id, true, true); + $(newOption).data('partName', selectedData.partName); + $partNoSelect.append(newOption); + } + + // 품번 셀렉트박스 값 설정 + $partNoSelect.val(selectedData.id).trigger('change.select2'); + + // hidden 필드에 값 설정 + var $row = $("#" + itemId); + $row.find(".item-part-objid").val(selectedData.id); + $row.find(".item-part-no").val(selectedData.partNo); + $row.find(".item-part-name").val(selectedData.partName); + + console.log("품명 선택 후 hidden 필드 설정:", { + itemId: itemId, + partObjId: $row.find(".item-part-objid").val(), + partNo: $row.find(".item-part-no").val(), + partName: $row.find(".item-part-name").val() + }); + + setTimeout(function() { + $partNoSelect.data('syncing', false); + }, 100); + } + }); // 기존 선택값이 있으면 로드 (수정 모드) console.log("기존 데이터 로드 체크:", {objId: selectedObjId, partNo: savedPartNo, partName: savedPartName}); diff --git a/WebContent/WEB-INF/view/contractMgmt/estimateTemplate1.jsp b/WebContent/WEB-INF/view/contractMgmt/estimateTemplate1.jsp index 11b6fe4..2114cab 100644 --- a/WebContent/WEB-INF/view/contractMgmt/estimateTemplate1.jsp +++ b/WebContent/WEB-INF/view/contractMgmt/estimateTemplate1.jsp @@ -561,20 +561,23 @@ function fn_initItemDescSelect(itemId) { } }); - // 품명 선택 시 hidden 필드와 규격 자동 입력 - $("#" + itemId + " .item-desc-select").on('change', function() { - var selectedData = $(this).select2('data')[0]; + // 품명 선택 시 hidden 필드와 규격 자동 입력 (select2:select는 같은 값 재선택 시에도 발생) + $("#" + itemId + " .item-desc-select").on('select2:select', function(e) { + var selectedData = e.params.data; if(selectedData) { $("#" + itemId + " .item-desc").val(selectedData.text); $("#" + itemId + " .item-part-objid").val(selectedData.id); // part_objid 저장 if(selectedData.spec) { $("#" + itemId + " .item-spec").val(selectedData.spec); } - } else { - $("#" + itemId + " .item-desc").val(''); - $("#" + itemId + " .item-part-objid").val(''); // part_objid 초기화 } }); + + // 품명 선택 해제 시 (X 버튼 클릭) + $("#" + itemId + " .item-desc-select").on('select2:clear', function() { + $("#" + itemId + " .item-desc").val(''); + $("#" + itemId + " .item-part-objid").val(''); // part_objid 초기화 + }); } // 행 추가 함수 @@ -650,32 +653,36 @@ function fn_loadData() { $("#contact_person").val(data.estimate.CONTACT_PERSON || ""); $("#greeting_text").val(data.estimate.GREETING_TEXT || "견적을 요청해 주셔서 대단히 감사합니다.\n하기와 같이 견적서를 제출합니다."); - // 담당자/연락처는 저장된 값이 있을 때만 덮어씀 - var managerName = data.estimate.MANAGER_NAME || ""; - var managerContact = data.estimate.MANAGER_CONTACT || ""; - if(managerName && managerName !== "" && managerName !== "영업부") { - $("#manager_name").val(managerName); - } - if(managerContact && managerContact !== "") { - $("#manager_contact").val(managerContact); - } + // 담당자/연락처는 저장된 값이 있을 때만 덮어씀 + var managerName = data.estimate.MANAGER_NAME || ""; + var managerContact = data.estimate.MANAGER_CONTACT || ""; + if(managerName && managerName !== "" && managerName !== "영업부") { + $("#manager_name").val(managerName); + } + if(managerContact && managerContact !== "") { + $("#manager_contact").val(managerContact); + } - // 품목 데이터 로드 + /* 품목 데이터 로드 - 주석처리 (새로 작성 시 빈 템플릿 사용) if(data.items && data.items.length > 0) { // 기존 행 초기화 후 데이터 추가 var itemsHtml = ""; for(var i = 0; i < data.items.length; i++) { var item = data.items[i]; var itemId = 'loaded_item_' + i; - itemsHtml += ''; - itemsHtml += '' + (i + 1) + ''; - itemsHtml += ''; - itemsHtml += ''; - itemsHtml += ''; - itemsHtml += ''; - itemsHtml += ''; + itemsHtml += ''; + itemsHtml += '' + (i + 1) + ''; + itemsHtml += ''; + itemsHtml += ''; + itemsHtml += ''; + itemsHtml += ''; + itemsHtml += ''; itemsHtml += ''; itemsHtml += ''; itemsHtml += ''; @@ -758,6 +765,14 @@ function fn_loadData() { // 합계 계산 fn_calculateTotal(); } + */ // 품목 데이터 로드 주석처리 끝 + + // 새로 작성 시 기본 행의 셀렉트박스 초기화 + fn_initItemDescSelect('default_item_1'); + fn_initItemDescSelect('default_item_2'); + + // 초기 로드 시 합계 계산 + fn_calculateTotal(); // 하단 비고 로드 $("#note1").val(data.estimate.NOTE1 || "1. 견적유효기간: 일"); @@ -874,13 +889,18 @@ function fn_loadTemplateData(templateObjId){ var unitPriceFormatted = unitPrice ? addComma(unitPrice) : ''; var amountFormatted = amount ? addComma(amount) : ''; - itemsHtml += ''; - itemsHtml += '' + (i + 1) + ''; - itemsHtml += ''; - itemsHtml += ''; - itemsHtml += ''; - itemsHtml += ''; - itemsHtml += ''; + itemsHtml += ''; + itemsHtml += '' + (i + 1) + ''; + itemsHtml += ''; + itemsHtml += ''; + itemsHtml += ''; + itemsHtml += ''; + itemsHtml += ''; itemsHtml += ''; itemsHtml += ''; itemsHtml += ''; diff --git a/WebContent/js/common.js b/WebContent/js/common.js index 235acb1..2ac5d06 100644 --- a/WebContent/js/common.js +++ b/WebContent/js/common.js @@ -3379,10 +3379,10 @@ function initPartSelect2Ajax(partNoSelectId, partNameSelectId, partObjIdInputId, } }); - // 품번 변경 이벤트 핸들러 - var partNoChangeHandler = function() { - var selectedData = $(this).select2('data')[0]; - if(debug) console.log("품번 변경됨:", selectedData); + // 품번 선택 이벤트 핸들러 (select2:select는 같은 값 재선택 시에도 발생) + var partNoSelectHandler = function(e) { + var selectedData = e.params.data; + if(debug) console.log("품번 선택됨:", selectedData); if(selectedData && selectedData.objId) { if(debug) console.log("품목 OBJID 설정:", selectedData.objId); @@ -3390,7 +3390,7 @@ function initPartSelect2Ajax(partNoSelectId, partNameSelectId, partObjIdInputId, // 품명 셀렉트박스도 동기화 var $partNameSelect = $(partNameSelectId); - $partNameSelect.off('change'); + $partNameSelect.off('select2:select'); if($partNameSelect.find("option[value='" + selectedData.partName + "']").length === 0) { var newOption = new Option(selectedData.partName, selectedData.partName, true, true); $partNameSelect.append(newOption); @@ -3400,17 +3400,21 @@ function initPartSelect2Ajax(partNoSelectId, partNameSelectId, partObjIdInputId, $partNameSelect.trigger('change.select2'); setTimeout(function() { - $partNameSelect.on('change', partNameChangeHandler); + $partNameSelect.on('select2:select', partNameSelectHandler); }, 100); - } else { - $(partObjIdInputId).val(""); } }; - // 품명 변경 이벤트 핸들러 - var partNameChangeHandler = function() { - var selectedData = $(this).select2('data')[0]; - if(debug) console.log("품명 변경됨:", selectedData); + // 품번 선택 해제 이벤트 + var partNoClearHandler = function() { + $(partObjIdInputId).val(""); + $(partNameSelectId).val(null).trigger('change'); + }; + + // 품명 선택 이벤트 핸들러 (select2:select는 같은 값 재선택 시에도 발생) + var partNameSelectHandler = function(e) { + var selectedData = e.params.data; + if(debug) console.log("품명 선택됨:", selectedData); if(selectedData && selectedData.objId) { if(debug) console.log("품목 OBJID 설정:", selectedData.objId); @@ -3418,7 +3422,7 @@ function initPartSelect2Ajax(partNoSelectId, partNameSelectId, partObjIdInputId, // 품번 셀렉트박스도 동기화 var $partNoSelect = $(partNoSelectId); - $partNoSelect.off('change'); + $partNoSelect.off('select2:select'); if($partNoSelect.find("option[value='" + selectedData.partNo + "']").length === 0) { var newOption = new Option(selectedData.partNo, selectedData.partNo, true, true); $partNoSelect.append(newOption); @@ -3428,14 +3432,20 @@ function initPartSelect2Ajax(partNoSelectId, partNameSelectId, partObjIdInputId, $partNoSelect.trigger('change.select2'); setTimeout(function() { - $partNoSelect.on('change', partNoChangeHandler); + $partNoSelect.on('select2:select', partNoSelectHandler); }, 100); - } else { - $(partObjIdInputId).val(""); } }; + // 품명 선택 해제 이벤트 + var partNameClearHandler = function() { + $(partObjIdInputId).val(""); + $(partNoSelectId).val(null).trigger('change'); + }; + // 이벤트 연결 - $(partNoSelectId).on('change', partNoChangeHandler); - $(partNameSelectId).on('change', partNameChangeHandler); + $(partNoSelectId).on('select2:select', partNoSelectHandler); + $(partNoSelectId).on('select2:clear', partNoClearHandler); + $(partNameSelectId).on('select2:select', partNameSelectHandler); + $(partNameSelectId).on('select2:clear', partNameClearHandler); } \ No newline at end of file diff --git a/src/com/pms/salesmgmt/controller/ContractMgmtController.java b/src/com/pms/salesmgmt/controller/ContractMgmtController.java index 8519551..1a1824b 100644 --- a/src/com/pms/salesmgmt/controller/ContractMgmtController.java +++ b/src/com/pms/salesmgmt/controller/ContractMgmtController.java @@ -1868,11 +1868,11 @@ public class ContractMgmtController { estimate = contractMgmtService.getEstimateTemplateByObjId(paramMap); items = contractMgmtService.getEstimateTemplateItemsByTemplateObjId(paramMap); } - // objId만 있으면 CONTRACT 정보로 견적서 신규 작성 - else if(!"".equals(objId) && !"-1".equals(objId)){ - estimate = contractMgmtService.getEstimateTemplateInfo(paramMap); - items = contractMgmtService.getEstimateTemplateItems(paramMap); - } + // objId만 있으면 CONTRACT 정보로 견적서 신규 작성 + else if(!"".equals(objId) && !"-1".equals(objId)){ + estimate = contractMgmtService.getEstimateTemplateInfo(paramMap); + // items = contractMgmtService.getEstimateTemplateItems(paramMap); // 주석처리: 새로 작성 시 빈 템플릿 사용 + } // 고객사 코드맵 추가 String customer_cd = "";